Ne.app NeANT
The Ne.app NeANT User module of the NeANT distribution.
20.tuple.cnstr.cpp
Go to the documentation of this file.
1
29#include <rw_driver.h>
30
31// compile out all test code if extensions disabled
32#if !defined (_RWSTD_NO_EXT_CXX_0X) \
33 && !defined(_RWSTD_NO_RVALUE_REFERENCES)
34
35#include <climits> // for CHAR_MAX
36#include <cstdlib> // for rand
37#include <cstring> // for strcmp
38#include <tuple>
39#include <type_traits> // for decay
40
41#include <rw_valcmp.h> // for rw_fltcmp
42#include <rw_allocator.h> // for UserAlloc
43
44#include "20.tuple.h"
45
46
48// general test function and underlying abstractions
49
50template <class T, class U = T>
51bool equal (const T& x, const U& y)
52{
53 return x == y;
54}
55
56template <>
57bool equal (const float& x, const float& y)
58{
59 return 0 == rw_fltcmp (x, y);
60}
61
62template <>
63bool equal (const char* const& x, const char* const& y)
64{
65 return 0 == std::strcmp (x, y);
66}
67
68
69template <class T, class U>
70void assert (int line, unsigned index, const char* tuple_name,
71 const T& t, const U& u)
72{
73 const char* fmtT = FMT_SPEC (T);
74 const char* fmtU = FMT_SPEC (U);
75 rw_assert (equal (t, u), __FILE__, line,
76 "get<%d, %s> (); got %{@}, expected %{@}",
77 index, tuple_name, fmtT, t, fmtU, u);
78}
79
80void assert (int line, unsigned index, const char* tuple_name,
81 const UserDefined& t, const UserDefined& u)
82{
83 rw_assert (equal (t, u), __FILE__, line,
84 "get<%d, %s> (); got %p [%d], expected %p [%d]",
85 index, tuple_name, &t, t.value (), &u, u.value ());
86
88
89#undef CHECK
90#define CHECK(N) \
91 a = UserDefined::actual.N; e = UserDefined::expect.N; \
92 rw_assert (a == e, __FILE__, line, \
93 "UserDefined::" #N "; got %u, expected %u", a, e)
94
95 CHECK (dflt_ctor);
96 CHECK (copy_ctor);
97 CHECK (tmpl_ctor);
98 CHECK (move_ctor);
99 CHECK (copy_asgn);
100 CHECK (tmpl_asgn);
101 CHECK (move_asgn);
102}
103
104template <class T, class U>
105void assert (int line, unsigned index, const char* tuple_name,
106 const std::tuple<T>& t, const std::tuple<U>& u)
107{
108 const char* fmtT = FMT_SPEC (T);
109 const char* fmtU = FMT_SPEC (U);
110 rw_assert (equal (t, u), __FILE__, line,
111 "get<%d, %s> (); got %{@}, expected %{@}",
112 index, tuple_name,
113 fmtT, std::get<0> (t), fmtU, std::get<0> (u));
114}
115
116
117template <unsigned Index, class Tuple, class... Elements>
118/*static*/ void
119test_impl (int line, const Tuple& tuple, const Elements&... values);
120
121// terminating specialization
122template <unsigned Index, class Tuple>
123/*static*/ void
124test_impl (int, const Tuple&) {}
125
126// generic definition
127template <unsigned Index, class Tuple, class Element, class... Elements>
128/*static*/ void
129test_impl (int line, const Tuple& tuple,
130 const Element& value, const Elements&... values)
131{
132 // assume std::get() has been fully tested and works correctly
133 assert (line, Index, TYPE_NAME (Tuple),
134 std::get<Index> (tuple), value);
135
136 test_impl<Index+1> (line, tuple, values...);
137}
138
139template <class Tuple, class... Elements>
140/*static*/ void
141test (int line, const Tuple& tuple, const Elements&... values)
142{
143 test_impl<0> (line, tuple, values...);
144}
145
146
148static void
150{
151 rw_info (0, __FILE__, __LINE__, "default constructor");
152
153 std::tuple<> et; _RWSTD_UNUSED (et);
154 // TODO: enable this test after implementing empty space optimization
155 //rw_assert (sizeof (et) == 0, __FILE__, __LINE__,
156 //"sizeof (std::tuple<>); got %u, expected 0",
157 //sizeof (et));
158
159 std::tuple<int> it; _RWSTD_UNUSED (it);
160 std::tuple<const int> ct; _RWSTD_UNUSED (ct);
161 // ill-formed for tuples with element types containing references
162 std::tuple<long, const char*> pt; _RWSTD_UNUSED (pt);
163 std::tuple<std::tuple<int> > nt; _RWSTD_UNUSED (nt);
164 std::tuple<bool, char, int, double, void*, UserDefined> bt;
165 _RWSTD_UNUSED (bt);
166
168 std::tuple<UserDefined> ut; _RWSTD_UNUSED (ut);
169 rw_assert (1 == UserDefined::actual.dflt_ctor, __FILE__, __LINE__,
170 "std::tuple<UserDefined> ut; called %d default ctors, "
171 "expected 1", UserDefined::actual.dflt_ctor);
172}
173
174
176static void
177test_value_copy_ctor ()
178{
179 rw_info (0, __FILE__, __LINE__, "value copy constructor");
180
181 const int i = std::rand ();
182 std::tuple<int> it1 (i);
183 test (__LINE__, it1, i);
184
185 const std::tuple<int> it2 (i);
186 test (__LINE__, it2, i);
187
188 std::tuple<const int> ct (i);
189 test (__LINE__, ct, i);
190
191 int j = std::rand ();
192 const std::tuple<int&> rt (j);
193 test (__LINE__, rt, j);
194
195 std::tuple<std::tuple<int> > nt (it2);
196 //std::get<0> (it2) = std::rand (); // diliberately cause assertion
197 test (__LINE__, nt, it2);
198
199 const long l = std::rand ();
200 std::tuple<long, const char*> pt (l, "string");
201 test (__LINE__, pt, l, (const char*) "string");
202
203 const UserDefined ud (i);
205 std::tuple<UserDefined> ut (ud);
207 test (__LINE__, ut, ud);
208
209 const bool b = true; const char c = 'a';
210 const double d = 3.14159; void* const p = (void*) &i;
211 std::tuple<bool, char, int, double, void*, UserDefined>
212 bt (b, c, i, d, p, ud);
214 test (__LINE__, bt, b, c, i, d, p, ud);
215}
216
217
219static void
220test_value_move_ctor ()
221{
222 rw_info (0, __FILE__, __LINE__, "value move constructor");
223
224#define INTEGER_CONSTANT 256
225
226 std::tuple<int> it1 (INTEGER_CONSTANT);
227 test (__LINE__, it1, INTEGER_CONSTANT);
228 const int c = std::rand ();
229 int i = c; // move semantics can alter source value
230 std::tuple<int> it2 (i); // temporary source value
231 test (__LINE__, it2, c);
232
233 const std::tuple<int> it3 (INTEGER_CONSTANT);
234 test (__LINE__, it3, INTEGER_CONSTANT);
235 i = c;
236 const std::tuple<int> it4 (i);
237 test (__LINE__, it4, c);
238
239 std::tuple<const int> ct1 (INTEGER_CONSTANT);
240 test (__LINE__, ct1, INTEGER_CONSTANT);
241 i = c;
242 std::tuple<const int> ct2 (i);
243 test (__LINE__, ct2, c);
244
245 // ill-formed for tuples with element types containing references
246
247 std::tuple<std::tuple<int> > nt (it1);
248 test (__LINE__, nt, it1);
249
250 std::tuple<long, const char*> pt (123456789L, "string");
251 test (__LINE__, pt, 123456789L, (const char*) "string");
252
253 const UserDefined src (c);
254 UserDefined tmp (src);
256 std::tuple<UserDefined> ut (tmp);
258 test (__LINE__, ut, src);
259
261 std::tuple<bool, char, int, double, void*, UserDefined>
262 bt (true, 'a', INTEGER_CONSTANT, 3.14159, (void*) 0, tmp);
264 test (__LINE__, bt,
265 true, 'a', INTEGER_CONSTANT, 3.14159, (void*) 0, src);
266}
267
268
270static void
271test_homo_copy_ctor ()
272{
273 rw_info (0, __FILE__, __LINE__,
274 "copy constructor (homogenous tuples)");
275
276 std::tuple<> et1, et2 (et1);
277 _RWSTD_UNUSED (et2);
278
279 const int ci = std::rand ();
280 const std::tuple<int> it1 (ci);
281 std::tuple<int> it2 (it1);
282 test (__LINE__, it2, ci);
283
284 const std::tuple<const int>& ct1 = it1; // same as copy ctor
285 std::tuple<const int> ct2 (ct1);
286 test (__LINE__, ct2, ci);
287
288 int i = ci;
289 const std::tuple<int&> rt1 (i);
290 std::tuple<int&> rt2 (rt1);
291 test (__LINE__, rt2, ci);
292
293 const std::tuple<std::tuple<int> > nt1 (it1);
294 std::tuple<std::tuple<int> > nt2 (nt1);
295 test (__LINE__, nt2, it1);
296
297 const std::tuple<long, const char*> pt1 (1234567890L, "string");
298 std::tuple<long, const char*> pt2 (pt1);
299 test (__LINE__, pt2, 1234567890L, (const char*) "string");
300
301 UserDefined ud (ci);
302 const std::tuple<UserDefined> ut1 (ud);
304 std::tuple<UserDefined> ut2 (ut1);
306 test (__LINE__, ut2, ud);
307
308 const std::tuple<bool, char, int, double, void*, UserDefined>
309 bt1 (true, 'a', ci, 3.14159, (void* const) &i, ud);
310 ++UserDefined::expect.move_ctor; // moved ud to bt1
311 std::tuple<bool, char, int, double, void*, UserDefined> bt2 (bt1);
312 ++UserDefined::expect.copy_ctor; // copied to bt2
313 test (__LINE__, bt2, true, 'a', ci, 3.14159, (void* const) &i, ud);
314}
315
316
318static void
319test_homo_move_ctor ()
320{
321 rw_info (0, __FILE__, __LINE__,
322 "move constructor (homogenous tuples)");
323
324 std::tuple<> et (std::tuple<> ()); _RWSTD_UNUSED (et);
325
326 const int ci = std::rand ();
327
328 std::tuple<int> it1 (ci);
329 std::tuple<int> it2 (std::move (it1));
330 test (__LINE__, it2, ci);
331
332 std::tuple<const int> ct1 (ci);
333 std::tuple<const int> ct2 = std::move (ct1);
334 test (__LINE__, ct2, ci);
335
336 std::tuple<std::tuple<int> > nt1 (it1);
337 std::tuple<std::tuple<int> > nt2 = std::move (nt1);
338 test (__LINE__, nt2, it1);
339
340 std::tuple<long, const char*> pt1 (1234567890L, "string");
341 std::tuple<long, const char*> pt2 (std::move (pt1));
342 test (__LINE__, pt2, 1234567890L, (const char*) "string");
343
344 const UserDefined ud (ci);
345 std::tuple<UserDefined> ut1 (ud);
347 std::tuple<UserDefined> ut2 (std::move (ut1));
349 test (__LINE__, ut2, ud);
350
351 std::tuple<bool, char, int, double, void*, UserDefined>
352 bt1 (true, 'a', ci, 3.14159, (void*) &ci, ud);
354 std::tuple<bool, char, int, double, void*, UserDefined>
355 bt2 (std::move (bt1));
357 test (__LINE__, bt2, true, 'a', ci, 3.14159, (void*) &ci, ud);
358}
359
360
362static void
363test_homo_copy_assign ()
364{
365 rw_info (0, __FILE__, __LINE__,
366 "copy assignment operator (homogenous tuples)");
367
368 const std::tuple<> et1 = std::tuple<> ();
369 std::tuple<> et2;
370 et2 = et1;
371 _RWSTD_UNUSED (et2);
372
373 int i = std::rand ();
374 const std::tuple<int> it1 (i);
375 std::tuple<int> it2;
376 it2 = it1;
377 test (__LINE__, it2, i);
378
379 // copy assignment ill-formed for constant element types
380
381 const std::tuple<int&> rt1 (i);
382 int j = -1; // outside range of rand()
383 std::tuple<int&> rt2 (j); // note, different reference
384 rt2 = rt1;
385 test (__LINE__, rt2, i);
386
387 std::tuple<std::tuple<int> > nt1 (it1);
388 std::tuple<std::tuple<int> > nt2;
389 nt2 = nt1;
390 test (__LINE__, nt2, it1);
391
392 const std::tuple<long, const char*> pt1 (long (i), "string");
393 std::tuple<long, const char*> pt2;
394 pt2 = pt1;
395 test (__LINE__, pt2, long (i), (const char*) "string");
396
397 const UserDefined ud (i);
398 const std::tuple<UserDefined> ut1 (ud);
399 std::tuple<UserDefined> ut2;
401 ut2 = ut1; ++UserDefined::expect.copy_asgn;
402 test (__LINE__, ut2, ud);
403
404 const std::tuple<bool, char, int, double, void*, UserDefined>
405 bt1 (true, 'a', i, 3.14159, (void* const) &i, ud);
407 std::tuple<bool, char, int, double, void*, UserDefined> bt2;
409 bt2 = bt1; ++UserDefined::expect.copy_asgn;
410 test (__LINE__, bt2, true, 'a', i, 3.14159, (void* const) &i, ud);
411}
412
413
415static void
416test_homo_move_assign ()
417{
418 rw_info (0, __FILE__, __LINE__,
419 "move assignment operator (homogenous tuples)");
420
421 std::tuple<> et1, et2;
422 et2 = std::move (et1);
423 _RWSTD_UNUSED (et2);
424
425 int i = std::rand ();
426
427 std::tuple<int> it1 (i);
428 std::tuple<int> it2;
429 it2 = std::move (it1);
430 test (__LINE__, it2, i);
431
432 // move assignment ill-formed for constant element types
433
434 std::tuple<std::tuple<int> > nt1 (it2);
435 std::tuple<std::tuple<int> > nt2;
436 nt2 = std::move (nt1);
437 test (__LINE__, nt2, it2);
438
439 std::tuple<long, const char*> pt1 (1234567890L, "string");
440 std::tuple<long, const char*> pt2;
441 pt2 = std::move (pt1);
442 test (__LINE__, pt2, 1234567890L, (const char*) "string");
443
444 const UserDefined ud (i);
445 std::tuple<UserDefined> ut1 (ud);
446 std::tuple<UserDefined> ut2;
448 ut2 = std::move (ut1); ++UserDefined::expect.move_asgn;
449 test (__LINE__, ut2, ud);
450
451 std::tuple<bool, char, int, double, void*, UserDefined>
452 bt1 (true, 'a', i, 3.14159, (void* const) &i, ud);
453 std::tuple<bool, char, int, double, void*, UserDefined> bt2;
455 bt2 = std::move (bt1); ++UserDefined::expect.move_asgn;
456 test (__LINE__, bt2, true, 'a', i, 3.14159, (void* const) &i, ud);
457}
458
459
461// heterogenous tests do not apply to empty tuples so no tests required
462
463#include <string>
464
465// need a string class with implicit conversion to type `const char*'
466struct String: public std::string
467{
468 String (): std::string () {}
469 String (const char* s): std::string (s) {}
470 operator const char* () const { return this->data (); }
471};
472
473
474static void
475test_hetero_copy_ctor ()
476{
477 rw_info (0, __FILE__, __LINE__,
478 "copy constructor (heterogenous tuples)");
479
480 int i = std::rand () % CHAR_MAX;
481
482 const std::tuple<char> cit (static_cast<char> (i));
483 std::tuple<int> it (cit);
484 test (__LINE__, it, i);
485
486 std::tuple<unsigned, String> cpt (12345U, "string");
487 std::tuple<long, const char*> pt (cpt);
488 test (__LINE__, pt, 12345U, (const char*) "string");
489
490 char s [] = "string"; const UserDefined ud (i);
491 const std::tuple<int, int, short, float, char*, UserDefined>
492 cbt (int (true), int ('a'), short (i), 3.14159f, s, ud);
494 std::tuple<bool, char, int, double, void*, UserDefined> bt (cbt);
496 test (__LINE__, bt, true, 'a', i, 3.14159f, s, ud);
497}
498
499
501static void
502test_hetero_move_ctor ()
503{
504 rw_info (0, __FILE__, __LINE__,
505 "move constructor (heterogenous tuples)");
506
507 int i = std::rand () % CHAR_MAX;
508
509 std::tuple<char> cit (static_cast<char> (i));
510 std::tuple<int> it (std::move (cit));
511 test (__LINE__, it, i);
512
513 std::tuple<unsigned, String> cpt (12345U, "string");
514 std::tuple<long, const char*> pt (std::move (cpt));
515 test (__LINE__, pt, 12345U, (const char*) "string");
516
517 char s [] = "string"; const UserDefined ud (i);
518 std::tuple<int, int, short, float, char*, UserDefined>
519 cbt (int (true), int ('a'), short (i), 3.14159f, s, ud);
521 std::tuple<bool, char, int, double, void*, UserDefined>
522 bt (std::move (cbt));
524 test (__LINE__, bt, true, 'a', i, 3.14159f, s, ud);
525}
526
527
529static void
530test_hetero_copy_assign ()
531{
532 rw_info (0, __FILE__, __LINE__,
533 "copy assignment operator (heterogenous tuples)");
534
535 int i = std::rand () % CHAR_MAX;
536
537 std::tuple<char> cit (static_cast<char> (i));
538 std::tuple<int> it;
539 it = cit;
540 test (__LINE__, it, i);
541
542 std::tuple<unsigned, String> cpt (12345U, "string");
543 std::tuple<long, const char*> pt;
544 pt = cpt;
545 test (__LINE__, pt, 12345U, (const char*) "string");
546
547 char s [] = "string"; const UserDefined ud (i);
548 std::tuple<int, int, short, float, char*, UserDefined>
549 cbt (int (true), int ('a'), short (i), 3.14159f, s, ud);
550 std::tuple<bool, char, int, double, void*, UserDefined> bt;
552 bt = cbt; ++UserDefined::expect.copy_asgn;
553 test (__LINE__, bt, true, 'a', i, 3.14159f, s, ud);
554}
555
556
558static void
559test_hetero_move_assign ()
560{
561 rw_info (0, __FILE__, __LINE__,
562 "move assignment operator (heterogenous tuples)");
563
564 int i = std::rand () % CHAR_MAX;
565
566 std::tuple<char> cit (i);
567 std::tuple<int> it;
568 it = std::move (cit);
569 test (__LINE__, it, i);
570
571 std::tuple<unsigned, String> cpt (12345U, "string");
572 std::tuple<long, const char*> pt;
573 pt = std::move (cpt);
574 test (__LINE__, pt, 12345U, (const char*) "string");
575
576 char s [] = "string"; const UserDefined ud (i);
577 std::tuple<int, int, short, float, char*, UserDefined>
578 cbt (int (true), int ('a'), short (i), 3.14159f, s, ud);
579 std::tuple<bool, char, int, double, void*, UserDefined> bt;
582 bt = std::move (cbt); ++UserDefined::expect.move_asgn;
583 test (__LINE__, bt, true, 'a', i, 3.14159f, s, ud);
584}
585
586
588static void
589test_alloc_ctors ()
590{
591 rw_info (0, __FILE__, __LINE__,
592 "user-defined allocator constructors");
593
594}
595
596
598static int
599run_test (int /*argc*/, char* /*argv*/ [])
600{
602
603 test_value_copy_ctor ();
604 test_value_move_ctor ();
605
606 test_homo_copy_ctor ();
607 test_homo_move_ctor ();
608 test_homo_copy_assign ();
609 test_homo_move_assign ();
610
611 test_hetero_copy_ctor ();
612 test_hetero_move_ctor ();
613 test_hetero_copy_assign ();
614 test_hetero_move_assign ();
615
616 test_alloc_ctors ();
617
618 return 0;
619}
620
621#else // _RWSTD_NO_EXT_CXX_0X || _RWSTD_NO_RVALUE_REFERENCES
622
623static int
624run_test (int, char*[])
625{
626#if defined (_RWSTD_NO_EXT_CXX_OX)
627
628 rw_warn (0, 0, __LINE__,
629 "test disabled because _RWSTD_NO_EXT_CXX_0X is defined");
630
631#elif defined (_RWSTD_NO_RVALUE_REFERENCES)
632
633 rw_warn (0, 0, __LINE__,
634 "test disabled because _RWSTD_NO_RVALUE_REFERENCES is "
635 "defined");
636
637#endif
638
639 return 0;
640}
641
642#endif // _RWSTD_NO_EXT_CXX_0X || _RWSTD_NO_RVALUE_REFERENCES
643
644/*extern*/ int
645main (int argc, char* argv [])
646{
647 return rw_test (argc, argv, __FILE__,
648 "[tuple.cnstr]", "20.3.1.2 Construction",
649 run_test, "", 0);
650}
651
#define i
Definition 17.names.cpp:126
#define T
Definition 17.names.cpp:163
#define y
Definition 17.names.cpp:141
#define t
Definition 17.names.cpp:136
#define u
Definition 17.names.cpp:137
#define d
Definition 17.names.cpp:115
#define cpt
Definition 17.names.cpp:460
#define e
Definition 17.names.cpp:118
#define line
Definition 17.names.cpp:490
#define x
Definition 17.names.cpp:140
#define index
Definition 17.names.cpp:482
#define a
Definition 17.names.cpp:109
#define j
Definition 17.names.cpp:127
#define c
Definition 17.names.cpp:111
#define b
Definition 17.names.cpp:110
#define tmp
Definition 17.names.cpp:553
#define s
#define p
Definition 17.names.cpp:132
#define U
Definition 17.names.cpp:164
#define CHECK(N)
void test_impl(int line, const Tuple &tuple, const Elements &... values)
bool equal(const T &x, const U &y)
#define INTEGER_CONSTANT
std::tuple< bool, char, int, double, void *, UserDefined > Tuple
#define FMT_SPEC(T, S)
Definition 20.tuple.h:201
#define TYPE_NAME(T)
Definition 20.tuple.h:165
const char *const data[]
void test_default_ctor(std::bitset< N > *)
void run_test(const ForwardIterator &dummy, T *, Predicate *pred)
T value(const T &val)
#define main
#define assert(expr)
Definition _cassert.h:40
#define _RWSTD_UNUSED(arg)
Definition _defs.h:972
static count_type expect
Definition 20.tuple.h:144
static void reset()
Definition 20.tuple.h:125
unsigned size_type
Definition 20.tuple.h:50
static count_type actual
Definition 20.tuple.h:141
#define CHAR_MAX
Definition limits.h:44
Definition json.h:5363
_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_info(int, const char *, int, const char *,...)
Definition driver.cpp:1681
_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_fltcmp(float x, float y)
Definition valcmp.cpp:712
String(const char *s)