Ne.app NeANT
The Ne.app NeANT User module of the NeANT distribution.
23.list.insert.cpp
Go to the documentation of this file.
1
27#include <list> // for list
28#include <stdexcept> // for out_of_range, length_error
29#include <cstddef> // for size_t
30
31#include <rw_lists.h> // for ListMembers
32#include <rw_alg_test.h> // for InputIter
33#include <rw_driver.h> // for rw_test()
34#include <rw_allocator.h> // for UserAlloc
35#include <rw_new.h> // for bad_alloc, replacement operator new
36
37
39// for convenience and brevity
40#define Insert(sig) ListIds::insert_ ## sig
41
42static const char* const exceptions[] = {
43 "unknown exception", "bad_alloc", "exception"
44};
45
46
48// exercises
49// insert (iterator, InputIterator, InputIterator)
50static const ContainerTestCase
51iter_range_test_cases [] = {
52
53#undef TEST
54#define TEST(lst, off, arg, off2, size2, res, bthrow) { \
55 __LINE__, off, -1, off2, size2, -1, lst, sizeof lst - 1, \
56 arg, sizeof arg - 1, res, sizeof res - 1, bthrow \
57 }
58
59 // +----------------------------------------- controlled sequence
60 // | +------------------------ insert() pos argument
61 // | | +--------------------- sequence to be inserted
62 // | | | +-------- insert() off2 argument
63 // | | | | +----- insert() num argument
64 // | | | | | +-- expected result sequence
65 // | | | | | | +--- exception info
66 // | | | | | | | 0 - no exception
67 // | | | | | | | 1 - out_of_range
68 // | | | | | | | 2 - length_error
69 // | | | | | | | -1 - exc. safety
70 // | | | | | | |
71 // | | | | | | +----------------+
72 // V V V V V V V
73 TEST ("ab", 0, "c", 0, 1, "cab", 0),
74
75 TEST ("", 0, "", 0, 0, "", 0),
76 TEST ("", 0, "abc", 1, 1, "b", 0),
77 TEST ("", 0, "<U0>", 0, 1, "<U0>", 0),
78
79 TEST ("<U0>", 0, "", 0, 0, "<U0>", 0),
80 TEST ("<U0>", 1, "", 0, 0, "<U0>", 0),
81
82 TEST ("abc", 0, "", 0, 0, "abc", 0),
83 TEST ("abc", 1, "", 0, 0, "abc", 0),
84 TEST ("abc", 3, "", 0, 0, "abc", 0),
85
86 TEST ("<U0>", 0, "a", 0, 1, "a<U0>", 0),
87 TEST ("<U0>", 1, "a", 0, 1, "<U0>a", 0),
88 TEST ("<U0>", 0, "<U0>@2", 1, 1, "<U0>@2", 0),
89 TEST ("<U0>", 1, "<U0>@2", 0, 2, "<U0>@3", 0),
90
91 TEST ("cde", 0, "ab", 0, 2, "abcde", 0),
92 TEST ("cde", 1, "ab", 0, 1, "cade", 0),
93 TEST ("cde", 3, "ab", 1, 1, "cdeb", 0),
94
95 TEST ("ab", 0, "c<U0>e", 0, 3, "c<U0>eab", 0),
96 TEST ("ab", 1, "c<U0>e", 1, 2, "a<U0>eb", 0),
97 TEST ("ab", 2, "c<U0>e", 0, 2, "abc<U0>", 0),
98
99 TEST ("<U0>e<U0>", 1, "<U0>ab<U0>@2c", 0, 6, "<U0>@2ab<U0>@2ce<U0>",0),
100 TEST ("<U0>e<U0>", 1, "<U0>ab<U0>@2c", 0, 3, "<U0>@2abe<U0>", 0),
101 TEST ("a<U0>b<U0>@2c", 3, "<U0>e<U0>", 0, 3, "a<U0>b<U0>e<U0>@3c", 0),
102 TEST ("a<U0>b<U0>@2c", 2, "<U0>@2e<U0>", 0, 2, "a<U0>@3b<U0>@2c", 0),
103 TEST ("<U0>ab<U0>@2c", 0, "<U0>e<U0>", 2, 1, "<U0>@2ab<U0>@2c", 0),
104 TEST ("a<U0>bc<U0>@2", 6, "<U0>e", 0, 2, "a<U0>bc<U0>@3e", 0),
105
106 TEST ("", 0, "x@4096", 0, 4096, "x@4096", 0),
107 TEST ("x@4096", 0, "", 0, 0, "x@4096", 0),
108 TEST ("a@1000", 0, "b@1000", 0, 999, "b@999a@1000", 0),
109 TEST ("a@1000", 1, "b@1001", 0, 1000, "ab@1000a@999", 0),
110 TEST ("a@1000", 2, "b@1002", 0, 1001, "aab@1001a@998", 0),
111 TEST ("a@1000", 998, "b@1000", 1, 999, "a@998b@999aa", 0),
112 TEST ("a@1000", 999, "b@1001", 2, 999, "a@999b@999a", 0),
113 TEST ("a@1000", 2, "b@1002", 999, 3, "aabbba@998", 0),
114
115 TEST ("x@10", 1, "x@118", 0, 118, "x@128", 0),
116 TEST ("x@128", 0, "x@129", 50, 79, "x@207", 0),
117 TEST ("x@207", 207, "x@127", 0, 127, "x@334", 0),
118 TEST ("x@207", 128, "x@207", 10, 127, "x@334", 0),
119 TEST ("x@334", 334, "x@208", 2, 206, "x@540", 0),
120 TEST ("x@540", 0, "x@336", 3, 333, "x@873", 0),
121 TEST ("x@539", 538, "x@873", 0, 873, "x@1412", 0),
122 TEST ("x@873", 540, "x@540", 1, 539, "x@1412", 0),
123 TEST ("x@872", 0, "x@1412", 0, 1412, "x@2284", 0),
124 TEST ("x@1411", 1411, "x@2288", 4, 2284, "x@3695", 0),
125 TEST ("x@1411", 872, "x@3695", 128, 2284, "x@3695", 0),
126 TEST ("x@1412", 0, "x@2284", 0, 2284, "x@3696", 0),
127
128 TEST ("<U0>", 2, "", 0, 0, "<U0>", 1),
129 TEST ("", 0, "<U0>", 2, 0, "", 2),
130
131 TEST ("a", 2, "", 0, 0, "a", 1),
132 TEST ("", 0, "a", 2, 0, "", 2),
133
134 TEST ("x@4096", 4106, "", 0, 0, "x@4096", 1),
135 TEST ("", 0, "x@4096", 4106, 0, "", 2),
136
137 TEST ("last", 4, "test", 0, 4, "lasttest", 0)
138};
139
140
142// exercises
143// insert (iterator, size_type, const value_type&)
144static const ContainerTestCase
145iter_size_cref_test_cases [] = {
146
147#undef TEST
148#define TEST(lst, off, size, val, res, bthrow) { \
149 __LINE__, off, size, -1, -1, val, lst, sizeof lst - 1, \
150 0, 0, res, sizeof res - 1, bthrow \
151 }
152
153 // +---------------------------------------- controlled sequence
154 // | +----------------------- insert() pos argument
155 // | | +-------------------- insert() size argument
156 // | | | +------------- character to be inserted
157 // | | | | +--------- expected result sequence
158 // | | | | | +- exception info
159 // | | | | | | 0 - no exception
160 // | | | | | | 1 - out_of_range
161 // | | | | | | 2 - length_error
162 // | | | | | | -1 - exc. safety
163 // | | | | | |
164 // | | | | | +---------+
165 // V V V V V V
166 TEST ("ab", 0, 1, 'c', "cab", 0),
167
168 TEST ("", 0, 0, ' ', "", 0),
169 TEST ("", 0, 1, 'b', "b", 0),
170
171 TEST ("<U0>", 0, 0, ' ', "<U0>", 0),
172 TEST ("<U0>", 1, 0, ' ', "<U0>", 0),
173 TEST ("", 0, 2, '\0', "<U0>@2", 0),
174
175 TEST ("<U0>", 0, 1, 'a', "a<U0>", 0),
176 TEST ("<U0>", 1, 1, 'a', "<U0>a", 0),
177 TEST ("<U0>", 0, 1, '\0', "<U0>@2", 0),
178 TEST ("<U0>", 1, 2, '\0', "<U0>@3", 0),
179 TEST ("<U0>", 1, 0, '\0', "<U0>", 0),
180
181 TEST ("cde", 0, 2, 'a', "aacde", 0),
182 TEST ("cde", 1, 1, 'a', "cade", 0),
183 TEST ("cde", 3, 3, 'a', "cdeaaa", 0),
184 TEST ("cde", 2, 3, 'a', "cdaaae", 0),
185
186 TEST ("ab", 0, 2, '\0', "<U0>@2ab", 0),
187 TEST ("ab", 1, 1, '\0', "a<U0>b", 0),
188 TEST ("ab", 2, 2, '\0', "ab<U0>@2", 0),
189
190 TEST ("a<U0>b<U0>@2c", 3, 2, '\0', "a<U0>b<U0>@3<U0>c", 0),
191 TEST ("a<U0>b<U0>@2c", 2, 1, '\0', "a<U0>@2b<U0>@2c", 0),
192 TEST ("<U0>ab<U0>@2c", 0, 3, '\0', "<U0>@3<U0>ab<U0>@2c", 0),
193 TEST ("a<U0>bc<U0>@2", 6, 2, 'a', "a<U0>bc<U0>@2aa", 0),
194
195 TEST ("", 0, 4106, 'x', "x@4106", 0),
196 TEST ("x@4096", 0, 2, 'a', "aax@4096", 0),
197
198 TEST ("x@4096", 0, 2, 'a', "aax@4096", 0),
199 TEST ("x@4096", 1, 2, 'a', "xaax@4095", 0),
200 TEST ("x@4096", 1, 1, '\0', "x<U0>x@4095", 0),
201
202 TEST ("x@127", 0, 1, 'x', "x@128", 0),
203 TEST ("x@200", 128, 7, 'x', "x@207", 0),
204 TEST ("x@331", 331, 3, 'x', "x@334", 0),
205 TEST ("x@539", 0, 1, 'x', "x@540", 0),
206 TEST ("x@539", 0, 873, 'x', "x@1412", 0),
207 TEST ("x@873", 873, 1411, 'x', "x@2284", 0),
208 TEST ("x@3694", 128, 1, 'x', "x@3695", 0),
209 TEST ("x@540", 0, 1, 'x', "x@541", 0),
210 TEST ("", 0, 3695, 'x', "x@3695", 0),
211
212 TEST ("a", 0, 4095, 'x', "x@4095a", 0),
213 TEST ("x@4096", 0, 2047, 'b', "b@2047x@4096", 0),
214 TEST ("x@4096", 2047, 2048, 'x', "x@6144", 0),
215
216 TEST ("last", 4, 4, 't', "lasttttt", 0)
217};
218
219
221// used to exercise
222// insert (iterator, const value_type&)
223static const ContainerTestCase
224iter_cref_test_cases [] = {
225
226#undef TEST
227#define TEST(lst, off, val, res, bthrow) \
228 { __LINE__, off, -1, -1, -1, val, lst, sizeof lst - 1, 0, \
229 0, res, sizeof res - 1, bthrow }
230
231 // +----------------------------------------- controlled sequence
232 // | +------------------------ insert() pos argument
233 // | | +------------------- character to be inserted
234 // | | | +--------------- expected result sequence
235 // | | | | +--- exception info
236 // | | | | | 0 - no exception
237 // | | | | | 1 - out_of_range
238 // | | | | | 2 - length_error
239 // | | | | | -1 - exc. safety
240 // | | | | |
241 // | | | | |
242 // V V V V V
243 TEST ("ab", 0, 'c', "cab", 0),
244
245 TEST ("", 0, 'b', "b", 0),
246 TEST ("", 0, '\0', "<U0>", 0),
247
248 TEST ("<U0>", 0, 'a', "a<U0>", 0),
249 TEST ("<U0>", 1, 'a', "<U0>a", 0),
250 TEST ("<U0>", 0, '\0', "<U0>@2", 0),
251 TEST ("<U0>", 1, '\0', "<U0>@2", 0),
252
253 TEST ("cde", 0, 'a', "acde", 0),
254 TEST ("cde", 1, 'a', "cade", 0),
255 TEST ("cde", 2, 'a', "cdae", 0),
256 TEST ("cde", 3, 'a', "cdea", 0),
257
258 TEST ("a<U0>b<U0>@2c", 3, '\0', "a<U0>b<U0>@3c", 0),
259 TEST ("<U0>ab<U0>@2c", 0, '\0', "<U0>@2ab<U0>@2c", 0),
260 TEST ("a<U0>bc<U0>@2", 6, 'a', "a<U0>bc<U0>@2a", 0),
261
262 TEST ("x@4096", 0, 'a', "ax@4096", 0),
263 TEST ("x@4096", 1, 'a', "xax@4095", 0),
264 TEST ("x@4096", 1, '\0', "x<U0>x@4095", 0),
265
266 TEST ("x@127", 0, 'x', "x@128", 0),
267 TEST ("x@206", 1, 'x', "x@207", 0),
268 TEST ("x@333", 333, 'x', "x@334", 0),
269 TEST ("x@539", 128, 'x', "x@540", 0),
270 TEST ("x@1411", 0, 'x', "x@1412", 0),
271 TEST ("x@2283", 10, 'x', "x@2284", 0),
272 TEST ("x@3694", 3694, 'x', "x@3695", 0),
273 TEST ("x@540", 538, 'x', "x@541", 0),
274
275 TEST ("last", 4, 't', "lastt", 0)
276};
277
278
280// used to exercise
281// push_front (const value_type&)
282static const ContainerTestCase
283push_front_test_cases [] = {
284
285#undef TEST
286#define TEST(str, val, res) { \
287 __LINE__, -1, -1, -1, -1, val, str, sizeof str - 1, \
288 0, 0, res, sizeof res - 1, 0 }
289
290 // +----------------------------------------- controlled sequence
291 // | +------------------------ character to be inserted
292 // | | +------------------ expected result sequence
293 // | | |
294 // | | |
295 // | | |
296 // | | |
297 // | | |
298 // V V V
299 TEST ("", 'x', "x" ),
300 TEST ("<U0>", '\0', "<U0>@2" ),
301 TEST ("", 'a', "a" ),
302 TEST ("bc", 'a', "abc" ),
303 TEST ("<U0> s", 't', "t<U0> s" ),
304 TEST ("<U0>@3b", 'a', "a<U0>@3b" ),
305 TEST ("<U0>b<U0>@2c", 'a', "a<U0>b<U0>@2c" ),
306 TEST ("ab<U0>@2c", '\0', "<U0>ab<U0>@2c" ),
307 TEST ("b<U0>c<U0>@2", 'a', "ab<U0>c<U0>@2" ),
308 TEST ("x@4095", 'x', "x@4096" ),
309
310 TEST ("ast test", 'l', "last test" )
311};
312
313
315// used to exercise
316// push_back (const value_type&)
317static const ContainerTestCase
318push_back_test_cases [] = {
319
320#undef TEST
321#define TEST(str, val, res) { \
322 __LINE__, -1, -1, -1, -1, val, str, sizeof str - 1, \
323 0, 0, res, sizeof res - 1, 0 }
324
325 // +----------------------------------------- controlled sequence
326 // | +------------------------ character to be inserted
327 // | | +------------------ expected result sequence
328 // | | |
329 // | | |
330 // | | |
331 // | | |
332 // | | |
333 // V V V
334 TEST ("", 'x', "x" ),
335 TEST ("<U0>", '\0', "<U0>@2" ),
336 TEST ("", 'a', "a" ),
337 TEST ("ab", 'c', "abc" ),
338 TEST ("t<U0> ", 's', "t<U0> s" ),
339 TEST ("a<U0>@3", 'b', "a<U0>@3b" ),
340 TEST ("a<U0>b<U0>@2", 'c', "a<U0>b<U0>@2c" ),
341 TEST ("<U0>ab<U0>@2", 'c', "<U0>ab<U0>@2c" ),
342 TEST ("ab<U0>c<U0>", '\0', "ab<U0>c<U0>@2" ),
343 TEST ("x@4095", 'x', "x@4096" ),
344
345 TEST ("last tes", 't', "last test" )
346};
347
348
350template <class InputIterator, class Distance>
351inline void
353
354 while (0 < dist) {
355 --dist;
356 ++it;
357 }
358}
359
360template<class InputIterator>
361inline std::size_t
363{
364 std::size_t dist = 0;
365
366 for (; first != last; ++first)
367 ++dist;
368
369 return dist;
370}
371
372// invokes specializations of the member function template
373// on the required iterator categories
374template <class List, class Iterator>
376
377 typedef typename List::iterator ListIter;
378 typedef typename List::value_type ListVal;
379
381
382 virtual List&
383 operator() (List &lst,
384 const ContainerTestCaseData<ListVal>& tdata) const {
385
386 // create a pair of iterators into the list object being modified
387 ListIter first1 (lst.begin ());
388 _rw_advance (first1, tdata.off1_);
389
390 const ListVal* const beg = tdata.arg_ + tdata.off2_;
391 const ListVal* const end = beg + tdata.ext2_;
392
393 const Iterator first2 (beg, beg, end);
394 const Iterator last2 (end, beg, end);
395
396 lst.insert (first1, first2, last2);
397 return lst;
398 }
399};
400
401
402// invokes possible overloads of the member function template
403// on common RandomAccessIterator types
404template <class List, class Iterator>
406{
407 typedef typename List::iterator ListIter;
408 typedef typename List::value_type ListVal;
409
411
412 virtual List&
413 operator() (List &lst,
414 const ContainerTestCaseData<ListVal>& tdata) const {
415
416 // create a pair of iterators into the list object being modified
417 ListIter first1 (lst.begin ());
418 _rw_advance (first1, tdata.off1_);
419
420 bool reverse_iter = ListIds::ReverseIterator == tdata.func_.iter_id_
422
423 const std::size_t srclen_ = tdata.arglen_;
424
425 const std::size_t off =
426 reverse_iter ? srclen_ - tdata.off2_ - tdata.ext2_ : tdata.off2_;
427 const std::size_t ext = tdata.ext2_;
428
429 List str_arg (tdata.arg_, tdata.arg_ + tdata.arglen_);
430
431 Iterator first2 (this->begin (str_arg, (Iterator*)0));
432 _rw_advance (first2, off);
433
434 Iterator last2 (first2);
435 _rw_advance (last2, ext);
436
437 if (ListIds::UserClass == tdata.func_.elem_id_)
439
440 lst.insert (first1, first2, last2);
441 return lst;
442 }
443};
444
445// invokes specializations of the member function template
446// on the required iterator categories
447template <class List, class Iterator>
449
450 typedef typename List::iterator ListIter;
451 typedef typename List::value_type ListVal;
452
454
455 virtual List&
456 operator() (List& lst,
457 const ContainerTestCaseData<ListVal>& tdata) const {
458
459 ListIter first1 (lst.begin ());
460 _rw_advance (first1, tdata.off1_);
461
462 const ListVal* const beg = tdata.arg_ + tdata.off2_;
463 const ListVal* const end = beg + tdata.ext2_;
464
465 const Iterator first2 = _RWSTD_CONST_CAST (Iterator, beg);
466 const Iterator last2 = _RWSTD_CONST_CAST (Iterator, end);
467
468 lst.insert (first1, first2, last2);
469 return lst;
470 }
471};
472
473
475template <class T, class Allocator>
477 const ContRangeBase< std::list <T, Allocator> > &rng,
478 const ContainerTestCaseData<T> &tdata)
479{
480 typedef std::list <T, Allocator> List;
481 typedef typename List::iterator ListIter;
482 typedef typename List::const_iterator ListCIter;
484
485 const ContainerFunc &func = tdata.func_;
486 const ContainerTestCase &tcase = tdata.tcase_;
487
488 // construct the list object to be modified
489 List lst (tdata.str_, tdata.str_ + tdata.strlen_);
490
491 // save the state of the list object before the call
492 // to detect exception safety violations (changes to
493 // the state of the object after an exception)
494 const ListState lst_state (lst);
495
496 std::ptrdiff_t exp_off = Insert (iter_cref) == func.which_ ? tcase.off : 0;
497
498 // compute the offset and the extent (the number of elements)
499 // of the first range into the list object being modified
500 const std::size_t size1 = tdata.strlen_;
501 const std::size_t off1 =
502 std::size_t (tcase.off) < size1 ? std::size_t (tcase.off) : size1;
503
504 const T arg_val = T::from_char (char (tcase.val));
505
506 rwt_free_store* const pst = rwt_get_free_store (0);
507 SharedAlloc* const pal = SharedAlloc::instance ();
508
509 // iterate for`throw_after' starting at the next call to operator new,
510 // forcing each call to throw an exception, until the function finally
511 // succeeds (i.e, no exception is thrown)
512 std::size_t throw_count;
513 for (throw_count = 0; ; ++throw_count) {
514
515 // (name of) expected and caught exception
516 const char* expected = 0;
517 const char* caught = 0;
518
519#ifndef _RWSTD_NO_EXCEPTIONS
520
521 if (0 == tcase.bthrow) {
522 // by default exercise the exception safety of the function
523 // by iteratively inducing an exception at each call to operator
524 // new or Allocator::allocate() until the call succeeds
525 expected = exceptions [1]; // bad_alloc
526 *pst->throw_at_calls_ [0] = pst->new_calls_ [0] + throw_count + 1;
527 pal->throw_at_calls_ [pal->m_allocate] =
528 pal->throw_at_calls_ [pal->m_allocate] + throw_count + 1;
529 }
530 else {
531 // exceptions disabled for this test case
532 }
533
534#else // if defined (_RWSTD_NO_EXCEPTIONS)
535
536 if (tcase.bthrow)
537 return;
538
539#endif // _RWSTD_NO_EXCEPTIONS
540
541 // pointer to the returned reference
542 const List* ret_ptr = 0;
543
544 // start checking for memory leaks
545 rw_check_leaks (lst.get_allocator ());
546
547 const bool is_class = ListIds::UserClass == func.elem_id_;
548
549 const std::size_t x_count_save = UserClass::count_;
550
551 try {
552 // reset function call counters
553 if (is_class)
555
556 std::size_t newcnt = 0;
557
558 switch (func.which_) {
559
560 case Insert (iter_size_cref): {
561 ListIter it (lst.begin ());
562 _rw_advance (it, off1);
563 lst.insert (it, tcase.size, arg_val);
564 ret_ptr = &lst; // function returns void
565 newcnt = tcase.size;
566 break;
567 }
568
569 case Insert (iter_cref): {
570 ListIter it (lst.begin ());
571 _rw_advance (it, off1);
572 it = lst.insert (it, arg_val);
573 ret_ptr = &lst + _rw_distance (lst.begin (), it);
574 newcnt = 1;
575 break;
576 }
577
578 case Insert (iter_range): {
579 ret_ptr = &rng (lst, tdata); // function returns void
580 newcnt = tcase.size2;
581 break;
582 }
583
584 case ListIds::push_front_cref:
585 lst.push_front (arg_val);
586 ret_ptr = &lst; // function returns void
587 newcnt = 1;
588 break;
589
590 case ListIds::push_back_cref:
591 lst.push_back (arg_val);
592 ret_ptr = &lst; // function returns void
593 newcnt = 1;
594 break;
595
596 default:
597 RW_ASSERT (!"logic error: unknown insert overload");
598 return;
599 }
600
601 if (is_class) {
602 // verify that the erase method calls only dtor
603 // of UserClass and only the given number of times each
604 bool success = UserClass::is_total (x_count_save + newcnt,
605 0, newcnt, 0, 0, 0);
606
607 rw_assert (success, 0, tcase.line,
608 "line %d. %{$FUNCALL} called default/copy ctor "
609 "and operator=() %zu, %zu and %zu times, "
610 "respectively, 0, %zu, 0, expected",
611 __LINE__,
615 newcnt);
616 }
617
618 // verify that the reference returned from the function
619 // refers to the modified list object (i.e., *this
620 // within the function)
621 const std::ptrdiff_t ret_off = ret_ptr - &lst;
622
623 // verify the returned value
624 rw_assert (exp_off == ret_off, 0, tcase.line,
625 "line %d. %{$FUNCALL} %{?}== begin() + %td, got %td%{;}"
626 "%{?}returned invalid reference, offset is %td%{;}",
627 __LINE__, Insert (iter_cref) == func.which_,
628 exp_off, ret_off,
629 Insert (iter_cref) != func.which_, ret_off);
630
631 // for convenience
632 static const int cwidth = sizeof (T);
633
634 const std::size_t got_size = lst.size ();
635 char* const got = new char [got_size + 1];
636
637 std::size_t index = 0;
638 for (ListCIter it = lst.begin (),
639 end = lst.end (); it != end; ++it) {
640 got [index++] = char (it->data_.val_);
641 }
642
643 got [got_size] = '\0';
644
645 // verify that strings length are equal
646 rw_assert (tdata.reslen_ == got_size, 0, tcase.line,
647 "line %d. %{$FUNCALL} expected \"%{X=*}\" with length "
648 "%zu, got %{/*.*Gs} with length %zu", __LINE__,
649 cwidth, int (tdata.reslen_), tdata.res_, tdata.reslen_,
650 1, int (got_size), got, got_size);
651
652 if (tdata.reslen_ == got_size) {
653 // if the result length matches the expected length
654 // (and only then), also verify that the modified
655 // list matches the expected result
656 const T* pmatch = T::mismatch (tdata.res_, got, got_size);
657
658 rw_assert (0 == pmatch, 0, tcase.line,
659 "line %d. %{$FUNCALL} expected \"%{X=*}\", "
660 "got %{/*.*Gs}, difference at offset %zu",
661 __LINE__, cwidth, int (tdata.reslen_), tdata.res_,
662 1, int (got_size), got, pmatch - tdata.res_);
663 }
664
665 delete [] got;
666 }
667
668#ifndef _RWSTD_NO_EXCEPTIONS
669
670 catch (const std::bad_alloc &ex) {
671 caught = exceptions [1];
672 rw_assert (0 == tcase.bthrow, 0, tcase.line,
673 "line %d. %{$FUNCALL} %{?}expected %s,%{:}"
674 "unexpectedly%{;} caught std::%s(%#s)",
675 __LINE__, 0 != expected, expected, caught, ex.what ());
676 }
677 catch (const std::exception &ex) {
678 caught = exceptions [2];
679 rw_assert (0, 0, tcase.line,
680 "line %d. %{$FUNCALL} %{?}expected %s,%{:}"
681 "unexpectedly%{;} caught std::%s(%#s)",
682 __LINE__, 0 != expected, expected, caught, ex.what ());
683 }
684 catch (...) {
685 caught = exceptions [0];
686 rw_assert (0, 0, tcase.line,
687 "line %d. %{$FUNCALL} %{?}expected %s,%{:}"
688 "unexpectedly%{;} caught %s",
689 __LINE__, 0 != expected, expected, caught);
690 }
691
692#endif // _RWSTD_NO_EXCEPTIONS
693
694 // FIXME: verify the number of blocks the function call
695 // is expected to allocate and detect any memory leaks
696 rw_check_leaks (lst.get_allocator (), tcase.line,
697 std::size_t (-1), std::size_t (-1));
698
699 if (caught) {
700 // verify that an exception thrown during allocation
701 // didn't cause a change in the state of the object
702 lst_state.assert_equal (ListState (lst),
703 __LINE__, tcase.line, caught);
704
705 if (0 == tcase.bthrow) {
706 // allow this call to operator new to succeed and try
707 // to make the next one to fail during the next call
708 // to the same function again
709 continue;
710 }
711 }
712 else if (0 < tcase.bthrow) {
713 rw_assert (caught == expected, 0, tcase.line,
714 "line %d. %{$FUNCALL} %{?}expected %s, caught %s"
715 "%{:}unexpectedly caught %s%{;}",
716 __LINE__, 0 != expected, expected, caught, caught);
717 }
718
719 break;
720 }
721
722 // disable bad_alloc exceptions
723 *pst->throw_at_calls_ [0] = 0;
724 pal->throw_at_calls_ [pal->m_allocate] = 0;
725}
726
727
729template <class T, class Allocator>
731 const ContainerTestCaseData<T> &tdata)
732{
733 typedef std::list<T, Allocator> List;
734
735 if (tdata.func_.which_ == Insert (iter_range)) {
736
737 switch (tdata.func_.iter_id_) {
738
739 // exercise possible overloads of the member function template
740 // on common RandomAccessIterator types
741#undef TEST
742#define TEST(Iterator) do { \
743 typedef typename List::Iterator Iter; \
744 static const \
745 InsertRangePtrOverload<List, Iter> rng; \
746 test_insert ((T*)0, (Allocator*)0, rng, tdata); \
747 } while (0)
748
749 case ListIds::Pointer: TEST (pointer); break;
750 case ListIds::ConstPointer: TEST (const_pointer); break;
751
752#undef TEST
753#define TEST(Iterator) do { \
754 typedef typename List::Iterator Iter; \
755 static const \
756 InsertRangeOverload<List, Iter> rng; \
757 test_insert ((T*)0, (Allocator*)0, rng, tdata); \
758 } while (0)
759
760 case ListIds::Iterator: TEST (iterator); break;
761 case ListIds::ConstIterator: TEST (const_iterator); break;
762
763 case ListIds::ReverseIterator: TEST (reverse_iterator); break;
764 case ListIds::ConstReverseIterator: TEST (const_reverse_iterator);
765 break;
766
767 // exercise specializations of the member function template
768 // on the required iterator categories
769#undef TEST
770#define TEST(Iterator) do { \
771 typedef Iterator<T> Iter; \
772 static const \
773 InsertRange<List, Iter> rng; \
774 test_insert ((T*)0, (Allocator*)0, rng, tdata); \
775 } while (0)
776
777 case ListIds::Input: TEST (InputIter); break;
778 case ListIds::Forward: TEST (ConstFwdIter); break;
779 case ListIds::Bidir: TEST (ConstBidirIter); break;
781
782 default:
783 rw_error (0, 0, __LINE__, "bad iterator id");
784 }
785 }
786 else {
787 // exercise ordinary overloads of the member function
788 static const ContRangeBase<List> rng;
789 test_insert ((T*)0, (Allocator*)0, rng, tdata);
790 }
791}
792
793
796
797int main (int argc, char** argv)
798{
799 static const ContainerTest
800 tests [] = {
801
802#undef TEST
803#define TEST(sig) { \
804 Insert (sig), sig ## _test_cases, \
805 sizeof sig ## _test_cases / sizeof *sig ## _test_cases \
806 }
807
808 TEST (iter_cref),
809 TEST (iter_size_cref),
810 TEST (iter_range),
811
812#undef TEST
813#define TEST(sig) { \
814 ListIds::sig ## _cref, sig ## _test_cases, \
815 sizeof sig ## _test_cases / sizeof *sig ## _test_cases \
816 }
817
818 TEST (push_front),
819 TEST (push_back)
820 };
821
822 const std::size_t test_count = sizeof tests / sizeof *tests;
823
824 const int status =
825 rw_run_cont_test (argc, argv, __FILE__,
826 "lib.list.insert",
828 test_insert_func_array, tests, test_count);
829
830 return status;
831}
#define T
Definition 17.names.cpp:163
#define Distance
Definition 17.names.cpp:466
#define last
Definition 17.names.cpp:487
#define dist
Definition 17.names.cpp:464
#define index
Definition 17.names.cpp:482
#define off
Definition 17.names.cpp:507
void test_insert()
void _rw_advance(InputIterator &it, Distance dist)
#define TEST(lst, off, arg, off2, size2, res, bthrow)
#define Insert(sig)
std::size_t _rw_distance(InputIterator first, InputIterator last)
void _rw_advance(InputIterator &it, Distance dist)
const int end
#define main
int caught
#define _RWSTD_CONST_CAST(T, x)
Definition _defs.h:536
const ContainerFunc & func_
const ContainerTestCase & tcase_
_TEST_EXPORT void rw_check_leaks(const SharedAlloc *=0, int=0, _RWSTD_SIZE_T=0, _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 rwt_free_store * rwt_get_free_store(rwt_free_store *)
Definition new.cpp:597
#define RW_ASSERT(expr)
static ContIter begin(List &cont, ContIter *)
ContainerIds::ElemId elem_id_
_RWSTD_SIZE_T which_
ContainerIds::IteratorId iter_id_
virtual List & operator()(List &lst, const ContainerTestCaseData< ListVal > &tdata) const
List::iterator ListIter
List::value_type ListVal
virtual List & operator()(List &lst, const ContainerTestCaseData< ListVal > &tdata) const
virtual List & operator()(List &lst, const ContainerTestCaseData< ListVal > &tdata) const
List::iterator ListIter
List::value_type ListVal
void assert_equal(const ListState &state, int line, int case_line, const char *when) const
Definition rw_lists.h:267
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 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