Ne.app NeANT
The Ne.app NeANT User module of the NeANT distribution.
23.list.cons.cpp
Go to the documentation of this file.
1
27#include <list> // for list
28#include <cstddef> // for size_t
29
30#include <rw_lists.h> // for ListMembers
31#include <rw_alg_test.h> // for InputIter
32#include <rw_driver.h> // for rw_test()
33#include <rw_allocator.h> // for UserAlloc
34#include <rw_new.h> // for bad_alloc, replacement operator new
35
36
38// for convenience and brevity
39#define Cons(sig) ListIds::ctor_ ## sig
40#define OpSet(sig) ListIds::op_set_ ## sig
41
42static const char* const exceptions[] = {
43 "unknown exception", "bad_alloc", "exception", "UserClass::CopyCtor"
44};
45
46
48// exercises:
49// list (void)
50// list (const allocator_type&)
51#define alloc_test_cases void_test_cases
52static const ContainerTestCase
53void_test_cases [] = {
54
55#undef TEST
56#define TEST(dummy) { \
57 __LINE__, -1, -1, -1, -1, -1, \
58 0, 0, dummy, sizeof dummy - 1, \
59 "", 0, 0 \
60 }
61
62 // +--------------------- dummy argument
63 // |
64 // V
65 TEST ("ab"),
66
67 TEST ("last test")
68};
69
70
72// exercises:
73// list (const list&)
74static const ContainerTestCase
75ccont_test_cases [] = {
76
77#undef TEST
78#define TEST(arg, res) { \
79 __LINE__, -1, -1, -1, -1, -1, \
80 0, 0, arg, sizeof arg - 1, \
81 res, sizeof res - 1, 0 \
82 }
83
84 // +----------------------------------------- source sequence
85 // | +------------------------- expected result sequence
86 // | |
87 // | |
88 // V V
89 TEST ("ab", "ab"),
90
91 TEST ("", ""),
92 TEST ("<U0>", "<U0>"),
93 TEST ("<U0>@2", "<U0>@2"),
94
95 TEST ("a", "a"),
96 TEST ("bcd", "bcd"),
97 TEST ("cdefaihjb", "cdefaihjb"),
98
99 TEST ("<U0>@2ab", "<U0>@2ab"),
100 TEST ("a<U0>@2b", "a<U0>@2b"),
101 TEST ("ab<U0>@2", "ab<U0>@2"),
102 TEST ("abefdcc<U0>a", "abefdcc<U0>a"),
103
104 TEST ("x@128", "x@128"),
105 TEST ("x@207", "x@207"),
106 TEST ("x@334", "x@334"),
107 TEST ("x@540", "x@540"),
108 TEST ("x@873", "x@873"),
109 TEST ("x@1412", "x@1412"),
110 TEST ("x@3695", "x@3695"),
111 TEST ("x@4096", "x@4096"),
112
113 TEST ("last test", "last test")
114};
115
116
118// exercises:
119// list (InputIterator, InputIterator)
120// list (InputIterator, InputIterator, const allocator&)
121#define range_alloc_test_cases range_test_cases
122static const ContainerTestCase
123range_test_cases [] = {
124
125#undef TEST
126#define TEST(arg, off, size, res, bthrow) { \
127 __LINE__, -1, -1, off, size, -1, \
128 0, 0, arg, sizeof arg - 1, \
129 res, sizeof res - 1, bthrow \
130 }
131
132 // +----------------------------------------- source sequence
133 // | +------------------------- ctor off argument
134 // | | +--------------------- ctor n argument
135 // | | | +---------------- expected result sequence
136 // | | | | +--- exception info
137 // | | | | | 0 - no exception
138 // | | | | | 1 - out_of_range
139 // | | | | |
140 // | | | | |
141 // V V V V V
142 TEST ("ab", 0, 2, "ab", 0),
143
144 TEST ("", 0, 0, "", 0),
145 TEST ("<U0>", 0, 1, "<U0>", 0),
146 TEST ("<U0>@2", 0, 2, "<U0>@2", 0),
147
148 TEST ("a", 0, 1, "a", 0),
149 TEST ("bcd", 0, 3, "bcd", 0),
150 TEST ("cdefaihjb", 0, 9, "cdefaihjb", 0),
151
152 TEST ("<U0>@2ab", 0, 4, "<U0>@2ab", 0),
153 TEST ("a<U0>@2b", 0, 4, "a<U0>@2b", 0),
154 TEST ("ab<U0>@2", 0, 4, "ab<U0>@2", 0),
155 TEST ("abefdcc<U0>a", 0, 9, "abefdcc<U0>a", 0),
156
157 TEST ("x@207", 0, 207, "x@207", 0),
158 TEST ("x@334", 10, 207, "x@207", 0),
159 TEST ("x@207", 50, 128, "x@128", 0),
160 TEST ("x@1412", 128, 873, "x@873", 0),
161 TEST ("x@1412", 0, 1412, "x@1412", 0),
162 TEST ("x@1412", 207, 540, "x@540", 0),
163 TEST ("x@874", 1, 873, "x@873", 0),
164 TEST ("x@3695", 10, 2284, "x@2284", 0),
165 TEST ("x@4096", 0, 4096, "x@4096", 0),
166
167 TEST ("last test", 0, 9, "last test", 0)
168};
169
170
172// exercises:
173// list (size_type)
174static const ContainerTestCase
175size_test_cases [] = {
176
177#undef TEST
178#define TEST(size, res) { \
179 __LINE__, -1, size, -1, -1, 0, \
180 0, 0, 0, 0, \
181 res, sizeof res - 1, 0 \
182 }
183
184 // +---------------------------------------- ctor n argument
185 // | +------------------------------ expected result sequence
186 // | |
187 // | |
188 // V V
189 TEST (1, "<U0>"),
190 TEST (2, "<U0>@2"),
191 TEST (5, "<U0>@5"),
192 TEST (10, "<U0>@10"),
193 TEST (128, "<U0>@128"),
194 TEST (207, "<U0>@207"),
195 TEST (540, "<U0>@540"),
196 TEST (873, "<U0>@873"),
197 TEST (1412, "<U0>@1412"),
198 TEST (3695, "<U0>@3695"),
199 TEST (4096, "<U0>@4096")
200};
201
202
204// exercises:
205// list (size_type, const value_type&)
206// list (size_type, const value_type&, const allocator_type&)
207#define size_cref_alloc_test_cases size_cref_test_cases
208static const ContainerTestCase
209size_cref_test_cases [] = {
210
211#undef TEST
212#define TEST(size, val, res) { \
213 __LINE__, -1, size, -1, -1, val, \
214 0, 0, 0, 0, \
215 res, sizeof res - 1, 0 \
216}
217
218 // +---------------------------------------- ctor n argument
219 // | +----------------------------- source value
220 // | | +------------------------ expected result sequence
221 // | | |
222 // | | |
223 // V V V
224 TEST (1, 'a', "a"),
225 TEST (1, '\0', "<U0>"),
226
227 TEST (2, 'a', "aa"),
228 TEST (2, '\0', "<U0>@2"),
229
230 TEST (5, '\0', "<U0>@5"),
231 TEST (10, 'a', "aaaaaaaaaa"),
232
233 TEST (128, 'x', "x@128"),
234 TEST (207, 'x', "x@207"),
235 TEST (540, 'x', "x@540"),
236 TEST (873, 'x', "x@873"),
237 TEST (1412, 'x', "x@1412"),
238 TEST (3695, 'x', "x@3695"),
239
240 TEST (4096, 'x', "x@4096"),
241
242 TEST (4, 't', "tttt")
243};
244
245
246// exercises:
247// operator= (const list&)
248static const ContainerTestCase
249ccont_op_set_test_cases [] = {
250
251#undef TEST
252#define TEST(str, arg, res, bthrow) { \
253 __LINE__, -1, -1, -1, -1, -1, \
254 str, sizeof str - 1, arg, sizeof arg - 1, \
255 res, sizeof res - 1, bthrow \
256}
257
258 // +----------------------------------------- source sequence
259 // | +------------------------------ argument sequence
260 // | | +--------------- expected result sequence
261 // | | | +- exception info
262 // | | | | 0 - no exception
263 // | | | | -1 - excpetion safety
264 // | | | |
265 // | | | |
266 // V V V V
267 TEST ("", "ab", "ab", 0),
268
269 TEST ("", "", "", 0),
270 TEST ("abc", "", "", 0),
271 TEST ("", "<U0>", "<U0>", 0),
272 TEST ("abc", "<U0>", "<U0>", 0),
273
274 TEST ("", "a", "a", 0),
275 TEST ("<U0>@2", "a", "a", 0),
276 TEST ("a", "bcd", "bcd", 0),
277 TEST ("x@4096", "bcd", "bcd", 0),
278 TEST ("", "cdefaihjb", "cdefaihjb", 0),
279 TEST ("a<U0>b", "cdefaihjb", "cdefaihjb", 0),
280
281 TEST ("", "<U0>@2ab", "<U0>@2ab", 0),
282 TEST ("c<U0>d", "<U0>@2ab", "<U0>@2ab", 0),
283 TEST ("", "a<U0>@2b", "a<U0>@2b", 0),
284 TEST ("bcd", "a<U0>@2b", "a<U0>@2b", 0),
285 TEST ("<U0>", "ab<U0>@2", "ab<U0>@2", 0),
286 TEST ("x@4096", "ab<U0>@2", "ab<U0>@2", 0),
287 TEST ("<U0>a", "abefdcc<U0>a", "abefdcc<U0>a", 0),
288 TEST ("x@4096", "abefdcc<U0>a", "abefdcc<U0>a", 0),
289
290 TEST ("", "x@207", "x@207", 0),
291 TEST ("x@128", "x@207", "x@207", 0),
292 TEST ("x@540", "x@207", "x@207", 0),
293 TEST ("", "x@1412", "x@1412", 0),
294 TEST ("x@128", "x@1412", "x@1412", 0),
295 TEST ("x@3695", "x@1412", "x@1412", 0),
296 TEST ("x@872", "x@873", "x@873", 0),
297 TEST ("x@873", "x@3695", "x@3695", 0),
298
299 TEST ("abc", "x@4096", "x@4096", 0),
300
301 TEST ("", 0, "", 0),
302 TEST ("a<U0>b<U0>", 0, "a<U0>b<U0>", 0),
303 TEST ("x@4096", 0, "x@4096", 0),
304
305 TEST ("", "last test", "last test", 0)
306};
307
308
310// invokes specializations of the member function template
311// on the required iterator categories
312template <class List, class Iterator>
314
315 typedef typename List::value_type ListVal;
316 typedef typename List::allocator_type ListAlloc;
317
319
320 virtual List&
321 operator() (List&, const ContainerTestCaseData<ListVal>& tdata) const {
322
323 const ListVal* const beg = tdata.arg_ + tdata.off2_;
324 const ListVal* const end = beg + tdata.ext2_;
325
326 const Iterator first (beg, beg, end);
327 const Iterator last (end, beg, end);
328
329 if (Cons (range_alloc) == tdata.func_.which_) {
331 List* tmp = new List (first, last, alloc);
332 return *tmp;
333 }
334
335 List* tmp = new List (first, last);
336 return *tmp;
337 }
338};
339
340
342// invokes specializations of the member function template
343// on the required iterator categories
344template <class List, class Iterator>
346
347 typedef typename List::value_type ListVal;
348 typedef typename List::allocator_type ListAlloc;
349
351
352 virtual List&
353 operator() (List&, const ContainerTestCaseData<ListVal>& tdata) const {
354
355 const ListVal* const beg = tdata.arg_ + tdata.off2_;
356 const ListVal* const end = beg + tdata.ext2_;
357
358 const Iterator first = _RWSTD_CONST_CAST (Iterator, beg);
360
361 if (Cons (range_alloc) == tdata.func_.which_) {
363 List* tmp = new List (first, last, alloc);
364 return *tmp;
365 }
366
367 List* tmp = new List (first, last);
368 return *tmp;
369 }
370};
371
372
374template <class InputIterator, class Distance>
375inline void
377
378 while (0 < dist) {
379 --dist;
380 ++it;
381 }
382}
383
384// invokes possible overloads of the member function template
385// on common RandomAccessIterator types
386template <class List, class Iterator>
388{
389 //typedef typename List::iterator ListIter;
390 typedef typename List::value_type ListVal;
391 typedef typename List::allocator_type ListAlloc;
392
394
395 virtual List&
396 operator() (List& list_arg,
397 const ContainerTestCaseData<ListVal>& tdata) const {
398
399 bool reverse_iter =
402
403 const std::size_t off = reverse_iter ?
404 tdata.arglen_ - tdata.off2_ - tdata.ext2_ : tdata.off2_;
405 const std::size_t ext = tdata.ext2_;
406
407 Iterator first (this->begin (list_arg, (Iterator*)0));
408 _rw_advance (first, off);
409
410 Iterator last (first);
411 _rw_advance (last, ext);
412
413 if (Cons (range_alloc) == tdata.func_.which_) {
415 List* tmp = new List (first, last, alloc);
416 return *tmp;
417 }
418
419 List* tmp = new List (first, last);
420 return *tmp;
421 }
422};
423
424
426template <class T, class Allocator>
428 std::list <T, Allocator> > &rng,
429 const ContainerTestCaseData<T> &tdata)
430{
431 typedef std::list <T, Allocator> List;
432 typedef typename List::iterator ListIter;
433 typedef typename List::const_iterator ListCIter;
434
435 const ContainerFunc &func = tdata.func_;
436 const ContainerTestCase &tcase = tdata.tcase_;
437
438 // construct the argument list
439 /* const */ List arg (tdata.arg_, tdata.arg_ + tdata.arglen_);
440
441 // list function argument
442 const List& arg_list = arg;
443 const T arg_val = T::from_char (char (tcase.val));
444 const Allocator arg_alc;
445
446 // have UserClass copy ctor throw an exception during
447 // the copying of the last value
450
451 // (name of) expected and caught exception
452 const char* expected = 0;
453 const char* caught = 0;
454
455#ifndef _RWSTD_NO_EXCEPTIONS
456
457 if (0 == tcase.bthrow) {
458 // by default exercise the exception safety of the
459 // function by iteratively inducing an exception at
460 // each call to UserClass::UserClass(const UserClass&)
461 // until the call succeeds
462 expected = exceptions [3]; // UserClass::CopyCtor
463 }
464 else {
465 // exceptions disabled for this test case
466 }
467
468#else // if defined (_RWSTD_NO_EXCEPTIONS)
469
470 if (tcase.bthrow) {
471 return;
472 }
473
474#endif // _RWSTD_NO_EXCEPTIONS
475
476
477 // pointer to the returned reference
478 List* ret_ptr = 0;
479
480 // start checking for memory leaks
481 rwt_check_leaks (0, 0);
482
483 const bool is_class = ListIds::UserClass == func.elem_id_;
484
485 const std::size_t x_count_save = UserClass::count_;
486 const std::size_t arg_count = std::size_t (tcase.size);
487
488 try {
491
492 // reset function call counters
493 if (is_class)
495
496 switch (which) {
497
498 case Cons (void):
499 ret_ptr = new List ();
500 break;
501
502 case Cons (alloc):
503 ret_ptr = new List (arg_alc);
504 break;
505
506 case Cons (ccont):
507 ret_ptr = new List (arg_list);
508 break;
509
510 case Cons (size):
511 ret_ptr = new List (arg_count);
512 break;
513
514 case Cons (size_cref):
515 ret_ptr = new List (arg_count, arg_val);
516 break;
517
518 case Cons (size_cref_alloc):
519 ret_ptr = new List (arg_count, arg_val, arg_alc);
520 break;
521
522 case Cons (range):
523 ret_ptr = &rng (arg, tdata);
524 break;
525
526 case Cons (range_alloc):
527 ret_ptr = &rng (arg, tdata);
528 break;
529
530 default:
531 RW_ASSERT (!"logic error: unknown constructor overload");
532 }
533
534 // for convenience
535 static const int cwidth = sizeof (T);
536
537 // verify that returned pointer is valid
538 rw_assert (0 != ret_ptr, 0, tcase.line,
539 "line %d. %{$FUNCALL} expected \"%{X=*}\", got null",
540 __LINE__, cwidth, int (tdata.reslen_), tdata.res_);
541
542 if (0 != ret_ptr) {
543
544 if (is_class) {
545
546 std::size_t def_ctor = (Cons (size) == which);
547
548 // verify that the list ctor calls only copy ctor
549 // of UserClass and only the given number of times each
550 bool success = UserClass::is_total (std::size_t (-1),
551 def_ctor,
552 tdata.reslen_,
553 0, 0, 0);
554 rw_assert (success, 0, tcase.line,
555 "line %d. %{$FUNCALL} called default/copy ctor "
556 "and operator=() %zu, %zu, and %zu times, "
557 "respectively, %zu, %zu, 0 expected",
558 __LINE__,
562 def_ctor, tdata.reslen_);
563 }
564
565 const std::size_t got_size = ret_ptr->size ();
566 char* const got = new char [got_size + 1];
567
568 std::size_t index = 0;
569 for (ListCIter it = ret_ptr->begin (),
570 end = ret_ptr->end (); it != end; ++it) {
571 got [index++] = char (it->data_.val_);
572 }
573
574 got [got_size] = '\0';
575
576 // verify that the length of the resulting list
577 rw_assert (tdata.reslen_ == got_size, 0, tcase.line,
578 "line %d. %{$FUNCALL} expected \"%{X=*}\" with "
579 "length %zu, got %{/*.*Gs} with length %zu",
580 __LINE__,
581 cwidth, int (tdata.reslen_), tdata.res_,
582 tdata.reslen_,
583 1, int (got_size), got, got_size);
584
585 if (tdata.reslen_ == got_size) {
586 // if the result length matches the expected length
587 // (and only then), also verify that the modified
588 // list matches the expected result
589 const std::size_t match =
590 rw_match (tcase.res, got, got_size);
591
592 rw_assert (match == tdata.reslen_, 0, tcase.line,
593 "line %d. %{$FUNCALL} expected \"%{X=*}\", got "
594 "%{/*.*Gs}, difference at offset %zu",
595 __LINE__,
596 cwidth, int (tdata.reslen_), tdata.res_,
597 1, int (got_size), got, match);
598 }
599
600 delete [] got;
601
602 delete ret_ptr;
603 }
604 }
605
606#ifndef _RWSTD_NO_EXCEPTIONS
607
608 catch (const UserClass::CopyCtor &ex) {
609 caught = exceptions [3];
610 rw_assert (0 == tcase.bthrow, 0, tcase.line,
611 "line %d. %{$FUNCALL} %{?}expected %s,%{:}"
612 "unexpectedly%{;} caught %s (id_ = %d)",
613 __LINE__, 0 != expected, expected, caught,
614 ex.id_);
615 }
616 catch (const std::bad_alloc &ex) {
617 caught = exceptions [1];
618 rw_assert (0, 0, tcase.line,
619 "line %d. %{$FUNCALL} %{?}expected %s,%{:}"
620 "unexpectedly%{;} caught std::%s(%#s)",
621 __LINE__, 0 != expected, expected, caught,
622 ex.what ());
623 }
624 catch (const std::exception &ex) {
625 caught = exceptions [2];
626 rw_assert (0, 0, tcase.line,
627 "line %d. %{$FUNCALL} %{?}expected %s,%{:}"
628 "unexpectedly%{;} caught std::%s(%#s)",
629 __LINE__, 0 != expected, expected, caught,
630 ex.what ());
631 }
632 catch (...) {
633 caught = exceptions [0];
634 rw_assert (0, 0, tcase.line,
635 "line %d. %{$FUNCALL} %{?}expected %s,%{:}"
636 "unexpectedly%{;} caught %s",
637 __LINE__, 0 != expected, expected, caught);
638 }
639
640#endif // _RWSTD_NO_EXCEPTIONS
641
642 // disable UserClass::CopyCtor exception
643 if (!caught)
644 UserClass::copy_ctor_throw_count_ = std::size_t (-1);
645
646 /* const */ std::size_t nbytes;
647 const std::size_t nblocks = rwt_check_leaks (&nbytes, 0);
648
649 // FIXME: verify the number of blocks the function call
650 // is expected to allocate and detect any memory leaks
651 const std::size_t expect_blocks = nblocks;
652
653 rw_assert (nblocks == expect_blocks, 0, tcase.line,
654 "line %d. %{$FUNCALL} allocated %td bytes in %td blocks",
655 __LINE__, nbytes, expect_blocks);
656
657 if (is_class)
658 rw_assert (x_count_save == UserClass::count_, 0, tcase.line,
659 "line %d. %{$FUNCALL} leaked %zu value(s) "
660 "of %zu after %{?}an exception %s%{:}call%{;}",
661 __LINE__, UserClass::count_ - x_count_save,
662 tdata.reslen_, 0 != caught, caught);
663
664 if (caught) {
665 if (0 == tcase.bthrow) {
666 // allow this call to operator new to succeed and try
667 // to make the next one to fail during the next call
668 // to the same function again
669 continue;
670 }
671 }
672 else if (0 < tcase.bthrow) {
673 rw_assert (caught == expected, 0, tcase.line,
674 "line %d. %{$FUNCALL} %{?}expected %s, caught %s"
675 "%{:}unexpectedly caught %s%{;}",
676 __LINE__, 0 != expected, expected, caught, caught);
677 }
678
679 break;
680 }
681}
682
683
685template <class T, class Allocator>
687 const ContainerTestCaseData<T> &tdata)
688{
689 typedef std::list <T, Allocator> List;
690 typedef typename List::iterator ListIter;
691 typedef typename List::const_iterator ListCIter;
692
693 const ContainerFunc &func = tdata.func_;
694 const ContainerTestCase &tcase = tdata.tcase_;
695
696 // construct the list object to be modified
697 // and the (possibly unused) argument list
698 List lst (tdata.str_, tdata.str_ + tdata.strlen_, Allocator ());
699 const List arg (tdata.arg_, tdata.arg_ + tdata.arglen_, Allocator ());
700
701 // list function argument
702 const List& arg_list = tcase.arg ? arg : lst;
703
704 rwt_free_store* const pst = rwt_get_free_store (0);
705 SharedAlloc* const pal = SharedAlloc::instance ();
706
707 // iterate for`throw_after' starting at the next call to operator new,
708 // forcing each call to throw an exception, until the function finally
709 // succeeds (i.e, no exception is thrown)
710 std::size_t throw_count;
711 for (throw_count = 0; ; ++throw_count) {
712
713 // (name of) expected and caught exception
714 const char* expected = 0;
715 const char* caught = 0;
716
717#ifndef _RWSTD_NO_EXCEPTIONS
718
719 if (0 == tcase.bthrow) {
720 // by default exercise the exception safety of the
721 // function by iteratively inducing an exception at
722 // each call to operator new or Allocator::allocate()
723 // until the call succeeds
724 expected = exceptions [1]; // bad_alloc
725 *pst->throw_at_calls_ [0] =
726 pst->new_calls_ [0] + throw_count + 1;
727 pal->throw_at_calls_ [pal->m_allocate] =
728 pal->throw_at_calls_ [pal->m_allocate] + throw_count + 1;
729 }
730 else {
731 // exceptions disabled for this test case
732 }
733
734#else // if defined (_RWSTD_NO_EXCEPTIONS)
735
736 if (tcase.bthrow) {
737 return;
738 }
739
740#endif // _RWSTD_NO_EXCEPTIONS
741
742 // start checking for memory leaks
743 rw_check_leaks (lst.get_allocator ());
744
745 try {
746 const bool is_class = ListIds::UserClass == func.elem_id_;
747
748 // reset function call counters
749 if (is_class)
751
754
755 switch (which) {
756
757 case OpSet (ccont):
758 lst = arg_list;
759 break;
760
761 default:
762 RW_ASSERT (!"logic error: unknown operator= overload");
763 }
764
765 if (is_class && &lst != &arg_list) {
766
767 const std::size_t total_copy = UserClass::n_total_copy_ctor_ +
769
770 bool success = 0 == UserClass::n_total_def_ctor_
771 && total_copy == tdata.reslen_;
772
773 rw_assert (success, 0, tcase.line,
774 "line %d. %{$FUNCALL} called default ctor and "
775 "copy ctor + operator=() %zu, and %zu times, "
776 "respectively, 0, and %zu expected",
777 __LINE__,
779 total_copy, tdata.reslen_);
780 }
781
782 // for convenience
783 static const int cwidth = sizeof (T);
784
785 const std::size_t got_size = lst.size ();
786 char* const got = new char [got_size + 1];
787
788 std::size_t index = 0;
789 for (ListCIter it = lst.begin (),
790 end = lst.end (); it != end; ++it) {
791 got [index++] = char (it->data_.val_);
792 }
793
794 got [got_size] = '\0';
795
796 // verify that the length of the resulting list
797 rw_assert (tdata.reslen_ == got_size, 0, tcase.line,
798 "line %d. %{$FUNCALL} expected \"%{X=*}\" with "
799 "length %zu, got %{/*.*Gs} with length %zu",
800 __LINE__,
801 cwidth, int (tdata.reslen_), tdata.res_,
802 tdata.reslen_, 1, int (got_size), got, got_size);
803
804 if (tdata.reslen_ == got_size) {
805 // if the result length matches the expected length
806 // (and only then), also verify that the modified
807 // list matches the expected result
808 const std::size_t match =
809 rw_match (tcase.res, got, got_size);
810
811 rw_assert (match == tdata.reslen_, 0, tcase.line,
812 "line %d. %{$FUNCALL} expected \"%{X=*}\", "
813 "got %{/*.*Gs}, difference at offset %zu",
814 __LINE__, cwidth, int (tdata.reslen_),
815 tdata.res_, 1, int (got_size), got, match);
816 }
817
818 delete [] got;
819 }
820
821#ifndef _RWSTD_NO_EXCEPTIONS
822
823 catch (const std::bad_alloc &ex) {
824 caught = exceptions [1];
825 rw_assert (0 == tcase.bthrow, 0, tcase.line,
826 "line %d. %{$FUNCALL} %{?}expected %s,%{:}"
827 "unexpectedly%{;} caught std::%s(%#s)",
828 __LINE__, 0 != expected, expected, caught,
829 ex.what ());
830 }
831 catch (const std::exception &ex) {
832 caught = exceptions [2];
833 rw_assert (0, 0, tcase.line,
834 "line %d. %{$FUNCALL} %{?}expected %s,%{:}"
835 "unexpectedly%{;} caught std::%s(%#s)",
836 __LINE__, 0 != expected, expected, caught,
837 ex.what ());
838 }
839 catch (...) {
840 caught = exceptions [0];
841 rw_assert (0, 0, tcase.line,
842 "line %d. %{$FUNCALL} %{?}expected %s,%{:}"
843 "unexpectedly%{;} caught %s",
844 __LINE__, 0 != expected, expected, caught);
845 }
846
847#endif // _RWSTD_NO_EXCEPTIONS
848
849 // FIXME: verify the number of blocks the function call
850 // is expected to allocate and detect any memory leaks
851 rw_check_leaks (lst.get_allocator (), tcase.line,
852 std::size_t (-1), std::size_t (-1));
853
854 if (caught) {
855 if (0 == tcase.bthrow) {
856 // allow this call to operator new to succeed and try
857 // to make the next one to fail during the next call
858 // to the same function again
859 continue;
860 }
861 }
862 else if (0 < tcase.bthrow) {
863 rw_assert (caught == expected, 0, tcase.line,
864 "line %d. %{$FUNCALL} %{?}expected %s, caught %s"
865 "%{:}unexpectedly caught %s%{;}",
866 __LINE__, 0 != expected, expected, caught, caught);
867 }
868
869 break;
870 }
871
872 // disable bad_alloc exceptions
873 *pst->throw_at_calls_ [0] = 0;
874 pal->throw_at_calls_ [pal->m_allocate] = 0;
875}
876
877
879template <class T, class Allocator>
881 const ContainerTestCaseData<T> &tdata)
882{
883 typedef std::list<T, Allocator> List;
884
886 test_op_set ((T*)0, (Allocator*)0, tdata);
887 return;
888 }
889
890 if (tdata.func_.which_ == Cons (range)
891 || tdata.func_.which_ == Cons (range_alloc)) {
892
893 switch (tdata.func_.iter_id_) {
894
895 // exercise specializations of the member function template
896 // on the required iterator categories
897
898#undef TEST
899#define TEST(Iterator) do { \
900 typedef Iterator<T> Iter; \
901 static const \
902 ConsRange<List, Iter> rng; \
903 test_cons ((T*)0, (Allocator*)0, rng, tdata); \
904} while (0)
905
906 case ContainerIds::Input: TEST (InputIter); break;
910
911 // exercise possible overloads of the member function template
912 // on pointer and const_pointer types
913#undef TEST
914#define TEST(Iterator) do { \
915 typedef typename List::Iterator Iter; \
916 static const \
917 ConsRangePtrOverload<List, Iter> rng; \
918 test_cons ((T*)0, (Allocator*)0, rng, tdata); \
919} while (0)
920
921 case ContainerIds::Pointer: TEST (pointer); break;
922 case ContainerIds::ConstPointer: TEST (const_pointer); break;
923
924 // exercise possible overloads of the member function template
925 // on common RandomAccessIterator types except
926 // pointer and const_pointer types
927#undef TEST
928#define TEST(Iterator) do { \
929 typedef typename List::Iterator Iter; \
930 static const \
931 ConsRangeOverload<List, Iter> rng; \
932 test_cons ((T*)0, (Allocator*)0, rng, tdata); \
933} while (0)
934
935 case ContainerIds::Iterator: TEST (iterator); break;
936 case ContainerIds::ConstIterator: TEST (const_iterator); break;
937
939 TEST (reverse_iterator);
940 break;
942 TEST (const_reverse_iterator);
943 break;
944
945 default:
946 rw_error (0, 0, __LINE__, "bad iterator id");
947 }
948 }
949 else {
950 // exercise ordinary overloads of the member function
951 static const ContRangeBase<List> rng;
952 test_cons ((T*)0, (Allocator*)0, rng, tdata);
953 }
954}
955
956
959
960int main (int argc, char** argv)
961{
962 std::list<int> lst;
963
964 static const ContainerTest
965 tests [] = {
966
967#undef TEST
968#define TEST(sig) { \
969 Cons (sig), sig ## _test_cases, \
970 sizeof sig ## _test_cases / sizeof *sig ## _test_cases \
971 }
972
973 TEST (void),
974 TEST (alloc),
975 TEST (ccont),
976 TEST (size),
977 TEST (size_cref),
978 TEST (size_cref_alloc),
979 TEST (range),
980 TEST (range_alloc),
981
982#undef TEST
983#define TEST(sig) { \
984 OpSet (sig), sig ## _op_set_test_cases, \
985 sizeof sig ## _op_set_test_cases \
986 / sizeof *sig ## _op_set_test_cases \
987 }
988
989 TEST (ccont)
990 };
991
992 const std::size_t test_count = sizeof tests / sizeof *tests;
993
994 const int status =
995 rw_run_cont_test (argc, argv, __FILE__,
996 "lib.list.cons",
998 test_cons_func_array, tests, test_count);
999
1000 return status;
1001}
#define T
Definition 17.names.cpp:163
#define Distance
Definition 17.names.cpp:466
#define alloc
Definition 17.names.cpp:441
#define last
Definition 17.names.cpp:487
#define which
Definition 17.names.cpp:575
#define dist
Definition 17.names.cpp:464
#define index
Definition 17.names.cpp:482
#define off
Definition 17.names.cpp:507
#define tmp
Definition 17.names.cpp:553
#define range_test_cases
#define Cons(sig)
void _rw_advance(InputIterator &it, Distance dist)
void test_cons(T *, Allocator *, const ContRangeBase< std::list< T, Allocator > > &rng, const ContainerTestCaseData< T > &tdata)
#define TEST(dummy)
#define OpSet(sig)
void _rw_advance(InputIterator &it, Distance dist)
#define Cons(sig)
void test_op_set(T *, Allocator *, const ContainerTestCaseData< T > &tdata)
const int end
#define main
int caught
#define _RWSTD_STATIC_CAST(T, x)
Definition _defs.h:534
#define _RWSTD_CONST_CAST(T, x)
Definition _defs.h:536
const ContainerFunc & func_
const ContainerTestCase & tcase_
@ def_ctor
_TEST_EXPORT void rw_check_leaks(const SharedAlloc *=0, int=0, _RWSTD_SIZE_T=0, _RWSTD_SIZE_T=_RWSTD_SIZE_MAX)
_TEST_EXPORT _RWSTD_SIZE_T rw_match(const char *, const char *, _RWSTD_SIZE_T=_RWSTD_SIZE_MAX)
_TEST_EXPORT int rw_run_cont_test(int, char **, const char *, const char *, ContainerIds::ContainerId, ContainerTestFunc *, const ContainerTest *, _RWSTD_SIZE_T)
#define DEFINE_CONTAINER_TEST_FUNCTIONS(fname)
_TEST_EXPORT int rw_assert(int, const char *, int, const char *,...)
Definition driver.cpp:1630
_TEST_EXPORT int rw_error(int, const char *, int, const char *,...)
Definition driver.cpp:1613
_TEST_EXPORT _RWSTD_SIZE_T rwt_check_leaks(_RWSTD_SIZE_T *, const rwt_free_store *)
Definition new.cpp:684
_TEST_EXPORT rwt_free_store * rwt_get_free_store(rwt_free_store *)
Definition new.cpp:597
#define RW_ASSERT(expr)
List::allocator_type ListAlloc
List::value_type ListVal
virtual List & operator()(List &list_arg, const ContainerTestCaseData< ListVal > &tdata) const
virtual List & operator()(List &, const ContainerTestCaseData< ListVal > &tdata) const
List::allocator_type ListAlloc
List::value_type ListVal
List::value_type ListVal
List::allocator_type ListAlloc
virtual List & operator()(List &, const ContainerTestCaseData< ListVal > &tdata) const
static ContIter begin(List &cont, ContIter *)
_RWSTD_SIZE_T which_
ContainerIds::IteratorId iter_id_
static SharedAlloc * instance(SharedAlloc *=0)
_RWSTD_SIZE_T throw_at_calls_[n_funs]
static _RWSTD_SIZE_T n_total_op_assign_
Definition rw_value.h:127
static bool is_total(_RWSTD_SIZE_T count, _RWSTD_SIZE_T n_def_ctor, _RWSTD_SIZE_T n_copy_ctor, _RWSTD_SIZE_T n_op_assign, _RWSTD_SIZE_T n_op_eq, _RWSTD_SIZE_T n_op_lt)
Definition value.cpp:419
static _RWSTD_SIZE_T copy_ctor_throw_count_
Definition rw_value.h:164
static _RWSTD_SIZE_T count_
Definition rw_value.h:120
static void reset_totals()
Definition value.cpp:452
static _RWSTD_SIZE_T n_total_def_ctor_
Definition rw_value.h:124
static _RWSTD_SIZE_T n_total_copy_ctor_
Definition rw_value.h:125
_RWSTD_SIZE_T * throw_at_calls_[2]
Definition rw_new.h:83
_RWSTD_SIZE_T new_calls_[2]
Definition rw_new.h:47
int arg
Definition locale.cpp:2806