Ne.app NeANT
The Ne.app NeANT User module of the NeANT distribution.
20.meta.trans.other.cpp
Go to the documentation of this file.
1// -*- C++ -*-
2
30#include <rw_driver.h>
31#include <rw/_defs.h>
32
33// compile out all test code if extensions disabled
34#ifndef _RWSTD_NO_EXT_CXX_0X
35
36#include <type_traits>
37
38#include <rw_printf.h> // for rwsprintfa()
39
40#include <stdlib.h> // for free()
41#include <stddef.h> // for size_t
42
43
45template <class T>
46struct is_char
47{
48 enum { val = 0 };
49};
50
52struct is_char<char>
53{
54 enum { val = 1 };
55};
56
57// this function should available _only_ if T is char
58template <class T>
59int
60enabled_if_char (typename std::enable_if<is_char<T>::val>::type* = 0)
61{
62 return 1;
63}
64
65// this function should be available if T is _not_ char
66template <class T>
67int
68enabled_if_char (typename std::enable_if<!is_char<T>::val>::type* = 0)
69{
70 return 0;
71}
72
73// must have external linkage
74int _cond_if_char (void*)
75{
76 return 0;
77}
78
79// must have external linkage
80int _cond_if_char (long*)
81{
82 return 1;
83}
84
85template <class T>
87{
88 typedef typename
89 std::conditional<is_char<T>::val, long, void>::type selector;
90
91 return _cond_if_char ((selector*)0);
92}
93
94
95
97void test_trait (int line,
98 bool select,
99 const char* trait,
100 const char* typeT,
101 const char* typeU,
102 bool success)
103{
104 rw_assert (success, 0, line,
105 "%s<%b, %s, %s>::type is%{?}n't%{;} %s as expected",
106 trait, select, typeT, typeU, !success, select ? typeT : typeU);
107}
108
109void test_trait (int line, const char* trait,
110 const char* typeT, const char* typeU,
111 bool success)
112{
113 rw_assert (success, 0, line,
114 "%s<%s>::type is%{?}n't%{;} %s as expected",
115 trait, typeT, !success, typeU);
116}
117
118void test_enable_if (int line, const char* typeT, int got, int exp)
119{
120 const bool success = got == exp;
121
122 rw_assert (success, 0, line, "%s is%{?}n't%{;} %b as expected",
123 typeT, !success, exp);
124}
125
127 size_t exp_sz, size_t got_sz,
128 size_t exp_al, size_t got_al)
129{
130 //
131 rw_assert (exp_sz <= got_sz, 0, line,
132 "std::aligned_storage<%zu, %zu>::type size is %zu; "
133 "expected %zu or more", exp_sz, exp_al, got_sz, exp_sz);
134
135 if (exp_al != 0) {
136 // alignment should be greater than or equal to expected
137 rw_assert (exp_al <= got_al, 0, line,
138 "std::aligned_storage<%zu, %zu>::type alignment is %zu; "
139 "expected %zu or more", exp_sz, exp_al, got_al, exp_al);
140 }
141 else {
142 // alignment should be less than or equal to the size of
143 // the object
144 rw_assert (got_al <= exp_sz, 0, line,
145 "std::aligned_storage<%zu, %zu>::type alignment is %zu; "
146 "expected %zu or less", exp_sz, exp_al, got_al, exp_sz);
147 }
148
149 const bool is_pow_2 = (got_al & (got_al - 1)) == 0;
150 rw_assert (is_pow_2, 0, line,
151 "std::aligned_storage<%zu, %zu>::type alignment expected "
152 "to be a power-of-two; got %zu", exp_sz, exp_al, got_al);
153}
154
155
157static void test_aligned_storage ()
158{
159#ifdef _RWSTD_NO_ALIGN_TRAITS
160
161 rw_warn (0, 0, __LINE__,
162 "test_aligned_storage disabled because "
163 "_RWSTD_NO_ALIGN_TRAITS is defined");
164
165#else
166
167#define TEST(Size,Align) \
168 { \
169 typedef std::aligned_storage<Size, Align>::type storage_t; \
170 test_aligned_storage(__LINE__, \
171 Size, sizeof (storage_t), Align, \
172 std::alignment_of<storage_t>::value); \
173 } typedef void __dummy
174
175 TEST (1, 1);
176 TEST (1, 2);
177 TEST (1, 4);
178 TEST (1, 8);
179
180 TEST (9, 1);
181 TEST (9, 2);
182 TEST (9, 4);
183 TEST (9, 8);
184
185 TEST (55, 1);
186 TEST (23, 2);
187 TEST (17, 4);
188 TEST (19, 8);
189
190#undef TEST
191#define TEST(Size) \
192 { \
193 typedef std::aligned_storage<Size>::type storage_t; \
194 test_aligned_storage(__LINE__, \
195 Size, sizeof (storage_t), 0, \
196 std::alignment_of<storage_t>::value); \
197 } typedef void __dummy
198
199 // test default alignment
200 TEST (1);
201 TEST (2);
202 TEST (4);
203 TEST (8);
204
205 TEST (3);
206 TEST (5);
207 TEST (7);
208 TEST (9);
209
210 TEST (55);
211 TEST (23);
212 TEST (17);
213 TEST (19);
214
215#undef TEST
216
217#endif // _RWSTD_NO_ALIGN_TRAITS
218}
219
220
222#ifndef _RWSTD_NO_ALIGN_TRAITS
223
224struct null_t { };
225
226// get the maximum of 8 values
227size_t max8(size_t a1, size_t a2, size_t a3, size_t a4,
228 size_t a5, size_t a6, size_t a7, size_t a8)
229{
230 size_t r = a1;
231
232 if (r < a2) r = a2;
233 if (r < a3) r = a3;
234 if (r < a4) r = a4;
235 if (r < a5) r = a5;
236 if (r < a6) r = a6;
237 if (r < a7) r = a7;
238 if (r < a8) r = a8;
239
240 return r;
241}
242
243template <size_t Len,
244 class T1 , class T2 = null_t,
245 class T3 = null_t, class T4 = null_t,
246 class T5 = null_t, class T6 = null_t,
247 class T7 = null_t, class T8 = null_t>
249{
250 static void test (int line,
251 const char* t1 , const char* t2 = 0,
252 const char* t3 = 0, const char* t4 = 0,
253 const char* t5 = 0, const char* t6 = 0,
254 const char* t7 = 0, const char* t8 = 0)
255 {
256 const char* arr[] = {
257 t1, t2, t3, t4, t5, t6, t7, t8
258 };
259
260 char* pbuf = 0;
261 size_t bufsz = 0;
262
263 // get the list of template arguments in one buffer
264 rw_asnprintf(&pbuf, &bufsz, "%zu", Len);
265 for (size_t i = 0; i < sizeof (arr) / sizeof (*arr); ++i)
266 {
267 if (!arr [i])
268 break;
269
270 rw_asnprintf (&pbuf, &bufsz, "%{+}, %s", arr [i]);
271 }
272
273 typedef std::aligned_union<Len,T1,T2,T3,T4,T5,T6,T7,T8> aligned_t;
274 typedef typename aligned_t::type aligned_type_t;
275
276 const bool pass1 = std::alignment_of<aligned_type_t>::value
277 == aligned_t::alignment_value;
278 rw_assert (pass1, 0, line,
279 "std::aligned_union<%s>::alignment_value is %zu; "
280 "expected %zu",
281 pbuf, aligned_t::alignment_value,
282 std::alignment_of<aligned_type_t>::value);
283
284 const size_t exp_al = max8(std::alignment_of<T1>::value,
285 std::alignment_of<T2>::value,
286 std::alignment_of<T3>::value,
287 std::alignment_of<T4>::value,
288 std::alignment_of<T5>::value,
289 std::alignment_of<T6>::value,
290 std::alignment_of<T7>::value,
291 std::alignment_of<T8>::value);
292 const size_t got_al = std::alignment_of<aligned_type_t>::value;
293
294 const bool pass2 = exp_al == got_al;
295 rw_assert (pass2, 0, line,
296 "std::aligned_union<%s>::type alignment is %zu; "
297 "expected %zu",
298 pbuf, got_al, exp_al);
299
300 const size_t min_sz = Len;
301 const size_t got_sz = sizeof (aligned_type_t);
302
303 const bool pass3 = min_sz <= got_sz;
304
305 rw_assert (pass3, 0, __LINE__,
306 "std::aligned_union<%s>::type size is %zu; expected "
307 "at least %zu",
308 pbuf, got_sz, min_sz);
309
310 free (pbuf);
311 }
312};
313
314struct struct_t { };
315
316#endif // !_RWSTD_NO_ALIGN_TRAITS
317
318
319static void test_aligned_union ()
320{
321#ifdef _RWSTD_NO_ALIGN_TRAITS
322
323 rw_warn (0, 0, __LINE__,
324 "test_aligned_union disabled because "
325 "_RWSTD_NO_ALIGN_TRAITS is defined");
326
327#else
328
329#define TEST(Len,T1) \
330 aligned_union_tester<Len,T1>::test(__LINE__,#T1)
331
332 TEST (1, char);
333 TEST (1, long);
334 TEST (1, void*);
335 TEST (1, void (struct_t::*)());
336
337 TEST (2, char);
338 TEST (2, long);
339 TEST (2, void*);
340 TEST (2, void (struct_t::*)());
341
342 TEST (12, char);
343 TEST (12, long);
344 TEST (12, void*);
345 TEST (12, void (struct_t::*)());
346
347#undef TEST
348#define TEST(Len,T1,T2) \
349 aligned_union_tester<Len,T1,T2>::test(__LINE__,#T1,#T2)
350
351 TEST (11, char, long);
352 TEST (134, long, long);
353 TEST (7, void*, long);
354 TEST (1, void (struct_t::*)(), long);
355
356 TEST (2, char, long);
357 TEST (2, long, long);
358 TEST (2, void*, long);
359 TEST (2, void (struct_t::*)(), long);
360
361#undef TEST
362#define TEST(Len,T1,T2,T3,T4,T5) \
363 aligned_union_tester<Len,T1,T2,T3,T4,T5>::test(__LINE__,#T1,#T2,#T3,#T4,#T5)
364
365 TEST (12, char, short, int, long, void*);
366 TEST (13, void*, long, long, long, int);
367 TEST (17, void (struct_t::*)(), long, int, void*, char);
368
369#undef TEST
370
371#endif // _RWSTD_NO_ALIGN_TRAITS
372}
373
374
376static void test_decay ()
377{
378#define TEST(Trait,TypeT,TypeU) \
379 test_trait(__LINE__, #Trait, #TypeT, #TypeU, \
380 std::is_same<Trait<TypeT>::type, TypeU>::value)
381
382 // equal to remove_extent<remove_reference<T>::type>::type* for arrays
383 TEST (std::decay, int[ ], int*);
384 TEST (std::decay, int[2], int*);
385 TEST (std::decay, int[2][2], int (*)[2]);
386
387 // equal to add_pointer<remove_reference<U>::type>::type for functions
388 TEST (std::decay, int(), int (*)());
389 TEST (std::decay, int(char, long), int (*)(char, long));
390
391 TEST (std::decay, int(&)(), int (*)());
392 TEST (std::decay, int(&)(char, long), int (*)(char, long));
393
394 // otherwise equal to remove_cv<remove_reference<U>::type>::type
395 TEST (std::decay, int, int);
396 TEST (std::decay, const int, int);
397 TEST (std::decay, volatile int, int);
398 TEST (std::decay, const volatile int, int);
399
400 TEST (std::decay, int&, int);
401 TEST (std::decay, const int&, int);
402 TEST (std::decay, volatile int&, int);
403 TEST (std::decay, const volatile int&, int);
404
405#undef TEST
406}
407
408
410enum enum_t { E_a = 1 };
411
412static void test_enable_if ()
413{
414 typedef std::enable_if<true, int>::type int_type;
415
416#define TEST(Cond,Expect) \
417 test_enable_if(__LINE__, #Cond, Cond, Expect)
418
419 TEST (enabled_if_char< char>(), 1);
420 TEST (enabled_if_char< signed char>(), 0);
421 TEST (enabled_if_char<unsigned char>(), 0);
422
423 TEST (enabled_if_char< short>(), 0);
424 TEST (enabled_if_char< signed short>(), 0);
425 TEST (enabled_if_char<unsigned short>(), 0);
426
427 TEST (enabled_if_char< int>(), 0);
428 TEST (enabled_if_char< signed int>(), 0);
429 TEST (enabled_if_char<unsigned int>(), 0);
430
431 TEST (enabled_if_char< long>(), 0);
432 TEST (enabled_if_char< signed long>(), 0);
433 TEST (enabled_if_char<unsigned long>(), 0);
434
435 // miscellaneous other stuff to try and expose problems
436 TEST (enabled_if_char<char ()>(), 0);
437 TEST (enabled_if_char<char (*)()>(), 0);
438 TEST (enabled_if_char<char (&)()>(), 0);
439
440 TEST (enabled_if_char<char [1]>(), 0);
441 TEST (enabled_if_char<char (*)[1]>(), 0);
442 TEST (enabled_if_char<char (&)[1]>(), 0);
443
444 TEST (enabled_if_char<enum_t>(), 0);
445
446#undef TEST
447}
448
449
451static void test_conditional ()
452{
453#define TEST(Cond,Expect) \
454 test_enable_if(__LINE__, #Cond, Cond, Expect)
455
456 TEST (cond_if_char<void>(), 0);
457 TEST (cond_if_char<char>(), 1);
458
459#undef TEST
460#define TEST(Trait,Select,TypeT,TypeU,TypeV) \
461 test_trait(__LINE__, Select, #Trait, #TypeT, #TypeU, \
462 std::is_same<Trait<Select,TypeT,TypeU>::type, TypeV>::value)
463
464 TEST (std::conditional, true, char, long, char);
465 TEST (std::conditional, false, char, long, long);
466
467#undef TEST
468}
469
470
472static int run_test (int, char*[])
473{
475 test_aligned_union ();
476 test_decay ();
478 test_conditional ();
479
480 return 0;
481}
482
483
485#else // _RWSTD_NO_EXT_CXX_0X
486
487
489static int run_test (int, char*[])
490{
491 rw_warn (0, 0, __LINE__,
492 "test disabled because _RWSTD_NO_EXT_CXX_0X is defined");
493 return 0;
494}
495
496#endif // !_RWSTD_NO_EXT_CXX_0X
497
498
500int main (int argc, char *argv[])
501{
502 return rw_test (argc, argv, __FILE__,
503 "meta.trans.other",
504 0 /* no comment */,
505 run_test,
506 0);
507}
508
#define i
Definition 17.names.cpp:126
#define T2
Definition 17.names.cpp:323
#define line
Definition 17.names.cpp:490
#define r
Definition 17.names.cpp:134
#define t1
Definition 17.names.cpp:243
#define a2
Definition 17.names.cpp:251
#define t2
Definition 17.names.cpp:269
#define a1
Definition 17.names.cpp:225
#define T1
Definition 17.names.cpp:296
enum_t
int cond_if_char()
void test_aligned_storage(int line, size_t exp_sz, size_t got_sz, size_t exp_al, size_t got_al)
int _cond_if_char(void *)
int enabled_if_char(typename std::enable_if< is_char< T >::val >::type *=0)
#define TEST(Size, Align)
void test_trait(int line, bool select, const char *trait, const char *typeT, const char *typeU, bool success)
void test_enable_if(int line, const char *typeT, int got, int exp)
size_t max8(size_t a1, size_t a2, size_t a3, size_t a4, size_t a5, size_t a6, size_t a7, size_t a8)
void run_test(const ForwardIterator &dummy, T *, Predicate *pred)
#define main
#define _RWSTD_SPECIALIZED_CLASS
_TEST_EXPORT int rw_test(int argc, char *argv[], const char *filename, const char *clause, const char *comment, int(*testfun)(int, char **), const char *optspec,...)
_TEST_EXPORT int rw_assert(int, const char *, int, const char *,...)
Definition driver.cpp:1630
_TEST_EXPORT int rw_warn(int, const char *, int, const char *,...)
Definition driver.cpp:1647
_TEST_EXPORT int rw_asnprintf(char **pbuf, _RWSTD_SIZE_T *pbufsize, const char *fmt,...)
static void test(int line, const char *t1, const char *t2=0, const char *t3=0, const char *t4=0, const char *t5=0, const char *t6=0, const char *t7=0, const char *t8=0)