1 // P0466R5
2 // { dg-do compile { target c++20 } }
3 
4 namespace std
5 {
6 template <typename T, T v>
7 struct integral_constant
8 {
9   static constexpr T value = v;
10 };
11 
12 template <typename, typename>
13 struct is_layout_compatible;
14 
15 template<typename T, typename U>
16 struct is_layout_compatible
17   : public integral_constant <bool, __is_layout_compatible (T, U)>
18 {
19 };
20 
21 template <typename T, typename U>
22 inline constexpr bool is_layout_compatible_v = __is_layout_compatible (T, U);
23 }
24 
25 struct A { int a; char b; };
26 struct B { const int c; volatile char d; };
27 struct C { int a : 1; int : 7; int : 0; int b : 2; };
28 struct D { int : 1; int c : 7; int : 0; int : 2; };
29 struct E { int f : 1; int : 7; int g : 2; };
30 struct F { int a; signed char b; };
31 union G { int a; long long b; signed char c; unsigned char d; int e; };
32 union H { long long f; unsigned char g; int h; int i; signed char j; };
33 struct I : public A {};
34 struct J {};
35 struct K : public J {};
36 struct L {};
37 struct M : public K, L { const int a; volatile char b; };
38 struct N {};
39 struct O : public N, M {};
40 struct P { int a; private: int b; public: int c; };
41 struct Q { int a; private: int b; public: int c; };
42 union U1 { int a; private: int b; public: int c; };
43 union U2 { int a; private: int b; public: int c; };
44 struct S {};
45 struct T {};
46 struct W;
47 struct X;
48 enum E1 : int { E11, E12 };
49 enum E2 : int { E21, E22 };
50 enum E3 : long { E31, E32 };
51 enum E4 { E41, E42 };
52 enum E5 { E51, E52 };
53 
54 static_assert (std::is_layout_compatible<int, const int>::value);
55 static_assert (std::is_layout_compatible_v<double, volatile double>);
56 static_assert (std::is_layout_compatible_v<A, B>);
57 static_assert (std::is_layout_compatible_v<C, D>);
58 static_assert (!std::is_layout_compatible_v<int, unsigned int>);
59 static_assert (!std::is_layout_compatible_v<A, F>);
60 static_assert (std::is_layout_compatible_v<G, H>);
61 static_assert (std::is_layout_compatible_v<S, T>);
62 static_assert (std::is_layout_compatible_v<A[3], A[3]>);
63 static_assert (std::is_layout_compatible_v<A[], A[]>);
64 static_assert (!std::is_layout_compatible_v<S[1], T[1]>);
65 static_assert (std::is_layout_compatible_v<W[], W[]>);
66 static_assert (!std::is_layout_compatible_v<W[], X[]>);
67 static_assert (!std::is_layout_compatible_v<D, E>);
68 static_assert (std::is_layout_compatible_v<void, const void>);
69 static_assert (std::is_layout_compatible_v<I, const A>);
70 static_assert (std::is_layout_compatible_v<volatile A, const I>);
71 static_assert (std::is_layout_compatible_v<M, A>);
72 static_assert (std::is_layout_compatible_v<O, M>);
73 static_assert (std::is_layout_compatible_v<A, O>);
74 static_assert (std::is_layout_compatible_v<P, P>);
75 static_assert (!std::is_layout_compatible_v<P, Q>);
76 static_assert (std::is_layout_compatible_v<U1, U1>);
77 static_assert (!std::is_layout_compatible_v<U1, U2>);
78 static_assert (std::is_layout_compatible_v<E1, E2>);
79 static_assert (!std::is_layout_compatible_v<E1, E3>);
80 static_assert (std::is_layout_compatible_v<E4, E5>);
81