#include <cstddef>
#include <type_traits>
#define alignas(...) __attribute__((__aligned__(alignof(decltype(::wheels::detail::get_type_with_alignment<__VA_ARGS__>())))))
namespace wheels {
namespace detail {
constexpr std::size_t max(std::size_t n) { return n; }
constexpr std::size_t max(std::size_t a, std::size_t b) { return a > b? a : b; }
template <typename... T>
constexpr std::size_t max(std::size_t h, T... t) { return max(h, max(t...)); }
template <std::size_t... N> struct __attribute__((__aligned__(max(N...)))) alignment_type {};
template <typename... T> alignment_type<alignof(T)...> get_type_with_alignment();
template <std::size_t... N> alignment_type<N...> get_type_with_alignment();
}
template <std::size_t Len, typename... T>
struct aligned_union {
static constexpr std::size_t alignment_value = detail::max(alignof(T)...);
struct type { alignas(T...) char unnamed[detail::max(Len, sizeof(T)...)]; };
};
template <typename... T>
using AlignedUnion = typename aligned_union<1, T...>::type;
#define STATIC_ASSERT(...) static_assert((__VA_ARGS__), #__VA_ARGS__)
STATIC_ASSERT(std::is_pod<AlignedUnion<char, int, double>>::value);
STATIC_ASSERT(sizeof(AlignedUnion<char, int, double>) >= sizeof(char));
STATIC_ASSERT(sizeof(AlignedUnion<char, int, double>) >= sizeof(int));
STATIC_ASSERT(sizeof(AlignedUnion<char, int, double>) >= sizeof(double));
STATIC_ASSERT(alignof(AlignedUnion<char, int, double>) >= alignof(char));
STATIC_ASSERT(alignof(AlignedUnion<char, int, double>) >= alignof(int));
STATIC_ASSERT(alignof(AlignedUnion<char, int, double>) >= alignof(double));
}
int main() {}
I2luY2x1ZGUgPGNzdGRkZWY+CiNpbmNsdWRlIDx0eXBlX3RyYWl0cz4KIAojZGVmaW5lIGFsaWduYXMoLi4uKSBfX2F0dHJpYnV0ZV9fKChfX2FsaWduZWRfXyhhbGlnbm9mKGRlY2x0eXBlKDo6d2hlZWxzOjpkZXRhaWw6OmdldF90eXBlX3dpdGhfYWxpZ25tZW50PF9fVkFfQVJHU19fPigpKSkpKSkKIApuYW1lc3BhY2Ugd2hlZWxzIHsKICAgIG5hbWVzcGFjZSBkZXRhaWwgewogICAgICAgIGNvbnN0ZXhwciBzdGQ6OnNpemVfdCBtYXgoc3RkOjpzaXplX3QgbikgeyByZXR1cm4gbjsgfQogICAgICAgIGNvbnN0ZXhwciBzdGQ6OnNpemVfdCBtYXgoc3RkOjpzaXplX3QgYSwgc3RkOjpzaXplX3QgYikgeyByZXR1cm4gYSA+IGI/IGEgOiBiOyB9CiAgICAgICAgdGVtcGxhdGUgPHR5cGVuYW1lLi4uIFQ+CiAgICAgICAgY29uc3RleHByIHN0ZDo6c2l6ZV90IG1heChzdGQ6OnNpemVfdCBoLCBULi4uIHQpIHsgcmV0dXJuIG1heChoLCBtYXgodC4uLikpOyB9CgogICAgICAgIHRlbXBsYXRlIDxzdGQ6OnNpemVfdC4uLiBOPiBzdHJ1Y3QgX19hdHRyaWJ1dGVfXygoX19hbGlnbmVkX18obWF4KE4uLi4pKSkpIGFsaWdubWVudF90eXBlIHt9OwogICAgICAgIHRlbXBsYXRlIDx0eXBlbmFtZS4uLiBUPiBhbGlnbm1lbnRfdHlwZTxhbGlnbm9mKFQpLi4uPiBnZXRfdHlwZV93aXRoX2FsaWdubWVudCgpOwogICAgICAgIHRlbXBsYXRlIDxzdGQ6OnNpemVfdC4uLiBOPiBhbGlnbm1lbnRfdHlwZTxOLi4uPiBnZXRfdHlwZV93aXRoX2FsaWdubWVudCgpOwogICAgfQogCiAgICB0ZW1wbGF0ZSA8c3RkOjpzaXplX3QgTGVuLCB0eXBlbmFtZS4uLiBUPgogICAgc3RydWN0IGFsaWduZWRfdW5pb24gewogICAgICAgIHN0YXRpYyBjb25zdGV4cHIgc3RkOjpzaXplX3QgYWxpZ25tZW50X3ZhbHVlID0gZGV0YWlsOjptYXgoYWxpZ25vZihUKS4uLik7CiAgICAgICAgc3RydWN0IHR5cGUgeyBhbGlnbmFzKFQuLi4pIGNoYXIgdW5uYW1lZFtkZXRhaWw6Om1heChMZW4sIHNpemVvZihUKS4uLildOyB9OwogICAgfTsKICAgIHRlbXBsYXRlIDx0eXBlbmFtZS4uLiBUPgogICAgdXNpbmcgQWxpZ25lZFVuaW9uID0gdHlwZW5hbWUgYWxpZ25lZF91bmlvbjwxLCBULi4uPjo6dHlwZTsKCiNkZWZpbmUgU1RBVElDX0FTU0VSVCguLi4pIHN0YXRpY19hc3NlcnQoKF9fVkFfQVJHU19fKSwgI19fVkFfQVJHU19fKQogICAgU1RBVElDX0FTU0VSVChzdGQ6OmlzX3BvZDxBbGlnbmVkVW5pb248Y2hhciwgaW50LCBkb3VibGU+Pjo6dmFsdWUpOwogICAgU1RBVElDX0FTU0VSVChzaXplb2YoQWxpZ25lZFVuaW9uPGNoYXIsIGludCwgZG91YmxlPikgPj0gc2l6ZW9mKGNoYXIpKTsKICAgIFNUQVRJQ19BU1NFUlQoc2l6ZW9mKEFsaWduZWRVbmlvbjxjaGFyLCBpbnQsIGRvdWJsZT4pID49IHNpemVvZihpbnQpKTsKICAgIFNUQVRJQ19BU1NFUlQoc2l6ZW9mKEFsaWduZWRVbmlvbjxjaGFyLCBpbnQsIGRvdWJsZT4pID49IHNpemVvZihkb3VibGUpKTsKICAgIFNUQVRJQ19BU1NFUlQoYWxpZ25vZihBbGlnbmVkVW5pb248Y2hhciwgaW50LCBkb3VibGU+KSA+PSBhbGlnbm9mKGNoYXIpKTsKICAgIFNUQVRJQ19BU1NFUlQoYWxpZ25vZihBbGlnbmVkVW5pb248Y2hhciwgaW50LCBkb3VibGU+KSA+PSBhbGlnbm9mKGludCkpOwogICAgU1RBVElDX0FTU0VSVChhbGlnbm9mKEFsaWduZWRVbmlvbjxjaGFyLCBpbnQsIGRvdWJsZT4pID49IGFsaWdub2YoZG91YmxlKSk7Cn0KIAppbnQgbWFpbigpIHt9Cg==