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