1 //===----------------------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 // type_traits
10 
11 // aligned_storage
12 //
13 //  Issue 3034 added:
14 //  The member typedef type shall be a trivial standard-layout type.
15 
16 #include <type_traits>
17 #include <cstddef>       // for std::max_align_t
18 #include "test_macros.h"
19 
20 // The following tests assume naturally aligned types exist
21 // up to 64bit (double). For larger types, max_align_t should
22 // give the correct alignment. For pre-C++11 testing, only
23 // the lower bound is checked.
24 
25 #if TEST_STD_VER < 11
26 struct natural_alignment {
27     long t1;
28     long long t2;
29     double t3;
30     long double t4;
31 };
32 #endif
33 
34 int main(int, char**)
35 {
36     {
37     typedef std::aligned_storage<10, 1 >::type T1;
38 #if TEST_STD_VER > 11
39     ASSERT_SAME_TYPE(T1, std::aligned_storage_t<10, 1>);
40 #endif
41 #if TEST_STD_VER <= 17
42     static_assert(std::is_pod<T1>::value, "");
43 #endif
44     static_assert(std::is_trivial<T1>::value, "");
45     static_assert(std::is_standard_layout<T1>::value, "");
46     static_assert(std::alignment_of<T1>::value == 1, "");
47     static_assert(sizeof(T1) == 10, "");
48     }
49     {
50     typedef std::aligned_storage<10, 2 >::type T1;
51 #if TEST_STD_VER > 11
52     ASSERT_SAME_TYPE(T1, std::aligned_storage_t<10, 2>);
53 #endif
54 #if TEST_STD_VER <= 17
55     static_assert(std::is_pod<T1>::value, "");
56 #endif
57     static_assert(std::is_trivial<T1>::value, "");
58     static_assert(std::is_standard_layout<T1>::value, "");
59     static_assert(std::alignment_of<T1>::value == 2, "");
60     static_assert(sizeof(T1) == 10, "");
61     }
62     {
63     typedef std::aligned_storage<10, 4 >::type T1;
64 #if TEST_STD_VER > 11
65     ASSERT_SAME_TYPE(T1, std::aligned_storage_t<10, 4>);
66 #endif
67 #if TEST_STD_VER <= 17
68     static_assert(std::is_pod<T1>::value, "");
69 #endif
70     static_assert(std::is_trivial<T1>::value, "");
71     static_assert(std::is_standard_layout<T1>::value, "");
72     static_assert(std::alignment_of<T1>::value == 4, "");
73     static_assert(sizeof(T1) == 12, "");
74     }
75     {
76     typedef std::aligned_storage<10, 8 >::type T1;
77 #if TEST_STD_VER > 11
78     ASSERT_SAME_TYPE(T1, std::aligned_storage_t<10, 8>);
79 #endif
80 #if TEST_STD_VER <= 17
81     static_assert(std::is_pod<T1>::value, "");
82 #endif
83     static_assert(std::is_trivial<T1>::value, "");
84     static_assert(std::is_standard_layout<T1>::value, "");
85     static_assert(std::alignment_of<T1>::value == 8, "");
86     static_assert(sizeof(T1) == 16, "");
87     }
88     {
89     typedef std::aligned_storage<10, 16 >::type T1;
90 #if TEST_STD_VER > 11
91     ASSERT_SAME_TYPE(T1, std::aligned_storage_t<10, 16>);
92 #endif
93 #if TEST_STD_VER <= 17
94     static_assert(std::is_pod<T1>::value, "");
95 #endif
96     static_assert(std::is_trivial<T1>::value, "");
97     static_assert(std::is_standard_layout<T1>::value, "");
98     static_assert(std::alignment_of<T1>::value == 16, "");
99     static_assert(sizeof(T1) == 16, "");
100     }
101     {
102     typedef std::aligned_storage<10, 32 >::type T1;
103 #if TEST_STD_VER > 11
104     ASSERT_SAME_TYPE(T1, std::aligned_storage_t<10, 32>);
105 #endif
106 #if TEST_STD_VER <= 17
107     static_assert(std::is_pod<T1>::value, "");
108 #endif
109     static_assert(std::is_trivial<T1>::value, "");
110     static_assert(std::is_standard_layout<T1>::value, "");
111     static_assert(std::alignment_of<T1>::value == 32, "");
112     static_assert(sizeof(T1) == 32, "");
113     }
114     {
115     typedef std::aligned_storage<20, 32 >::type T1;
116 #if TEST_STD_VER > 11
117     ASSERT_SAME_TYPE(T1, std::aligned_storage_t<20, 32>);
118 #endif
119 #if TEST_STD_VER <= 17
120     static_assert(std::is_pod<T1>::value, "");
121 #endif
122     static_assert(std::is_trivial<T1>::value, "");
123     static_assert(std::is_standard_layout<T1>::value, "");
124     static_assert(std::alignment_of<T1>::value == 32, "");
125     static_assert(sizeof(T1) == 32, "");
126     }
127     {
128     typedef std::aligned_storage<40, 32 >::type T1;
129 #if TEST_STD_VER > 11
130     ASSERT_SAME_TYPE(T1, std::aligned_storage_t<40, 32>);
131 #endif
132 #if TEST_STD_VER <= 17
133     static_assert(std::is_pod<T1>::value, "");
134 #endif
135     static_assert(std::is_trivial<T1>::value, "");
136     static_assert(std::is_standard_layout<T1>::value, "");
137     static_assert(std::alignment_of<T1>::value == 32, "");
138     static_assert(sizeof(T1) == 64, "");
139     }
140     {
141     typedef std::aligned_storage<12, 16 >::type T1;
142 #if TEST_STD_VER > 11
143     ASSERT_SAME_TYPE(T1, std::aligned_storage_t<12, 16>);
144 #endif
145 #if TEST_STD_VER <= 17
146     static_assert(std::is_pod<T1>::value, "");
147 #endif
148     static_assert(std::is_trivial<T1>::value, "");
149     static_assert(std::is_standard_layout<T1>::value, "");
150     static_assert(std::alignment_of<T1>::value == 16, "");
151     static_assert(sizeof(T1) == 16, "");
152     }
153     {
154     typedef std::aligned_storage<1>::type T1;
155 #if TEST_STD_VER > 11
156     ASSERT_SAME_TYPE(T1, std::aligned_storage_t<1>);
157 #endif
158 #if TEST_STD_VER <= 17
159     static_assert(std::is_pod<T1>::value, "");
160 #endif
161     static_assert(std::is_trivial<T1>::value, "");
162     static_assert(std::is_standard_layout<T1>::value, "");
163     static_assert(std::alignment_of<T1>::value == 1, "");
164     static_assert(sizeof(T1) == 1, "");
165     }
166     {
167     typedef std::aligned_storage<2>::type T1;
168 #if TEST_STD_VER > 11
169     ASSERT_SAME_TYPE(T1, std::aligned_storage_t<2>);
170 #endif
171 #if TEST_STD_VER <= 17
172     static_assert(std::is_pod<T1>::value, "");
173 #endif
174     static_assert(std::is_trivial<T1>::value, "");
175     static_assert(std::is_standard_layout<T1>::value, "");
176     static_assert(std::alignment_of<T1>::value == 2, "");
177     static_assert(sizeof(T1) == 2, "");
178     }
179     {
180     typedef std::aligned_storage<3>::type T1;
181 #if TEST_STD_VER > 11
182     ASSERT_SAME_TYPE(T1, std::aligned_storage_t<3>);
183 #endif
184 #if TEST_STD_VER <= 17
185     static_assert(std::is_pod<T1>::value, "");
186 #endif
187     static_assert(std::is_trivial<T1>::value, "");
188     static_assert(std::is_standard_layout<T1>::value, "");
189     static_assert(std::alignment_of<T1>::value == 2, "");
190     static_assert(sizeof(T1) == 4, "");
191     }
192     {
193     typedef std::aligned_storage<4>::type T1;
194 #if TEST_STD_VER > 11
195     ASSERT_SAME_TYPE(T1, std::aligned_storage_t<4>);
196 #endif
197 #if TEST_STD_VER <= 17
198     static_assert(std::is_pod<T1>::value, "");
199 #endif
200     static_assert(std::is_trivial<T1>::value, "");
201     static_assert(std::is_standard_layout<T1>::value, "");
202     static_assert(std::alignment_of<T1>::value == 4, "");
203     static_assert(sizeof(T1) == 4, "");
204     }
205     {
206     typedef std::aligned_storage<5>::type T1;
207 #if TEST_STD_VER > 11
208     ASSERT_SAME_TYPE(T1, std::aligned_storage_t<5>);
209 #endif
210 #if TEST_STD_VER <= 17
211     static_assert(std::is_pod<T1>::value, "");
212 #endif
213     static_assert(std::is_trivial<T1>::value, "");
214     static_assert(std::is_standard_layout<T1>::value, "");
215     static_assert(std::alignment_of<T1>::value == 4, "");
216     static_assert(sizeof(T1) == 8, "");
217     }
218     {
219     typedef std::aligned_storage<7>::type T1;
220 #if TEST_STD_VER > 11
221     ASSERT_SAME_TYPE(T1, std::aligned_storage_t<7>);
222 #endif
223     static_assert(std::is_trivial<T1>::value, "");
224     static_assert(std::is_standard_layout<T1>::value, "");
225     static_assert(std::alignment_of<T1>::value == 4, "");
226     static_assert(sizeof(T1) == 8, "");
227     }
228     {
229     typedef std::aligned_storage<8>::type T1;
230 #if TEST_STD_VER > 11
231     ASSERT_SAME_TYPE(T1, std::aligned_storage_t<8>);
232 #endif
233 #if TEST_STD_VER <= 17
234     static_assert(std::is_pod<T1>::value, "");
235 #endif
236     static_assert(std::is_trivial<T1>::value, "");
237     static_assert(std::is_standard_layout<T1>::value, "");
238     static_assert(std::alignment_of<T1>::value == 8, "");
239     static_assert(sizeof(T1) == 8, "");
240     }
241     {
242     typedef std::aligned_storage<9>::type T1;
243 #if TEST_STD_VER > 11
244     ASSERT_SAME_TYPE(T1, std::aligned_storage_t<9>);
245 #endif
246 #if TEST_STD_VER <= 17
247     static_assert(std::is_pod<T1>::value, "");
248 #endif
249     static_assert(std::is_trivial<T1>::value, "");
250     static_assert(std::is_standard_layout<T1>::value, "");
251     static_assert(std::alignment_of<T1>::value == 8, "");
252     static_assert(sizeof(T1) == 16, "");
253     }
254     {
255     typedef std::aligned_storage<15>::type T1;
256 #if TEST_STD_VER > 11
257     ASSERT_SAME_TYPE(T1, std::aligned_storage_t<15>);
258 #endif
259 #if TEST_STD_VER <= 17
260     static_assert(std::is_pod<T1>::value, "");
261 #endif
262     static_assert(std::is_trivial<T1>::value, "");
263     static_assert(std::is_standard_layout<T1>::value, "");
264     static_assert(std::alignment_of<T1>::value == 8, "");
265     static_assert(sizeof(T1) == 16, "");
266     }
267     {
268     typedef std::aligned_storage<16>::type T1;
269 #if TEST_STD_VER > 11
270     ASSERT_SAME_TYPE(T1, std::aligned_storage_t<16>);
271 #endif
272     static_assert(std::is_trivial<T1>::value, "");
273     static_assert(std::is_standard_layout<T1>::value, "");
274 #if TEST_STD_VER >= 11
275     const size_t alignment = TEST_ALIGNOF(std::max_align_t) > 16 ?
276         16 : TEST_ALIGNOF(std::max_align_t);
277     static_assert(std::alignment_of<T1>::value == alignment, "");
278 #else
279     static_assert(std::alignment_of<T1>::value >=
280                   TEST_ALIGNOF(natural_alignment), "");
281     static_assert(std::alignment_of<T1>::value <= 16, "");
282 #endif
283     static_assert(sizeof(T1) == 16, "");
284     }
285     {
286     typedef std::aligned_storage<17>::type T1;
287 #if TEST_STD_VER > 11
288     ASSERT_SAME_TYPE(T1, std::aligned_storage_t<17>);
289 #endif
290     static_assert(std::is_trivial<T1>::value, "");
291     static_assert(std::is_standard_layout<T1>::value, "");
292 #if TEST_STD_VER >= 11
293     const size_t alignment = TEST_ALIGNOF(std::max_align_t) > 16 ?
294         16 : TEST_ALIGNOF(std::max_align_t);
295     static_assert(std::alignment_of<T1>::value == alignment, "");
296     static_assert(sizeof(T1) == 16 + alignment, "");
297 #else
298     static_assert(std::alignment_of<T1>::value >=
299                   TEST_ALIGNOF(natural_alignment), "");
300     static_assert(std::alignment_of<T1>::value <= 16);
301     static_assert(sizeof(T1) % TEST_ALIGNOF(natural_alignment) == 0, "");
302 #endif
303     }
304     {
305     typedef std::aligned_storage<10>::type T1;
306 #if TEST_STD_VER > 11
307     ASSERT_SAME_TYPE(T1, std::aligned_storage_t<10>);
308 #endif
309     static_assert(std::is_trivial<T1>::value, "");
310     static_assert(std::is_standard_layout<T1>::value, "");
311     static_assert(std::alignment_of<T1>::value == 8, "");
312     static_assert(sizeof(T1) == 16, "");
313     }
314   {
315     const int Align = 65536;
316     typedef typename std::aligned_storage<1, Align>::type T1;
317     static_assert(std::is_trivial<T1>::value, "");
318     static_assert(std::is_standard_layout<T1>::value, "");
319     static_assert(std::alignment_of<T1>::value == Align, "");
320     static_assert(sizeof(T1) == Align, "");
321   }
322 
323   return 0;
324 }
325