blob: a3ff211420dfa8d25f344ac9d592a0d4c755219e [file] [log] [blame]
// { dg-do compile { target c++11 } }
template <typename To, typename From>
constexpr To
bit_cast (const From &from)
{
return __builtin_bit_cast (To, from);
}
template <typename To, typename From>
constexpr bool
check (const From &from)
{
return bit_cast <From> (bit_cast <To> (from)) == from;
}
struct A
{
int a, b, c;
constexpr bool operator == (const A &x) const
{
return x.a == a && x.b == b && x.c == c;
}
};
struct B
{
unsigned a[3];
constexpr bool operator == (const B &x) const
{
return x.a[0] == a[0] && x.a[1] == a[1] && x.a[2] == a[2];
}
};
struct C
{
char a[2][3][2];
constexpr bool operator == (const C &x) const
{
return x.a[0][0][0] == a[0][0][0]
&& x.a[0][0][1] == a[0][0][1]
&& x.a[0][1][0] == a[0][1][0]
&& x.a[0][1][1] == a[0][1][1]
&& x.a[0][2][0] == a[0][2][0]
&& x.a[0][2][1] == a[0][2][1]
&& x.a[1][0][0] == a[1][0][0]
&& x.a[1][0][1] == a[1][0][1]
&& x.a[1][1][0] == a[1][1][0]
&& x.a[1][1][1] == a[1][1][1]
&& x.a[1][2][0] == a[1][2][0]
&& x.a[1][2][1] == a[1][2][1];
}
};
struct D
{
int a, b;
constexpr bool operator == (const D &x) const
{
return x.a == a && x.b == b;
}
};
struct E {};
struct F { char c, d, e, f; };
struct G : public D, E, F
{
int g;
constexpr bool operator == (const G &x) const
{
return x.a == a && x.b == b && x.c == c && x.d == d
&& x.e == e && x.f == f && x.g == g;
}
};
struct H
{
int a, b[2], c;
constexpr bool operator == (const H &x) const
{
return x.a == a && x.b[0] == b[0] && x.b[1] == b[1] && x.c == c;
}
};
#if __SIZEOF_INT__ == 4
struct I
{
int a;
int b : 3;
int c : 24;
int d : 5;
int e;
constexpr bool operator == (const I &x) const
{
return x.a == a && x.b == b && x.c == c && x.d == d && x.e == e;
}
};
#endif
#if __SIZEOF_INT__ == 4 && __SIZEOF_LONG_LONG__ == 8
struct J
{
long long int a, b : 11, c : 3, d : 37, e : 1, f : 10, g : 2, h;
constexpr bool operator == (const J &x) const
{
return x.a == a && x.b == b && x.c == c && x.d == d && x.e == e
&& x.f == f && x.g == g && x.h == h;
}
};
struct K
{
long long int a, b, c;
constexpr bool operator == (const K &x) const
{
return x.a == a && x.b == b && x.c == c;
}
};
struct M
{
signed a : 6, b : 7, c : 6, d : 5;
unsigned char e;
unsigned int f;
long long int g;
constexpr bool operator == (const M &x) const
{
return x.a == a && x.b == b && x.c == c && x.d == d && x.e == e
&& x.f == f && x.g == g;
}
};
struct N
{
unsigned long long int a, b;
constexpr bool operator == (const N &x) const
{
return x.a == a && x.b == b;
}
};
#endif
static_assert (check <unsigned int> (0), "");
static_assert (check <long long int> (0xdeadbeeffeedbac1ULL), "");
static_assert (check <signed char> ((unsigned char) 42), "");
static_assert (check <char> ((unsigned char) 42), "");
static_assert (check <unsigned char> ((unsigned char) 42), "");
static_assert (check <signed char> ((signed char) 42), "");
static_assert (check <char> ((signed char) 42), "");
static_assert (check <unsigned char> ((signed char) 42), "");
static_assert (check <signed char> ((char) 42), "");
static_assert (check <char> ((char) 42), "");
static_assert (check <unsigned char> ((char) 42), "");
#if __SIZEOF_INT__ == __SIZEOF_FLOAT__
static_assert (check <int> (2.5f), "");
static_assert (check <unsigned int> (136.5f), "");
#endif
#if __SIZEOF_LONG_LONG__ == __SIZEOF_DOUBLE__
static_assert (check <long long> (2.5), "");
static_assert (check <long long unsigned> (123456.75), "");
#endif
static_assert (check <B> (A{ 1, 2, 3 }), "");
static_assert (check <A> (B{ 4, 5, 6 }), "");
#if __SIZEOF_INT__ == 4
static_assert (check <C> (A{ 7, 8, 9 }), "");
static_assert (check <C> (B{ 10, 11, 12 }), "");
static_assert (check <A> (C{ { { { 13, 14 }, { 15, 16 }, { 17, 18 } },
{ { 19, 20 }, { 21, 22 }, { 23, 24 } } } }), "");
constexpr unsigned char c[] = { 1, 2, 3, 4 };
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
static_assert (bit_cast <unsigned int> (c) == 0x04030201U, "");
#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
static_assert (bit_cast <unsigned int> (c) == 0x01020304U, "");
#endif
#if __cplusplus >= 201703L
static_assert (check <G> (H { 0x12345678, { 0x23456789, 0x5a876543 }, 0x3ba78654 }), "");
#endif
constexpr int d[] = { 0x12345678, 0x23456789, 0x5a876543, 0x3ba78654 };
static_assert (bit_cast <G> (d) == bit_cast <G> (H { 0x12345678, { 0x23456789, 0x5a876543 }, 0x3ba78654 }), "");
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
static_assert (bit_cast <I> (A { 0x7efa3412, 0x5a876543, 0x1eeffeed })
== I { 0x7efa3412, 3, 0x50eca8, 0xb, 0x1eeffeed }, "");
static_assert (bit_cast <A> (I { 0x7efa3412, 3, 0x50eca8, 0xb, 0x1eeffeed })
== A { 0x7efa3412, 0x5a876543, 0x1eeffeed }, "");
#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
static_assert (bit_cast <I> (A { 0x7efa3412, 0x5a876543, 0x1eeffeed })
== I { 0x7efa3412, 2, -0x2bc4d6, 0x3, 0x1eeffeed }, "");
static_assert (bit_cast <A> (I { 0x7efa3412, 2, -0x2bc4d6, 0x3, 0x1eeffeed })
== A { 0x7efa3412, 0x5a876543, 0x1eeffeed }, "");
#endif
#endif
#if 2 * __SIZEOF_INT__ == __SIZEOF_LONG_LONG__ && __SIZEOF_INT__ >= 4
constexpr unsigned long long a = 0xdeadbeeffee1deadULL;
constexpr unsigned b[] = { 0xfeedbacU, 0xbeeffeedU };
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
static_assert (bit_cast <D> (a) == D { int (0xfee1deadU), int (0xdeadbeefU) }, "");
static_assert (bit_cast <unsigned long long> (b) == 0xbeeffeed0feedbacULL, "");
#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
static_assert (bit_cast <D> (a) == D { int (0xdeadbeefU), int (0xfee1deadU) }, "");
static_assert (bit_cast <unsigned long long> (b) == 0x0feedbacbeeffeedULL, "");
#endif
#endif
#if __SIZEOF_INT__ == 4 && __SIZEOF_LONG_LONG__ == 8
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
static_assert (bit_cast <J> (K { 0x0feedbacdeadbeefLL, 7862463375103529997LL, 0x0feedbacdeadbeefLL })
== J { 0x0feedbacdeadbeefLL, -1011, 2, -0xbacdeadbeLL, -1, -303, 1, 0x0feedbacdeadbeefLL }, "");
static_assert (bit_cast <K> (J { 0x0feedbacdeadbeefLL, -1011, 2, -0xbacdeadbeLL, -1, -303, 1, 0x0feedbacdeadbeefLL })
== K { 0x0feedbacdeadbeefLL, 7862463375103529997LL, 0x0feedbacdeadbeefLL }, "");
static_assert (bit_cast <M> (N { 0xfeedbacdeadbeef8ULL, 0x123456789abcde42ULL })
== M { -8, 59, 31, -5, 234, 0xfeedbacdU, 0x123456789abcde42ULL }, "");
static_assert (bit_cast <N> (M { -8, 59, 31, -5, 234, 0xfeedbacdU, 0x123456789abcde42ULL })
== N { 0xfeedbacdeadbeef8ULL, 0x123456789abcde42ULL }, "");
#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
static_assert (bit_cast <J> (K { 0x0feedbacdeadbeefLL, -9103311533965288635LL, 0x0feedbacdeadbeefLL })
== J { 0x0feedbacdeadbeefLL, -1011, 2, -0xbacdeadbeLL, -1, -303, 1, 0x0feedbacdeadbeefLL }, "");
static_assert (bit_cast <K> (J { 0x0feedbacdeadbeefLL, -1011, 2, -0xbacdeadbeLL, -1, -303, 1, 0x0feedbacdeadbeefLL })
== K { 0x0feedbacdeadbeefLL, -9103311533965288635LL, 0x0feedbacdeadbeefLL }, "");
static_assert (bit_cast <M> (N { 0xfeedbacdeadbeef8ULL, 0x123456789abcde42ULL })
== M { -1, -35, -19, -6, 205, 0xeadbeef8U, 0x123456789abcde42ULL }, "");
static_assert (bit_cast <N> (M { -1, -35, -19, -6, 205, 0xeadbeef8U, 0x123456789abcde42ULL })
== N { 0xfeedbacdeadbeef8ULL, 0x123456789abcde42ULL }, "");
#endif
#endif