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
28struct natural_alignment {
29 long t1;
30 long long t2;
31 double t3;
32 long double t4;
33};
34#endif
35
36int 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_trivially_copyable<T1>::value, "");
47 static_assert(std::is_trivially_default_constructible<T1>::value, "");
48 static_assert(std::is_standard_layout<T1>::value, "");
49 static_assert(std::alignment_of<T1>::value == 1, "");
50 static_assert(sizeof(T1) == 10, "");
51 }
52 {
53 typedef std::aligned_storage<10, 2 >::type T1;
54#if TEST_STD_VER > 11
55 ASSERT_SAME_TYPE(T1, std::aligned_storage_t<10, 2>);
56#endif
57#if TEST_STD_VER <= 17
58 static_assert(std::is_pod<T1>::value, "");
59#endif
60 static_assert(std::is_trivially_copyable<T1>::value, "");
61 static_assert(std::is_trivially_default_constructible<T1>::value, "");
62 static_assert(std::is_standard_layout<T1>::value, "");
63 static_assert(std::alignment_of<T1>::value == 2, "");
64 static_assert(sizeof(T1) == 10, "");
65 }
66 {
67 typedef std::aligned_storage<10, 4 >::type T1;
68#if TEST_STD_VER > 11
69 ASSERT_SAME_TYPE(T1, std::aligned_storage_t<10, 4>);
70#endif
71#if TEST_STD_VER <= 17
72 static_assert(std::is_pod<T1>::value, "");
73#endif
74 static_assert(std::is_trivially_copyable<T1>::value, "");
75 static_assert(std::is_trivially_default_constructible<T1>::value, "");
76 static_assert(std::is_standard_layout<T1>::value, "");
77 static_assert(std::alignment_of<T1>::value == 4, "");
78 static_assert(sizeof(T1) == 12, "");
79 }
80 {
81 typedef std::aligned_storage<10, 8 >::type T1;
82#if TEST_STD_VER > 11
83 ASSERT_SAME_TYPE(T1, std::aligned_storage_t<10, 8>);
84#endif
85#if TEST_STD_VER <= 17
86 static_assert(std::is_pod<T1>::value, "");
87#endif
88 static_assert(std::is_trivially_copyable<T1>::value, "");
89 static_assert(std::is_trivially_default_constructible<T1>::value, "");
90 static_assert(std::is_standard_layout<T1>::value, "");
91 static_assert(std::alignment_of<T1>::value == 8, "");
92 static_assert(sizeof(T1) == 16, "");
93 }
94 {
95 typedef std::aligned_storage<10, 16 >::type T1;
96#if TEST_STD_VER > 11
97 ASSERT_SAME_TYPE(T1, std::aligned_storage_t<10, 16>);
98#endif
99#if TEST_STD_VER <= 17
100 static_assert(std::is_pod<T1>::value, "");
101#endif
102 static_assert(std::is_trivially_copyable<T1>::value, "");
103 static_assert(std::is_trivially_default_constructible<T1>::value, "");
104 static_assert(std::is_standard_layout<T1>::value, "");
105 static_assert(std::alignment_of<T1>::value == 16, "");
106 static_assert(sizeof(T1) == 16, "");
107 }
108 {
109 typedef std::aligned_storage<10, 32 >::type T1;
110#if TEST_STD_VER > 11
111 ASSERT_SAME_TYPE(T1, std::aligned_storage_t<10, 32>);
112#endif
113#if TEST_STD_VER <= 17
114 static_assert(std::is_pod<T1>::value, "");
115#endif
116 static_assert(std::is_trivially_copyable<T1>::value, "");
117 static_assert(std::is_trivially_default_constructible<T1>::value, "");
118 static_assert(std::is_standard_layout<T1>::value, "");
119 static_assert(std::alignment_of<T1>::value == 32, "");
120 static_assert(sizeof(T1) == 32, "");
121 }
122 {
123 typedef std::aligned_storage<20, 32 >::type T1;
124#if TEST_STD_VER > 11
125 ASSERT_SAME_TYPE(T1, std::aligned_storage_t<20, 32>);
126#endif
127#if TEST_STD_VER <= 17
128 static_assert(std::is_pod<T1>::value, "");
129#endif
130 static_assert(std::is_trivially_copyable<T1>::value, "");
131 static_assert(std::is_trivially_default_constructible<T1>::value, "");
132 static_assert(std::is_standard_layout<T1>::value, "");
133 static_assert(std::alignment_of<T1>::value == 32, "");
134 static_assert(sizeof(T1) == 32, "");
135 }
136 {
137 typedef std::aligned_storage<40, 32 >::type T1;
138#if TEST_STD_VER > 11
139 ASSERT_SAME_TYPE(T1, std::aligned_storage_t<40, 32>);
140#endif
141#if TEST_STD_VER <= 17
142 static_assert(std::is_pod<T1>::value, "");
143#endif
144 static_assert(std::is_trivially_copyable<T1>::value, "");
145 static_assert(std::is_trivially_default_constructible<T1>::value, "");
146 static_assert(std::is_standard_layout<T1>::value, "");
147 static_assert(std::alignment_of<T1>::value == 32, "");
148 static_assert(sizeof(T1) == 64, "");
149 }
150 {
151 typedef std::aligned_storage<12, 16 >::type T1;
152#if TEST_STD_VER > 11
153 ASSERT_SAME_TYPE(T1, std::aligned_storage_t<12, 16>);
154#endif
155#if TEST_STD_VER <= 17
156 static_assert(std::is_pod<T1>::value, "");
157#endif
158 static_assert(std::is_trivially_copyable<T1>::value, "");
159 static_assert(std::is_trivially_default_constructible<T1>::value, "");
160 static_assert(std::is_standard_layout<T1>::value, "");
161 static_assert(std::alignment_of<T1>::value == 16, "");
162 static_assert(sizeof(T1) == 16, "");
163 }
164 {
165 typedef std::aligned_storage<1>::type T1;
166#if TEST_STD_VER > 11
167 ASSERT_SAME_TYPE(T1, std::aligned_storage_t<1>);
168#endif
169#if TEST_STD_VER <= 17
170 static_assert(std::is_pod<T1>::value, "");
171#endif
172 static_assert(std::is_trivially_copyable<T1>::value, "");
173 static_assert(std::is_trivially_default_constructible<T1>::value, "");
174 static_assert(std::is_standard_layout<T1>::value, "");
175 static_assert(std::alignment_of<T1>::value == 1, "");
176 static_assert(sizeof(T1) == 1, "");
177 }
178 {
179 typedef std::aligned_storage<2>::type T1;
180#if TEST_STD_VER > 11
181 ASSERT_SAME_TYPE(T1, std::aligned_storage_t<2>);
182#endif
183#if TEST_STD_VER <= 17
184 static_assert(std::is_pod<T1>::value, "");
185#endif
186 static_assert(std::is_trivially_copyable<T1>::value, "");
187 static_assert(std::is_trivially_default_constructible<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) == 2, "");
191 }
192 {
193 typedef std::aligned_storage<3>::type T1;
194#if TEST_STD_VER > 11
195 ASSERT_SAME_TYPE(T1, std::aligned_storage_t<3>);
196#endif
197#if TEST_STD_VER <= 17
198 static_assert(std::is_pod<T1>::value, "");
199#endif
200 static_assert(std::is_trivially_copyable<T1>::value, "");
201 static_assert(std::is_trivially_default_constructible<T1>::value, "");
202 static_assert(std::is_standard_layout<T1>::value, "");
203 static_assert(std::alignment_of<T1>::value == 2, "");
204 static_assert(sizeof(T1) == 4, "");
205 }
206 {
207 typedef std::aligned_storage<4>::type T1;
208#if TEST_STD_VER > 11
209 ASSERT_SAME_TYPE(T1, std::aligned_storage_t<4>);
210#endif
211#if TEST_STD_VER <= 17
212 static_assert(std::is_pod<T1>::value, "");
213#endif
214 static_assert(std::is_trivially_copyable<T1>::value, "");
215 static_assert(std::is_trivially_default_constructible<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) == 4, "");
219 }
220 {
221 typedef std::aligned_storage<5>::type T1;
222#if TEST_STD_VER > 11
223 ASSERT_SAME_TYPE(T1, std::aligned_storage_t<5>);
224#endif
225#if TEST_STD_VER <= 17
226 static_assert(std::is_pod<T1>::value, "");
227#endif
228 static_assert(std::is_trivially_copyable<T1>::value, "");
229 static_assert(std::is_trivially_default_constructible<T1>::value, "");
230 static_assert(std::is_standard_layout<T1>::value, "");
231 static_assert(std::alignment_of<T1>::value == 4, "");
232 static_assert(sizeof(T1) == 8, "");
233 }
234 {
235 typedef std::aligned_storage<7>::type T1;
236#if TEST_STD_VER > 11
237 ASSERT_SAME_TYPE(T1, std::aligned_storage_t<7>);
238#endif
239 static_assert(std::is_trivially_copyable<T1>::value, "");
240 static_assert(std::is_trivially_default_constructible<T1>::value, "");
241 static_assert(std::is_standard_layout<T1>::value, "");
242 static_assert(std::alignment_of<T1>::value == 4, "");
243 static_assert(sizeof(T1) == 8, "");
244 }
245 {
246 typedef std::aligned_storage<8>::type T1;
247#if TEST_STD_VER > 11
248 ASSERT_SAME_TYPE(T1, std::aligned_storage_t<8>);
249#endif
250#if TEST_STD_VER <= 17
251 static_assert(std::is_pod<T1>::value, "");
252#endif
253 static_assert(std::is_trivially_copyable<T1>::value, "");
254 static_assert(std::is_trivially_default_constructible<T1>::value, "");
255 static_assert(std::is_standard_layout<T1>::value, "");
256 static_assert(std::alignment_of<T1>::value == 8, "");
257 static_assert(sizeof(T1) == 8, "");
258 }
259 {
260 typedef std::aligned_storage<9>::type T1;
261#if TEST_STD_VER > 11
262 ASSERT_SAME_TYPE(T1, std::aligned_storage_t<9>);
263#endif
264#if TEST_STD_VER <= 17
265 static_assert(std::is_pod<T1>::value, "");
266#endif
267 static_assert(std::is_trivially_copyable<T1>::value, "");
268 static_assert(std::is_trivially_default_constructible<T1>::value, "");
269 static_assert(std::is_standard_layout<T1>::value, "");
270 static_assert(std::alignment_of<T1>::value == 8, "");
271 static_assert(sizeof(T1) == 16, "");
272 }
273 {
274 typedef std::aligned_storage<15>::type T1;
275#if TEST_STD_VER > 11
276 ASSERT_SAME_TYPE(T1, std::aligned_storage_t<15>);
277#endif
278#if TEST_STD_VER <= 17
279 static_assert(std::is_pod<T1>::value, "");
280#endif
281 static_assert(std::is_trivially_copyable<T1>::value, "");
282 static_assert(std::is_trivially_default_constructible<T1>::value, "");
283 static_assert(std::is_standard_layout<T1>::value, "");
284 static_assert(std::alignment_of<T1>::value == 8, "");
285 static_assert(sizeof(T1) == 16, "");
286 }
287 {
288 typedef std::aligned_storage<16>::type T1;
289#if TEST_STD_VER > 11
290 ASSERT_SAME_TYPE(T1, std::aligned_storage_t<16>);
291#endif
292 static_assert(std::is_trivially_copyable<T1>::value, "");
293 static_assert(std::is_trivially_default_constructible<T1>::value, "");
294 static_assert(std::is_standard_layout<T1>::value, "");
295#if TEST_STD_VER >= 11
296 const std::size_t alignment = TEST_ALIGNOF(std::max_align_t) > 16 ?
297 16 : TEST_ALIGNOF(std::max_align_t);
298 static_assert(std::alignment_of<T1>::value == 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#endif
304 static_assert(sizeof(T1) == 16, "");
305 }
306 {
307 typedef std::aligned_storage<17>::type T1;
308#if TEST_STD_VER > 11
309 ASSERT_SAME_TYPE(T1, std::aligned_storage_t<17>);
310#endif
311 static_assert(std::is_trivially_copyable<T1>::value, "");
312 static_assert(std::is_trivially_default_constructible<T1>::value, "");
313 static_assert(std::is_standard_layout<T1>::value, "");
314#if TEST_STD_VER >= 11
315 const std::size_t alignment = TEST_ALIGNOF(std::max_align_t) > 16 ?
316 16 : TEST_ALIGNOF(std::max_align_t);
317 static_assert(std::alignment_of<T1>::value == alignment, "");
318 static_assert(sizeof(T1) == 16 + alignment, "");
319#else
320 static_assert(std::alignment_of<T1>::value >=
321 TEST_ALIGNOF(natural_alignment), "");
322 static_assert(std::alignment_of<T1>::value <= 16, "");
323 static_assert(sizeof(T1) % TEST_ALIGNOF(natural_alignment) == 0, "");
324#endif
325 }
326 {
327 typedef std::aligned_storage<10>::type T1;
328#if TEST_STD_VER > 11
329 ASSERT_SAME_TYPE(T1, std::aligned_storage_t<10>);
330#endif
331 static_assert(std::is_trivially_copyable<T1>::value, "");
332 static_assert(std::is_trivially_default_constructible<T1>::value, "");
333 static_assert(std::is_standard_layout<T1>::value, "");
334 static_assert(std::alignment_of<T1>::value == 8, "");
335 static_assert(sizeof(T1) == 16, "");
336 }
337 {
338 const int Align = 8192;
339 typedef typename std::aligned_storage<1, Align>::type T1;
340 static_assert(std::is_trivially_copyable<T1>::value, "");
341 static_assert(std::is_trivially_default_constructible<T1>::value, "");
342 static_assert(std::is_standard_layout<T1>::value, "");
343 static_assert(std::alignment_of<T1>::value == Align, "");
344 static_assert(sizeof(T1) == Align, "");
345 }
346#ifndef _WIN32
347 // Windows only supports alignment up to 8192 bytes.
348 {
349 const int Align = 65536;
350 typedef typename std::aligned_storage<1, Align>::type T1;
351 static_assert(std::is_trivially_copyable<T1>::value, "");
352 static_assert(std::is_trivially_default_constructible<T1>::value, "");
353 static_assert(std::is_standard_layout<T1>::value, "");
354 static_assert(std::alignment_of<T1>::value == Align, "");
355 static_assert(sizeof(T1) == Align, "");
356 }
357#endif
358
359 return 0;
360}
361

source code of libcxx/test/std/utilities/meta/meta.trans/meta.trans.other/aligned_storage.pass.cpp