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