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_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

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