Ne.app NeANT
The Ne.app NeANT User module of the NeANT distribution.
23.deque.modifiers.cpp
Go to the documentation of this file.
1
29#ifdef _MSC_VER
30 // silence warning C4244: 'argument' : conversion from 'T' to
31 // 'const std::allocator<_TypeT>::value_type', possible loss of data
32 // issued for deque::assign(InputIterator a, InputIterator b) and
33 // deque::insert(iterator, InputIterator a, InputIterator b) due
34 // the implicit conversion of a to size_type and b to value_type
35 // required by DR 438:
36 // http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#438
37# pragma warning (disable: 4244)
38#endif
39
40#include <deque> // for deque
41
42#include <cstdlib> // for free()
43
44#ifndef _RWSTD_NO_REPLACEABLE_NEW_DELETE
45 // disabled for MSVC since it can't reliably replace the operators
46# include <rw_new.h>
47#endif // _RWSTD_NO_REPLACEABLE_NEW_DELETE
48
49#include <rw_value.h> // for UserClass
50#include <rw_driver.h> // for rw_test(), ...
51#include <rw_printf.h> // for rw_asnprintf
52
53
55// Runtime options
56/* extern */ int rw_opt_no_assign = 0;
57/* extern */ int rw_opt_no_erase = 0;
58/* extern */ int rw_opt_no_insert = 0;
59/* extern */ int rw_opt_no_dr438 = 0;
60/* extern */ int rw_opt_no_input_iterator = 0;
61/* extern */ int rw_opt_no_forward_iterator = 0;
63/* extern */ int rw_opt_no_random_iterator = 0;
64/* extern */ int rw_opt_no_right_thing = 0;
65
66
68// For konvenience
69typedef unsigned char UChar;
70
71
73typedef std::deque<UserClass, std::allocator<UserClass> > Deque;
74
75Deque::size_type new_capacity;
76
77namespace __rw {
78
80inline Deque::size_type
81__rw_new_capacity<Deque>(Deque::size_type n, const Deque*)
82{
83 if (n) {
84 // non-zero size argument indicates a request for an increase
85 // in the capacity of a deque object's dynamically sizable
86 // vector of nodes
87 return n * 2;
88 }
89
90 // zero size argument is a request for the initial size of a deque
91 // object's dynamically sizable vector of nodes or for the size of
92 // the objects's fixed-size buffer for elements
93 return new_capacity;
94}
95
96}
97
98
100enum {
101 NewThrows = 0x1 /* cause operator new to throw */,
102 CopyCtorThrows = 0x2 /* cause element's copy ctor to throw */,
103 AssignmentThrows = 0x4 /* cause element's assignment to throw */
105
107 Assign_n /* deque::assign (size_type, const_reference) */,
108 AssignRange /* deque::assign (InputIterator, InputIterator) */,
109
110 Erase_1 /* deque::erase (iterator) */,
111 EraseRange /* deque::erase (iterator, iterator) */,
112
113 Insert_1 /* deque::insert (iterator, const_reference) */,
114 Insert_n /* deque::insert (iterator, size_type, const_reference) */,
115 InsertRange /* deque::insert (iterator, InputIterator, InputIterator) */
117
118
119// causes operator new, deque element's copy ctor, or assignment operator
120// to throw an exception and iterates as long as the member function exits
121// by throwing an exception; verifies that the exception had no effects
122// on the container
123template <class Iterator>
124void exception_loop (int line /* line number in caller*/,
125 MemberFunction mfun /* deque member function */,
126 const char *fcall /* function call string */,
127 int exceptions /* enabled exceptions */,
128 Deque &deq /* container to call function on */,
129 const Deque::iterator &it /* iterator into container */,
130 int n /* number of elements or offset */,
131 const UserClass *x /* pointer to an element or 0 */,
132 const Iterator &first /* beginning of range */,
133 const Iterator &last /* end of range to insert */,
134 std::size_t *n_copy /* number of copy ctors */,
135 std::size_t *n_asgn /* number of assignments */)
136{
137 std::size_t throw_after = 0;
138
139 // get the initial size of the container and its begin() iterator
140 // to detect illegal changes after an exception (i.e., violations
141 // if the strong exception guarantee)
142 const std::size_t size = deq.size ();
143 const Deque::const_iterator begin = deq.begin ();
144 const Deque::const_iterator end = deq.end ();
145
146#ifdef DEFINE_REPLACEMENT_NEW_AND_DELETE
147
148 rwt_free_store* const pst = rwt_get_free_store (0);
149
150#endif // DEFINE_REPLACEMENT_NEW_AND_DELETE
151
152 // repeatedly call the specified member function until it returns
153 // without throwing an exception
154 for ( ; ; ) {
155
156 // detect objects constructed but not destroyed after an exception
157 std::size_t x_count = UserClass::count_;
158
159 _RWSTD_ASSERT (n_copy);
160 _RWSTD_ASSERT (n_asgn);
161
164
165#ifndef _RWSTD_NO_EXCEPTIONS
166
167 // iterate for `n=throw_after' starting at the next call to operator
168 // new, forcing each call to throw an exception, until the insertion
169 // finally succeeds (i.e, no exception is thrown)
170
171# ifdef DEFINE_REPLACEMENT_NEW_AND_DELETE
172
173 if (exceptions & NewThrows) {
174 *pst->throw_at_calls_ [0] = pst->new_calls_ [0] + throw_after + 1;
175 }
176
177# endif // DEFINE_REPLACEMENT_NEW_AND_DELETE
178
179 if (exceptions & CopyCtorThrows) {
181 UserClass::n_total_copy_ctor_ + throw_after;
182 }
183
184 if (exceptions & AssignmentThrows) {
186 UserClass::n_total_op_assign_ + throw_after;
187 }
188
189#endif // _RWSTD_NO_EXCEPTIONS
190
191 _TRY {
192
193 // convert an int to size_type to avoid conversion
194 // warnings when passing it to member functions
195 // that expect an unsigned argument
196 const Deque::size_type nelems (n);
197
198 switch (mfun) {
199 case Assign_n:
201 deq.assign (nelems, *x);
202 break;
203 case AssignRange:
204 deq.assign (first, last);
205 break;
206
207 case Erase_1:
208 deq.erase (it);
209 break;
210 case EraseRange: {
211 const Deque::iterator erase_end (it + n);
212 deq.erase (it, erase_end);
213 break;
214 }
215
216 case Insert_1:
218 deq.insert (it, *x);
219 break;
220 case Insert_n:
222 deq.insert (it, nelems, *x);
223 break;
224 case InsertRange:
225 deq.insert (it, first, last);
226 break;
227 }
228 }
229 _CATCH (...) {
230
231 // verify that an exception thrown from the member function
232 // didn't cause a change in the state of the container
233
234 rw_assert (deq.size () == size, 0, line,
235 "line %d: %s: size unexpectedly changed "
236 "from %zu to %zu after an exception",
237 __LINE__, fcall, size, deq.size ());
238
239 rw_assert (deq.begin () == begin, 0, line,
240 "line %d: %s: begin() unexpectedly "
241 "changed after an exception by %td",
242 __LINE__, fcall, deq.begin () - begin);
243
244 rw_assert (deq.end () == end, 0, line,
245 "line %d: %s: end() unexpectedly "
246 "changed after an exception by %td",
247 __LINE__, fcall, deq.end () - end);
248
249
250 // count the number of objects to detect leaks
251 x_count = UserClass::count_ - x_count;
252 rw_assert (x_count == deq.size () - size, 0, line,
253 "line %d: %s: leaked %zu objects after an exception",
254 __LINE__, fcall, x_count - (deq.size () - size));
255
256 if (exceptions) {
257
258 // increment to allow this call to operator new to succeed
259 // and force the next one to fail, and try to insert again
260 ++throw_after;
261 }
262 else
263 break;
264
265 continue;
266 }
267
268 // count the number of objects to detect leaks
269 x_count = UserClass::count_ - x_count;
270 rw_assert (x_count == deq.size () - size, 0, line,
271 "line %d: %s: leaked %zu objects "
272 "after a successful insertion",
273 __LINE__, fcall, x_count - (deq.size () - size));
274
275 break;
276 }
277
278#ifdef DEFINE_REPLACEMENT_NEW_AND_DELETE
279
280 // disable exceptions from replacement operator new
281 *pst->throw_at_calls_ [0] = _RWSTD_SIZE_MAX;
282
283#endif // DEFINE_REPLACEMENT_NEW_AND_DELETE
284
287
288 // compute the number of calls to UserClass copy ctor and assignment
289 // operator and set `n_copy' and `n_assgn' to the value of the result
290 *n_copy = UserClass::n_total_copy_ctor_ - *n_copy;
291 *n_asgn = UserClass::n_total_op_assign_ - *n_asgn;
292}
293
294
295// used to determine whether insert() can or cannot use
296// an algorithm optimized for BidirectionalIterators
297bool is_bidirectional (std::input_iterator_tag) { return false; }
298bool is_bidirectional (std::bidirectional_iterator_tag) { return true; }
299
300// returns the number of invocations of the assignment operators
301// for a call to deque::insert(iterator, InputIterator, InputIterator)
302// (the value depends on the iterator category)
303template <class Iterator>
305 int nelems,
306 std::size_t off,
307 std::size_t seqlen,
308 std::size_t inslen)
309{
311 return 0 == nelems ? 0 : off < seqlen - off ? off : seqlen - off;
312
313 if (0 < nelems)
314 --nelems;
315
316 if (0 == nelems || 0 == inslen)
317 return 0;
318
319 // compute the number of assignments done
320 // to insert the first element in the sequence
321 const std::size_t first = off < seqlen - off ? off : seqlen - off;
322
323 // recursively compute the numner of assignments
324 // for the rest of the elements in the sequence
325 const std::size_t rest =
326 insert_assignments (it, nelems, off + 1, seqlen + 1, inslen - 1);
327
328 return first + rest;
329}
330
331
332template <class Iterator>
333void test_insert (int line, int exceptions,
334 const Iterator &dummy, int nelems,
335 const char *seq, std::size_t seqlen, std::size_t off,
336 const char *ins, std::size_t inslen,
337 const char *res, std::size_t reslen)
338{
339 // Ensure that xsrc, xins are always dereferenceable
340 const UserClass* const xseq = UserClass::from_char (seq, seqlen + 1);
341 UserClass* const xins = UserClass::from_char (ins, inslen + 1);
342
343 Deque deq = seqlen ? Deque (xseq, xseq + seqlen) : Deque ();
344
345 // offset must be valid
346 _RWSTD_ASSERT (off <= deq.size ());
347 const Deque::iterator iter = deq.begin () + off;
348
349 // only insert() at either end of the container is exception safe
350 // insertions into the middle of the container are not (i.e., the
351 // container may grow or may even become inconsistent)
352 if (off && off < deq.size ())
353 exceptions = 0;
354
355 // format a string describing the function call being exercised
356 // (used in diagnostic output below)
357 char* funcall = 0;
358 std::size_t len = 0;
359
360 static const int cwidth = sizeof (*xseq);
361
362 rw_asnprintf (&funcall, &len, "deque(\"%{X=*.*}\").insert("
363 "%{?}begin(), %{:}%{?}end (), %{:}begin () + %zu%{;}%{;}"
364 "%{?}%d)%{:}%{?}\"%{X=*.*}\")%{:}%d, %d)%{;}%{;}",
365 cwidth, int (seqlen), -1, xseq, 0 == off, seqlen == off,
366 off, nelems == -2, *ins, nelems == -1,
367 cwidth, int (inslen), -1, xins, nelems, *ins);
368
369 std::size_t n_copy = UserClass::n_total_copy_ctor_;
370 std::size_t n_asgn = UserClass::n_total_op_assign_;
371
372 if (-2 == nelems) { // insert(iterator, const_reference)
373
374 exception_loop (line, Insert_1, funcall, exceptions,
375 deq, iter, nelems, xins, dummy, dummy,
376 &n_copy, &n_asgn);
377
378 }
379 else if (-1 == nelems) { // insert(iterator, Iterator, Iterator)
380
381 if (inslen > 1)
382 exceptions = 0;
383
384 const Iterator first =
385 make_iter (xins, xins, xins + inslen, dummy);
386
387 const Iterator last =
388 make_iter (xins + inslen, xins, xins + inslen, dummy);
389
390 exception_loop (line, InsertRange, funcall, exceptions,
391 deq, iter, nelems, 0, first, last,
392 &n_copy, &n_asgn);
393
394 }
395 else { // insert(iterator, size_type, const_reference)
396
397 if (nelems > 1)
398 exceptions = 0;
399
400 exception_loop (line, Insert_n, funcall, exceptions,
401 deq, iter, nelems, xins, dummy, dummy,
402 &n_copy, &n_asgn);
403
404 }
405
406 // verify the expected size of the deque after insertion
407 rw_assert (deq.size () == reslen, __FILE__, line,
408 "line %d: %s: size == %zu, got %zu\n",
409 __LINE__, funcall, reslen, deq.size ());
410
411 // verify the expected contents of the deque after insertion
412 const Deque::const_iterator resbeg = deq.begin ();
413 const Deque::const_iterator resend = deq.end ();
414
415 for (Deque::const_iterator it = resbeg; it != resend; ++it) {
416 if ((*it).data_.val_ != UChar (res [it - resbeg])) {
417
418 char* const got = new char [deq.size () + 1];
419
420 for (Deque::const_iterator i = resbeg; i != resend; ++i) {
421 got [i - resbeg] = char ((*i).data_.val_);
422 }
423
424 got [deq.size ()] = '\0';
425
426 rw_assert (false, __FILE__, line,
427 "line %d: %s: expected %s, got %s\n",
428 __LINE__, funcall, res, got);
429
430 delete[] got;
431 break;
432 }
433 }
434
435 // verify the complexity of the operation in terms of the number
436 // of calls to the copy ctor and assignment operator on value_type
437 const std::size_t expect_copy = nelems < 0 ? inslen : nelems;
438
439 rw_assert (n_copy == expect_copy, __FILE__, line,
440 "line %d: %s: expected %zu invocations "
441 "of UserClass::UserClass(const UserClass&), got %d\n",
442 __LINE__, funcall, expect_copy, n_copy);
443
444 // compute the number of calls to the assignment operator
445 const std::size_t expect_asgn =
446 insert_assignments (dummy, nelems, off, seqlen, inslen);
447
448 rw_assert (n_asgn == expect_asgn, __FILE__, line,
449 "line %d: %s: expected %zu invocations "
450 "of UserClass::operator=(const UserClass&), got %d\n",
451 __LINE__, funcall, expect_asgn, n_asgn);
452
453 // Free funcall storage
454 std::free (funcall);
455
456 delete[] xins;
457
458 // cast away constness to work around an HP aCC 6.16 bug
459 // see http://issues.apache.org/jira/browse/STDCXX-802
460 delete[] _RWSTD_CONST_CAST (UserClass*, xseq);
461}
462
463
465template <class Iterator>
466void test_insert_range (const Iterator &it, const char* itname)
467{
468 rw_info (0, 0 ,0,
469 "std::deque<UserClass>::insert(iterator, %s, %s)", itname, itname);
470
471#undef TEST
472#define TEST(seq, off, ins, res) \
473 test_insert (__LINE__, -1, \
474 it, -1, \
475 seq, sizeof seq - 1, \
476 std::size_t (off), \
477 ins, sizeof ins - 1, \
478 res, sizeof res - 1)
479
480 // +---------------------------------------- seq
481 // | +--------------------------------- off
482 // | | +----------------------------- ins
483 // | | | +---------------------- res
484 // | | | |
485 // v v v v
486 TEST ("", +0, "", "");
487 TEST ("", +0, "a", "a");
488 TEST ("", +0, "ab", "ab");
489 TEST ("", +0, "abc", "abc");
490 TEST ("a", +0, "", "a");
491 TEST ("b", +0, "a", "ab");
492 TEST ("c", +0, "ab", "abc");
493 TEST ("cd", +0, "ab", "abcd");
494 TEST ("def", +0, "abc", "abcdef");
495
496 TEST ("a", +1, "", "a");
497 TEST ("a", +1, "b", "ab");
498 TEST ("a", +1, "bc", "abc");
499 TEST ("a", +1, "bcd", "abcd");
500
501 TEST ("ab", +1, "", "ab");
502 TEST ("ac", +1, "b", "abc");
503 TEST ("acd", +1, "b", "abcd");
504
505 TEST ("ab", +2, "", "ab");
506 TEST ("ab", +2, "c", "abc");
507 TEST ("ab", +2, "cd", "abcd");
508
509 TEST ("abc", +2, "", "abc");
510 TEST ("abd", +2, "c", "abcd");
511 TEST ("abe", +2, "cd", "abcde");
512 TEST ("abf", +2, "cde", "abcdef");
513
514 TEST ("abc", +3, "", "abc");
515 TEST ("abc", +3, "d", "abcd");
516 TEST ("abc", +3, "de", "abcde");
517 TEST ("abc", +3, "def", "abcdef");
518
519
520#define UPPER "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
521#define LOWER "abcdefghijklmnopqrstuvwxyz"
522
523 TEST (UPPER, +0, LOWER, "" LOWER "ABCDEFGHIJKLMNOPQRSTUVWXYZ");
524 TEST (UPPER, +1, LOWER, "A" LOWER "BCDEFGHIJKLMNOPQRSTUVWXYZ");
525 TEST (UPPER, +2, LOWER, "AB" LOWER "CDEFGHIJKLMNOPQRSTUVWXYZ");
526 TEST (UPPER, +3, LOWER, "ABC" LOWER "DEFGHIJKLMNOPQRSTUVWXYZ");
527 TEST (UPPER, +4, LOWER, "ABCD" LOWER "EFGHIJKLMNOPQRSTUVWXYZ");
528 TEST (UPPER, +5, LOWER, "ABCDE" LOWER "FGHIJKLMNOPQRSTUVWXYZ");
529 TEST (UPPER, +6, LOWER, "ABCDEF" LOWER "GHIJKLMNOPQRSTUVWXYZ");
530 TEST (UPPER, +7, LOWER, "ABCDEFG" LOWER "HIJKLMNOPQRSTUVWXYZ");
531 TEST (UPPER, +8, LOWER, "ABCDEFGH" LOWER "IJKLMNOPQRSTUVWXYZ");
532 TEST (UPPER, +9, LOWER, "ABCDEFGHI" LOWER "JKLMNOPQRSTUVWXYZ");
533 TEST (UPPER, +10, LOWER, "ABCDEFGHIJ" LOWER "KLMNOPQRSTUVWXYZ");
534 TEST (UPPER, +11, LOWER, "ABCDEFGHIJK" LOWER "LMNOPQRSTUVWXYZ");
535 TEST (UPPER, +12, LOWER, "ABCDEFGHIJKL" LOWER "MNOPQRSTUVWXYZ");
536 TEST (UPPER, +13, LOWER, "ABCDEFGHIJKLM" LOWER "NOPQRSTUVWXYZ");
537 TEST (UPPER, +14, LOWER, "ABCDEFGHIJKLMN" LOWER "OPQRSTUVWXYZ");
538 TEST (UPPER, +15, LOWER, "ABCDEFGHIJKLMNO" LOWER "PQRSTUVWXYZ");
539 TEST (UPPER, +16, LOWER, "ABCDEFGHIJKLMNOP" LOWER "QRSTUVWXYZ");
540 TEST (UPPER, +17, LOWER, "ABCDEFGHIJKLMNOPQ" LOWER "RSTUVWXYZ");
541 TEST (UPPER, +18, LOWER, "ABCDEFGHIJKLMNOPQR" LOWER "STUVWXYZ");
542 TEST (UPPER, +19, LOWER, "ABCDEFGHIJKLMNOPQRS" LOWER "TUVWXYZ");
543 TEST (UPPER, +20, LOWER, "ABCDEFGHIJKLMNOPQRST" LOWER "UVWXYZ");
544 TEST (UPPER, +21, LOWER, "ABCDEFGHIJKLMNOPQRSTU" LOWER "VWXYZ");
545 TEST (UPPER, +22, LOWER, "ABCDEFGHIJKLMNOPQRSTUV" LOWER "WXYZ");
546 TEST (UPPER, +23, LOWER, "ABCDEFGHIJKLMNOPQRSTUVW" LOWER "XYZ");
547 TEST (UPPER, +24, LOWER, "ABCDEFGHIJKLMNOPQRSTUVWX" LOWER "YZ");
548 TEST (UPPER, +25, LOWER, "ABCDEFGHIJKLMNOPQRSTUVWXY" LOWER "Z");
549 TEST (UPPER, +26, LOWER, "ABCDEFGHIJKLMNOPQRSTUVWXYZ" LOWER "");
550}
551
552
554template <class T, class IntType>
555void test_insert_int_range (const T&, const IntType&,
556 const char* t_name, const char* int_name)
557{
558 rw_info (0, 0, 0,
559 "std::deque<%s>::insert(iterator, %s, %s)",
560 t_name, int_name, int_name);
561
562 std::deque<T> d;
563
564 typename std::deque<T>::iterator it = d.begin ();
565
566 // deque<T>::insert(iterator, size_type, const_reference)
567
568 d.insert (it, IntType (1), IntType (0));
569
570 rw_assert (1 == d.size (), 0, __LINE__,
571 "deque<%s>::insert(begin(), %s = 1, %s = 0); size() == 1,"
572 " got %zu", t_name, int_name, int_name, d.size ());
573
574 it = d.begin ();
575 ++it;
576
577 d.insert (it, IntType (3), IntType (2));
578
579 rw_assert (4 == d.size (), 0, __LINE__,
580 "deque<%s>::insert(begin() + 1, %s = 3, %s = 2); size() == 4,"
581 " got %zu", t_name, int_name, int_name, d.size ());
582
583 it = d.begin ();
584 ++it;
585
586 d.insert (it, IntType (2), IntType (1));
587
588 rw_assert (6 == d.size (), 0, __LINE__,
589 "deque<%s>::insert(begin() + 1, %s = 2, %s = 1); size() == 6,"
590 " got %zu", t_name, int_name, int_name, d.size ());
591}
592
593
594template <class T>
595void test_insert_int_range (const T &dummy, const char* tname)
596{
597 test_insert_int_range (dummy, (signed char)0, tname, "signed char");
598 test_insert_int_range (dummy, (unsigned char)0, tname, "unsigned char");
599 test_insert_int_range (dummy, short (), tname, "short");
600 test_insert_int_range (dummy, (unsigned short)0, tname, "unsigned short");
601 test_insert_int_range (dummy, int (), tname, "int");
602 test_insert_int_range (dummy, (unsigned int)0, tname, "unsigned int");
603 test_insert_int_range (dummy, long (), tname, "long");
604 test_insert_int_range (dummy, (unsigned long)0, tname, "unsigned long");
605
606#ifdef _RWSTD_LONG_LONG
607
609 tname, "long long");
610 test_insert_int_range (dummy, (unsigned _RWSTD_LONG_LONG)0,
611 tname, "unsigned long long");
612
613#endif // _RWSTD_LONG_LONG
614
615}
616
617
620{
622 // exercise deque::insert(iterator, const_reference)
623
624 rw_info (0, 0, 0,
625 "std::deque<UserClass>::insert(iterator, const_reference)");
626
627#undef TEST
628#define TEST(seq, off, ins, res) do { \
629 const char insseq [] = { ins, '\0' }; \
630 test_insert (__LINE__, -1, \
631 (UserClass*)0, -2, \
632 seq, sizeof seq - 1, \
633 std::size_t (off), \
634 insseq, 1, \
635 res, sizeof res - 1); \
636 } while (0)
637
638 // +------------------- original sequence
639 // | +----------- insertion offset
640 // | | +------ element to insert
641 // | | | +-- resulting sequence
642 // | | | |
643 // V V V V
644 TEST ("", +0, 'a', "a");
645 TEST ("b", +0, 'a', "ab");
646 TEST ("bc", +0, 'a', "abc");
647 TEST ("bcd", +0, 'a', "abcd");
648 TEST ("bcde", +0, 'a', "abcde");
649
650 TEST ("a", +1, 'b', "ab");
651 TEST ("ac", +1, 'b', "abc");
652 TEST ("acd", +1, 'b', "abcd");
653 TEST ("acde", +1, 'b', "abcde");
654
655 TEST ("ab", +2, 'c', "abc");
656 TEST ("abd", +2, 'c', "abcd");
657 TEST ("abde", +2, 'c', "abcde");
658
659 TEST ("abc", +3, 'd', "abcd");
660 TEST ("abce", +3, 'd', "abcde");
661
662 TEST ("abcd", +4, 'e', "abcde");
663
664#define A_to_B "AB"
665#define A_to_C "ABC"
666#define A_to_D "ABCD"
667#define A_to_E "ABCDE"
668#define A_to_F "ABCDEF"
669#define A_to_G "ABCDEFG"
670#define A_to_H "ABCDEFGH"
671#define A_to_I "ABCDEFGHI"
672#define A_to_J "ABCDEFGHIJ"
673#define A_to_K "ABCDEFGHIJK"
674#define A_to_L "ABCDEFGHIJKL"
675#define A_to_M "ABCDEFGHIJKLM"
676#define A_to_N "ABCDEFGHIJKLMN"
677#define A_to_O "ABCDEFGHIJKLMNO"
678#define A_to_P "ABCDEFGHIJKLMNOP"
679#define A_to_Q "ABCDEFGHIJKLMNOPQ"
680#define A_to_R "ABCDEFGHIJKLMNOPQR"
681#define A_to_S "ABCDEFGHIJKLMNOPQRS"
682#define A_to_T "ABCDEFGHIJKLMNOPQRST"
683#define A_to_U "ABCDEFGHIJKLMNOPQRSTU"
684#define A_to_V "ABCDEFGHIJKLMNOPQRSTUV"
685#define A_to_W "ABCDEFGHIJKLMNOPQRSTUVW"
686#define A_to_X "ABCDEFGHIJKLMNOPQRSTUVWX"
687#define A_to_Y "ABCDEFGHIJKLMNOPQRSTUVWXY"
688#define A_to_Z "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
689#define B_to_Z "BCDEFGHIJKLMNOPQRSTUVWXYZ"
690#define C_to_Z "CDEFGHIJKLMNOPQRSTUVWXYZ"
691#define D_to_Z "DEFGHIJKLMNOPQRSTUVWXYZ"
692#define E_to_Z "EFGHIJKLMNOPQRSTUVWXYZ"
693#define F_to_Z "FGHIJKLMNOPQRSTUVWXYZ"
694#define G_to_Z "GHIJKLMNOPQRSTUVWXYZ"
695#define H_to_Z "HIJKLMNOPQRSTUVWXYZ"
696#define I_to_Z "IJKLMNOPQRSTUVWXYZ"
697#define J_to_Z "JKLMNOPQRSTUVWXYZ"
698#define K_to_Z "KLMNOPQRSTUVWXYZ"
699#define L_to_Z "LMNOPQRSTUVWXYZ"
700#define M_to_Z "MNOPQRSTUVWXYZ"
701#define N_to_Z "NOPQRSTUVWXYZ"
702#define O_to_Z "OPQRSTUVWXYZ"
703#define P_to_Z "PQRSTUVWXYZ"
704#define Q_to_Z "QRSTUVWXYZ"
705#define R_to_Z "RSTUVWXYZ"
706#define S_to_Z "STUVWXYZ"
707#define T_to_Z "TUVWXYZ"
708#define U_to_Z "UVWXYZ"
709#define V_to_Z "VWXYZ"
710#define W_to_Z "WXYZ"
711#define X_to_Z "XYZ"
712#define Y_to_Z "YZ"
713
714 TEST (A_to_Z, + 0, '^', "" "^" A_to_Z);
715 TEST (A_to_Z, + 1, '^', "A" "^" B_to_Z);
716 TEST (A_to_Z, + 2, '^', A_to_B "^" C_to_Z);
717 TEST (A_to_Z, + 3, '^', A_to_C "^" D_to_Z);
718 TEST (A_to_Z, + 4, '^', A_to_D "^" E_to_Z);
719 TEST (A_to_Z, + 5, '^', A_to_E "^" F_to_Z);
720 TEST (A_to_Z, + 6, '^', A_to_F "^" G_to_Z);
721 TEST (A_to_Z, + 7, '^', A_to_G "^" H_to_Z);
722 TEST (A_to_Z, + 8, '^', A_to_H "^" I_to_Z);
723 TEST (A_to_Z, + 9, '^', A_to_I "^" J_to_Z);
724 TEST (A_to_Z, +10, '^', A_to_J "^" K_to_Z);
725 TEST (A_to_Z, +11, '^', A_to_K "^" L_to_Z);
726 TEST (A_to_Z, +12, '^', A_to_L "^" M_to_Z);
727 TEST (A_to_Z, +13, '^', A_to_M "^" N_to_Z);
728 TEST (A_to_Z, +14, '^', A_to_N "^" O_to_Z);
729 TEST (A_to_Z, +15, '^', A_to_O "^" P_to_Z);
730 TEST (A_to_Z, +16, '^', A_to_P "^" Q_to_Z);
731 TEST (A_to_Z, +17, '^', A_to_Q "^" R_to_Z);
732 TEST (A_to_Z, +18, '^', A_to_R "^" S_to_Z);
733 TEST (A_to_Z, +19, '^', A_to_S "^" T_to_Z);
734 TEST (A_to_Z, +20, '^', A_to_T "^" U_to_Z);
735 TEST (A_to_Z, +21, '^', A_to_U "^" V_to_Z);
736 TEST (A_to_Z, +22, '^', A_to_V "^" W_to_Z);
737 TEST (A_to_Z, +23, '^', A_to_W "^" X_to_Z);
738 TEST (A_to_Z, +24, '^', A_to_X "^" Y_to_Z);
739 TEST (A_to_Z, +25, '^', A_to_Y "^" "Z");
740 TEST (A_to_Z, +26, '^', A_to_Z "^" "");
741
743 // exercise deque::insert(iterator, size_type, const_reference)
744
745 rw_info (0, 0, 0,
746 "std::deque<UserClass>::insert(iterator, size_type, "
747 "const_reference)");
748
749#undef TEST
750#define TEST(seq, off, n, ins, res) do { \
751 const char insseq [] = { ins, '\0' }; \
752 test_insert (__LINE__, -1, \
753 (UserClass*)0, n, \
754 seq, sizeof seq - 1, \
755 std::size_t (off), \
756 insseq, 1, \
757 res, sizeof res - 1); \
758 } while (0)
759
760 TEST ("", +0, 0, 'a', "");
761 TEST ("", +0, 1, 'a', "a");
762 TEST ("", +0, 2, 'b', "bb");
763 TEST ("", +0, 3, 'c', "ccc");
764
765 TEST ("a", +0, 0, 'a', "a");
766 TEST ("b", +0, 1, 'a', "ab");
767 TEST ("b", +0, 2, 'a', "aab");
768 TEST ("b", +0, 3, 'a', "aaab");
769
770 TEST ("ab", +1, 0, 'b', "ab");
771 TEST ("ac", +1, 1, 'b', "abc");
772 TEST ("ac", +1, 2, 'b', "abbc");
773 TEST ("ac", +1, 3, 'b', "abbbc");
774
775 TEST ("abcd", +2, 0, 'c', "abcd");
776 TEST ("abde", +2, 1, 'c', "abcde");
777 TEST ("abde", +2, 2, 'c', "abccde");
778 TEST ("abde", +2, 3, 'c', "abcccde");
779
781 // exercise deque::insert(iterator, InputIterator, InputIterator)
782
783 rw_info (0, 0, 0,
784 "template <class InputIterator> std::deque<UserClass>::"
785 "insert(iterator, InputIterator, InputIterator)");
786
789 "InputIter<UserClass>");
790 else
791 rw_note (0, 0, __LINE__,
792 "template <class T> "
793 "std::deque<UserClass>::insert(iterator, T, T) "
794 "[with T = InputIterator] test disabled.");
795
797 test_insert_range (FwdIter<UserClass>(), "FwdIter<UserClass>");
798 else
799 rw_note (0, 0, __LINE__,
800 "template <class T> "
801 "std::deque<UserClass>::insert(iterator, T, T) "
802 "[with T = ForwardIterator] test disabled.");
803
805 test_insert_range (BidirIter<UserClass>(), "BidirIter<UserClass>");
806 else
807 rw_note (0, 0, __LINE__,
808 "template <class T> "
809 "std::deque<UserClass>::insert(iterator, T, T) "
810 "[with T = BidirectionalIterator] test disabled.");
811
814 "RandomAccessIter<UserClass>");
815 else
816 rw_note (0, 0, __LINE__,
817 "template <class T> "
818 "std::deque<UserClass>::insert(iterator, T, T) "
819 "[with T = RandomAccessIterator] test disabled.");
820
822 // exercise deque::insert(iterator, int, int)
823
824 rw_info (0, 0, 0,
825 "template <class IntType> "
826 "std::deque<IntType>::"
827 "insert(iterator, IntType, IntType)");
828
829 if (0 == rw_opt_no_right_thing) {
830 test_insert_int_range ((signed char)0, "signed char");
831 test_insert_int_range ((unsigned char)0, "unsigned char");
832 test_insert_int_range (short (), "short");
833 test_insert_int_range ((unsigned short)0, "unsigned short");
834 test_insert_int_range (int (), "int");
835 test_insert_int_range ((unsigned int)0, "unsigned int");
836 test_insert_int_range (long (), "long");
837 test_insert_int_range ((unsigned long)0, "unsigned long");
838
839#ifdef _RWSTD_LONG_LONG
840
842 "long long");
844 "unsigned long long");
845
846#endif // _RWSTD_LONG_LONG
847 }
848 else
849 rw_note (0, 0, __LINE__,
850 "template <class T> "
851 "std::deque<UserClass>::insert(iterator, T, T) "
852 "[with T = IntegralType] tests disabled.");
853
854}
855
856
858template <class Iterator>
859void test_assign (int line, int exceptions,
860 const Iterator &dummy, int nelems,
861 const char *seq, std::size_t seqlen,
862 const char *asn, std::size_t asnlen,
863 const char *res, std::size_t reslen)
864{
865 const UserClass* const xseq = UserClass::from_char (seq, seqlen + 1);
866 UserClass* const xasn = UserClass::from_char (asn, asnlen + 1);
867
868 Deque deq = seqlen ? Deque (xseq, xseq + seqlen) : Deque ();
869
870 // format a string describing the function call being exercised
871 // (used in diagnostic output below)
872 char* funcall = 0;
873 std::size_t len = 0;
874
875 static const int cwidth = sizeof (*xseq);
876
877 rw_asnprintf (&funcall, &len,
878 "deque(\"%{X=*.*}\").assign("
879 "%{?}\"%{X=*.*}\")%{:}%d, %d)%{;}",
880 cwidth, seqlen, -1, xseq,
881 nelems < 0,
882 cwidth, asnlen, -1, xasn,
883 nelems, *asn);
884
885 std::size_t n_copy = UserClass::n_total_copy_ctor_;
886 std::size_t n_asgn = UserClass::n_total_op_assign_;
887
888 // create a dummy deque iterator to pass to exception_loop
889 // (the object will not be used by the functiuon)
890 const Deque::iterator dummy_it = deq.begin ();
891
892 if (nelems < 0) { // assign(Iterator, Iterator)
893
894 if (asnlen > 1)
895 exceptions = 0;
896
897 const Iterator first =
898 make_iter (xasn, xasn, xasn + asnlen, dummy);
899
900 const Iterator last =
901 make_iter (xasn + asnlen, xasn, xasn + asnlen, dummy);
902
903 exception_loop (line, AssignRange, funcall, exceptions,
904 deq, dummy_it, nelems, 0, first, last,
905 &n_copy, &n_asgn);
906 }
907 else { // assign(size_type, const_reference)
908 if (nelems > 1)
909 exceptions = 0;
910
911 exception_loop (line, Assign_n, funcall, exceptions,
912 deq, dummy_it, nelems, xasn, dummy, dummy,
913 &n_copy, &n_asgn);
914 }
915
916 // verify the expected size of the deque after assignment
917 rw_assert (deq.size () == reslen, 0, line,
918 "line %d: %s: size == %zu, got %zu\n",
919 __LINE__, funcall, reslen, deq.size ());
920
921 // verify the expected contents of the deque after assignment
922 const Deque::const_iterator resbeg = deq.begin ();
923 const Deque::const_iterator resend = deq.end ();
924
925 for (Deque::const_iterator it = resbeg; it != resend; ++it) {
926
927 const Deque::size_type inx = it - resbeg;
928
929 _RWSTD_ASSERT (inx < deq.size ());
930
931 if ((*it).data_.val_ != UChar (res [inx])) {
932
933 char* const got = new char [deq.size () + 1];
934
935 for (Deque::const_iterator i = resbeg; i != resend; ++i) {
936
937 const Deque::size_type inx_2 = i - resbeg;
938
939 _RWSTD_ASSERT (inx_2 < deq.size ());
940
941 got [inx_2] = char ((*i).data_.val_);
942 }
943
944 got [deq.size ()] = '\0';
945
946 rw_assert (false, 0, line,
947 "line %d: %s: expected %s, got %s\n",
948 __LINE__, funcall, res, got);
949
950 delete[] got;
951 break;
952 }
953 }
954
955 // set asnlen to the number of elements assigned to the container
956 if (0 <= nelems)
957 asnlen = std::size_t (nelems);
958
959 // verify the complexity of the operation in terms of the number
960 // of calls to the copy ctor and assignment operator on value_type
961
962 // the number of invocations of the copy ctor and the assignment
963 // operator depends on whether the implementation of assign()
964 // strictly follows the requirements in 23.2.1.1, p7 or p8 and
965 // destroys the existing elements before inserting the new ones,
966 // or whether it assigns the new elements over the existing ones
967
968#ifndef _RWSTD_NO_EXT_DEQUE_ASSIGN_IN_PLACE
969 const std::size_t expect_copy = seqlen < asnlen ? asnlen - seqlen : 0;
970 const std::size_t expect_asgn = asnlen < seqlen ? asnlen : seqlen;
971#else // if defined (_RWSTD_NO_EXT_DEQUE_ASSIGN_IN_PLACE)
972 const std::size_t expect_copy = asnlen;
973 const std::size_t expect_asgn = 0;
974#endif // _RWSTD_NO_EXT_DEQUE_ASSIGN_IN_PLACE
975
976 rw_assert (n_copy == expect_copy, __FILE__, line,
977 "line %d: %s: expected %zu invocations "
978 "of UserClass::UserClass(const UserClass&), got %d\n",
979 __LINE__, funcall, expect_copy, n_copy);
980
981 rw_assert (n_asgn == expect_asgn, __FILE__, line,
982 "line %d: %s: expected %zu invocations "
983 "of UserClass::operator=(const UserClass&), got %d\n",
984 __LINE__, funcall, expect_asgn, n_asgn);
985
986 // Free funcall storage
987 std::free (funcall);
988
989 delete[] xasn;
990
991 // cast away constness to work around an HP aCC 6.16 bug
992 // see http://issues.apache.org/jira/browse/STDCXX-802
993 delete[] _RWSTD_CONST_CAST (UserClass*, xseq);
994}
995
996
997template <class Iterator>
998void test_assign_range (const Iterator &it, const char* itname)
999{
1000 rw_info (0, 0, 0, "std::deque<UserClass>::assign(%s, %s)", itname, itname);
1001
1002 static const char seq[] = "abcdefghijklmnopqrstuvwxyz";
1003 static const char asn[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
1004
1005 for (std::size_t i = 0; i != sizeof seq - 1; ++i) {
1006 for (std::size_t j = 0; j != sizeof asn - 1; ++j) {
1007
1008 test_assign (__LINE__, 0, it, -1, seq, i, asn, j, asn, j);
1009 }
1010 }
1011}
1012
1013
1015{
1017 // exercise
1018 // deque::assign(size_type, const_reference)
1019
1020 rw_info (0, 0, 0,
1021 "std::deque<UserClass>::assign(size_type, const_reference)");
1022
1023 static const char seq[] = "abcdefghijklmnopqrstuvwxyz";
1024 static const char res[] = "AAAAAAAAAAAAAAAAAAAAAAAAAA";
1025
1026 for (std::size_t i = 0; i != sizeof seq - 1; ++i) {
1027 for (std::size_t j = 0; j != sizeof seq - 1; ++j) {
1028
1029 test_assign (__LINE__, -1, (UserClass*)0, int (j),
1030 seq, i, res, 1U, res, j);
1031 }
1032 }
1033
1035 // exercise
1036 // template <class InputIterator>
1037 // deque::assign(InputIterator, InputIterator)
1038
1039 rw_info (0, 0, 0,
1040 "template <class InputIterator> "
1041 "std::deque<UserClass>::assign(InputIterator, InputIterator)");
1042
1043 if (0 == rw_opt_no_input_iterator)
1045 "InputIter<UserClass>");
1046 else
1047 rw_note (0, 0, __LINE__,
1048 "template <class T> "
1049 "std::deque<UserClass>::assign(T, T) [with T = InputIterator]"
1050 "test disabled.");
1051
1053 test_assign_range (FwdIter<UserClass>(), "FwdIter<UserClass>");
1054 else
1055 rw_note (0, 0, __LINE__,
1056 "template <class T> "
1057 "std::deque<UserClass>::assign(T, T) "
1058 "[with T = ForwardIterator] test disabled.");
1059
1061 test_assign_range (BidirIter<UserClass>(), "BidirIter<UserClass>");
1062 else
1063 rw_note (0, 0, __LINE__,
1064 "template <class T> "
1065 "std::deque<UserClass>::assign(T, T) "
1066 "[with T = BidirectionalIterator] test disabled.");
1067
1070 "RandomAccessIter<UserClass>");
1071 else
1072 rw_note (0, 0, __LINE__,
1073 "template <class T> "
1074 "std::deque<UserClass>::assign(T, T) "
1075 "[with T = RandomAccessIterator] test disabled.");
1076}
1077
1078
1081 const char *seq, std::size_t seqlen,
1082 std::size_t begoff, std::size_t len,
1083 const char *res, std::size_t reslen)
1084{
1085 const UserClass* const xseq = UserClass::from_char (seq, seqlen + 1);
1086
1087 Deque deq = seqlen ? Deque (xseq, xseq + seqlen) : Deque ();
1088 const Deque::iterator start = deq.begin () + begoff;
1089
1090 std::size_t n_copy = UserClass::n_total_copy_ctor_;
1091 std::size_t n_asgn = UserClass::n_total_op_assign_;
1092
1093 char* funcall = 0;
1094 std::size_t buflen = 0;
1095
1096 static const int cwidth = sizeof (*xseq);
1097
1098 if (std::size_t (-1) == len) { // erase(iterator)
1099
1100 rw_asnprintf (&funcall, &buflen,
1101 "deque(\"%{X=*.*}\").erase(%{?}end()%{:}"
1102 "%{?}begin () + %zu%{:}begin ()%{;}%{;}",
1103 cwidth, seqlen, -1, xseq,
1104 begoff == deq.size (), begoff, begoff);
1105
1106 exception_loop (line, Erase_1, funcall, 0,
1107 deq, start, 1, 0, (UserClass*)0, (UserClass*)0,
1108 &n_copy, &n_asgn);
1109 }
1110 else { // assign(size_type, const_reference)
1111
1112 const Deque::iterator end = start + len;
1113
1114 rw_asnprintf (&funcall, &buflen,
1115 "deque(\"%{X=*.*}\").erase(%{?}end()%{:}"
1116 "%{?}begin () + %zu%{:}begin ()%{;}%{;}"
1117 "%{?})%{:}%{?}, end ())%{:}%{?}, begin ())"
1118 "%{:}begin () + %zu%{;}%{;}%{;}",
1119 cwidth, seqlen, -1, xseq,
1120 begoff == deq.size (), begoff, begoff,
1121 std::size_t (-1) == len,
1122 end == deq.end (),
1123 end == deq.begin (),
1124 end - deq.begin ());
1125
1126 exception_loop (line, EraseRange, funcall, 0,
1127 deq, start, int (len), 0,
1128 (UserClass*)0, (UserClass*)0,
1129 &n_copy, &n_asgn);
1130
1131 }
1132
1133 // verify the expected size of the deque after erasure
1134 rw_assert (deq.size () == reslen, 0, line,
1135 "line %d: %s: size == %zu, got %zu\n",
1136 __LINE__, funcall, reslen, deq.size ());
1137
1138 // verify the expected contents of the deque after assignment
1139 const Deque::const_iterator resbeg = deq.begin ();
1140 const Deque::const_iterator resend = deq.end ();
1141
1142 for (Deque::const_iterator it = resbeg; it != resend; ++it) {
1143 if ((*it).data_.val_ != UChar (res [it - resbeg])) {
1144
1145 char* const got = new char [deq.size () + 1];
1146
1147 for (Deque::const_iterator i = resbeg; i != resend; ++i) {
1148 got [i - resbeg] = char ((*i).data_.val_);
1149 }
1150
1151 got [deq.size ()] = '\0';
1152
1153 rw_assert (false, 0, line,
1154 "line %d: %s: expected %s, got %s\n",
1155 __LINE__, funcall, res, got);
1156
1157 delete[] got;
1158 break;
1159 }
1160 }
1161
1162#if 0
1163 // set asnlen to the number of elements assigned to the container
1164 if (0 <= nelems)
1165 asnlen = std::size_t (nelems);
1166
1167 // verify the complexity of the operation in terms of the number
1168 // of calls to the copy ctor and assignment operator on value_type
1169
1170 // the number of invocations of the copy ctor and the assignment
1171 // operator depends on whether the implementation of assign()
1172 // strictly follows the requirements in 23.2.1.1, p7 or p8 and
1173 // destroys the existing elements before inserting the new ones,
1174 // or whether it assigns the new elements over the existing ones
1175
1176#ifndef _RWSTD_NO_EXT_DEQUE_ASSIGN_IN_PLACE
1177 const std::size_t expect_copy = seqlen < asnlen ? asnlen - seqlen : 0;
1178 const std::size_t expect_asgn = asnlen < seqlen ? asnlen : seqlen;
1179#else // if defined (_RWSTD_NO_EXT_DEQUE_ASSIGN_IN_PLACE)
1180 const std::size_t expect_copy = asnlen;
1181 const std::size_t expect_asgn = 0;
1182#endif // _RWSTD_NO_EXT_DEQUE_ASSIGN_IN_PLACE
1183
1184 rw_assert (n_copy == int (expect_copy), 0, line,
1185 "line %d: %s: expected %zu invocations "
1186 "of UserClass::UserClass(const UserClass&), got %d\n",
1187 __LINE__, funcall, expect_copy, n_copy);
1188
1189 rw_assert (n_asgn == int (expect_asgn), 0, line,
1190 "line %d: %s: expected %zu invocations "
1191 "of UserClass::operator=(const UserClass&), got %d\n",
1192 __LINE__, funcall, expect_asgn, n_asgn);
1193#endif
1194
1195 std::free (funcall);
1196
1197 // cast away constness to work around an HP aCC 6.16 bug
1198 // see http://issues.apache.org/jira/browse/STDCXX-802
1199 delete[] _RWSTD_CONST_CAST (UserClass*, xseq);
1200}
1201
1203{
1205 // exercise deque::erase(iterator)
1206
1207 rw_info (0, 0, 0, "std::deque<UserClass>::erase(iterator)");
1208
1209#undef TEST
1210#define TEST(seq, off, res) do { \
1211 test_erase (__LINE__, \
1212 seq, sizeof seq - 1, \
1213 std::size_t (off), \
1214 std::size_t (-1), \
1215 res, sizeof res - 1); \
1216 } while (0)
1217
1218 TEST ("a", 0, "");
1219
1220 TEST ("ab", 0, "b");
1221 TEST ("ab", 1, "a");
1222
1223 TEST ("abc", 0, "bc");
1224 TEST ("abc", 1, "ac");
1225 TEST ("abc", 2, "ab");
1226
1227 TEST ("abcd", 0, "bcd");
1228 TEST ("abcd", 1, "acd");
1229 TEST ("abcd", 2, "abd");
1230 TEST ("abcd", 3, "abc");
1231
1232 TEST ("abcde", 0, "bcde");
1233 TEST ("abcde", 1, "acde");
1234 TEST ("abcde", 2, "abde");
1235 TEST ("abcde", 3, "abce");
1236 TEST ("abcde", 4, "abcd");
1237
1238 TEST ("abcdef", 0, "bcdef");
1239 TEST ("abcdef", 1, "acdef");
1240 TEST ("abcdef", 2, "abdef");
1241 TEST ("abcdef", 3, "abcef");
1242 TEST ("abcdef", 4, "abcdf");
1243 TEST ("abcdef", 5, "abcde");
1244
1245 TEST ("abcdefg", 0, "bcdefg");
1246 TEST ("abcdefg", 1, "acdefg");
1247 TEST ("abcdefg", 2, "abdefg");
1248 TEST ("abcdefg", 3, "abcefg");
1249 TEST ("abcdefg", 4, "abcdfg");
1250 TEST ("abcdefg", 5, "abcdeg");
1251 TEST ("abcdefg", 6, "abcdef");
1252
1253 TEST ("abcdefgh", 0, "bcdefgh");
1254 TEST ("abcdefgh", 1, "acdefgh");
1255 TEST ("abcdefgh", 2, "abdefgh");
1256 TEST ("abcdefgh", 3, "abcefgh");
1257 TEST ("abcdefgh", 4, "abcdfgh");
1258 TEST ("abcdefgh", 5, "abcdegh");
1259 TEST ("abcdefgh", 6, "abcdefh");
1260 TEST ("abcdefgh", 7, "abcdefg");
1261
1263 // exercise deque::erase(iterator, iterator)
1264
1265 rw_info (0, 0, 0, "std::deque<UserClass>::erase(iterator, iterator)");
1266}
1267
1268
1270#if !defined (_MSC_VER) || _MSC_VER > 1200
1271
1273{
1274 static bool cast_used;
1275
1276 DR_438 () { }
1277
1278 explicit DR_438 (std::size_t) { cast_used = true; }
1279
1280 template <class T> DR_438 (T) { }
1281};
1282
1284
1285#else // if MSVC <= 6.0
1286 // avoid an MSVC 6.0 ICE on this code
1287# define NO_DR_438_TEST "this version of MSVC is too broken"
1288#endif // !MSVC || MSVC > 6.0
1289
1290
1292{
1294 // exercise the resolution of DR 438:
1296 //
1297 // For every sequence defined in clause [lib.containers]
1298 // and in clause [lib.strings]:
1299
1300 // * If the constructor
1301 //
1302 // template <class InputIterator>
1303 // UserClass (InputIterator f, InputIterator l,
1304 // const allocator_type& a = allocator_type())
1305 //
1306 // is called with a type InputIterator that does not qualify
1307 // as an input iterator, then the constructor will behave
1308 // as if the overloaded constructor:
1309 //
1310 // UserClass (size_type, const value_type& = value_type(),
1311 // const allocator_type& = allocator_type())
1312 //
1313 // were called instead, with the arguments static_cast<size_type>(f),
1314 // l and a, respectively.
1315 //
1316 // * If the member functions of the forms:
1317 //
1318 // template <class InputIterator> // such as insert()
1319 // rt fx1(iterator p, InputIterator f, InputIterator l);
1320 //
1321 // template <class InputIterator> // such as append(), assign()
1322 // rt fx2(InputIterator f, InputIterator l);
1323 //
1324 // template <class InputIterator> // such as replace()
1325 // rt fx3(iterator i1, iterator i2, InputIterator f, InputIterator l);
1326 //
1327 // are called with a type InputIterator that does not qualify
1328 // as an input iterator, then these functions will behave
1329 // as if the overloaded member functions:
1330 //
1331 // rt fx1(iterator, size_type, const value_type&);
1332 //
1333 // rt fx2(size_type, const value_type&);
1334 //
1335 // rt fx3(iterator, iterator, size_type, const value_type&);
1336 //
1337 // were called instead, with the same arguments.
1338 //
1339 // In the previous paragraph the alternative binding will fail
1340 // if f is not implicitly convertible to UserClass::size_type or
1341 // if l is not implicitly convertible to UserClass::value_type.
1342 //
1343 // The extent to which an implementation determines that a type
1344 // cannot be an input iterator is unspecified, except that
1345 // as a minimum integral types shall not qualify as input iterators.
1347
1348 rw_info (0, 0, 0, "resolution of DR 438");
1349
1350#ifndef NO_DR_438_TEST
1351
1352 std::deque<DR_438, std::allocator<DR_438> > dq;
1353
1354 dq.assign (1, 2);
1355
1356 rw_assert (!DR_438::cast_used, 0, __LINE__,
1357 "deque::assign(InputIterator, InputIterator)"
1358 "[ with InputIterator = <integral type> ] unexpectedly "
1359 "used explicit argument conversion");
1360
1361 dq.insert (dq.begin (), 1, 2);
1362
1363 rw_assert (!DR_438::cast_used, 0, __LINE__,
1364 "deque::insert(iterator, InputIterator, InputIterator) "
1365 "[ with InputIterator = <integral type> ] unexpectedly "
1366 "used explicit argument conversion");
1367#else // if defined (NO_DR_438_TEST)
1368
1369 rw_warning (0, 0, __LINE__, "%s; skipping test", NO_DR_438_TEST);
1370
1371#endif // NO_DR_438_TEST
1372
1373}
1374
1375
1377int run_test (int, char**)
1378{
1379 if (0 == rw_opt_no_dr438)
1380 test_dr_438 ();
1381
1382 static const std::size_t caps[] = {
1383 2, 3, 4, 5, 16, 32
1384 };
1385
1386 for (std::size_t i = 0; i != sizeof caps / sizeof *caps; ++i) {
1387
1388 new_capacity = caps [i];
1389
1390 rw_info (0, 0, 0,
1391 "__rw::__rw_new_capacity<std::deque<UserClass> >(0) = %zu",
1392 _RW::__rw_new_capacity (0, (Deque*)0));
1393
1394 if (0 == rw_opt_no_assign)
1395 test_assign ();
1396
1397 if (0 == rw_opt_no_erase)
1398 test_erase ();
1399
1400 if (0 == rw_opt_no_insert)
1401 test_insert ();
1402 }
1403
1404 return 0;
1405}
1406
1407
1409int main (int argc, char** argv)
1410{
1411 return rw_test (argc, argv, __FILE__,
1412 "lib.deque.modifiers",
1413 0 /* no comment */, run_test,
1414 "|-no-dr438#"
1415 "|-no-assign#"
1416 "|-no-erase#"
1417 "|-no-insert#"
1418 "|-no-InputIterator#"
1419 "|-no-ForwardIterator#"
1420 "|-no-BidirectionalIterator#"
1421 "|-no-RandomIterator#"
1422 "|-no-right-thing#",
1432}
#define i
Definition 17.names.cpp:126
#define T
Definition 17.names.cpp:163
#define d
Definition 17.names.cpp:115
#define start
Definition 17.names.cpp:547
#define line
Definition 17.names.cpp:490
#define res
Definition 17.names.cpp:531
#define last
Definition 17.names.cpp:487
#define x
Definition 17.names.cpp:140
#define j
Definition 17.names.cpp:127
#define off
Definition 17.names.cpp:507
#define len
Definition 17.names.cpp:488
#define n
Definition 17.names.cpp:130
#define inx
Definition 17.names.cpp:484
std::size_t new_capacity
#define A_to_D
void test_assign_range(const Iterator &it, const char *itname)
void test_insert_range(const Iterator &it, const char *itname)
#define A_to_Q
void exception_loop(int line, MemberFunction mfun, const char *fcall, int exceptions, Deque &deq, const Deque::iterator &it, int n, const UserClass *x, const Iterator &first, const Iterator &last, std::size_t *n_copy, std::size_t *n_asgn)
#define D_to_Z
#define A_to_U
int rw_opt_no_random_iterator
#define L_to_Z
int run_test(int, char **)
#define A_to_B
int rw_opt_no_assign
#define O_to_Z
#define A_to_X
#define X_to_Z
#define A_to_V
#define H_to_Z
#define A_to_I
#define U_to_Z
std::size_t insert_assignments(Iterator it, int nelems, std::size_t off, std::size_t seqlen, std::size_t inslen)
#define J_to_Z
void test_dr_438()
void test_erase()
#define B_to_Z
int rw_opt_no_right_thing
unsigned char UChar
int rw_opt_no_dr438
std::deque< UserClass, std::allocator< UserClass > > Deque
#define T_to_Z
#define I_to_Z
#define A_to_C
void test_insert()
#define A_to_Z
#define A_to_N
#define K_to_Z
#define A_to_P
#define A_to_O
#define Q_to_Z
#define F_to_Z
#define A_to_S
#define P_to_Z
#define A_to_Y
@ AssignmentThrows
@ CopyCtorThrows
Deque::size_type new_capacity
void test_assign()
#define LOWER
int rw_opt_no_erase
#define A_to_R
int rw_opt_no_bidirectional_iterator
#define A_to_K
#define UPPER
#define A_to_T
bool is_bidirectional(std::input_iterator_tag)
#define A_to_M
#define E_to_Z
#define A_to_J
#define A_to_L
#define W_to_Z
#define R_to_Z
#define A_to_G
#define G_to_Z
#define A_to_E
int rw_opt_no_forward_iterator
#define A_to_H
#define N_to_Z
#define M_to_Z
#define A_to_F
#define V_to_Z
#define S_to_Z
#define A_to_W
void test_insert_int_range(const T &, const IntType &, const char *t_name, const char *int_name)
#define Y_to_Z
int rw_opt_no_input_iterator
#define TEST(seq, off, ins, res)
int rw_opt_no_insert
#define C_to_Z
const int end
#define main
#define _RWSTD_LONG_LONG
#define _TRY
Definition _defs.h:850
#define _RWSTD_ASSERT(ignore)
Definition _defs.h:1108
#define _CATCH(ex)
Definition _defs.h:851
#define _RWSTD_CONST_CAST(T, x)
Definition _defs.h:536
#define _RWSTD_SPECIALIZED_FUNCTION
Definition _defs.h:556
#define _RWSTD_ITERATOR_CATEGORY(iterT, ignore)
Definition _defs.h:1055
std::deque< std::string, std::allocator< std::string > > Deque
Definition deque.cpp:35
_RWSTD_SPECIALIZED_FUNCTION Deque::size_type __rw_new_capacity< Deque >(Deque::size_type n, const Deque *)
T * make_iter(T *cur, const T *, const T *, T *)
_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_note(int, const char *, int, const char *,...)
Definition driver.cpp:1664
_TEST_EXPORT int rw_assert(int, const char *, int, const char *,...)
Definition driver.cpp:1630
_TEST_EXPORT rwt_free_store * rwt_get_free_store(rwt_free_store *)
Definition new.cpp:597
_TEST_EXPORT int rw_asnprintf(char **pbuf, _RWSTD_SIZE_T *pbufsize, const char *fmt,...)
unsigned char UChar
Definition collate.cpp:122
static ContIter begin(Cont &cont, ContIter *)
static bool cast_used
DR_438(std::size_t)
static _RWSTD_SIZE_T n_total_op_assign_
Definition rw_value.h:127
static UserClass from_char(char c)
Definition rw_value.h:221
static _RWSTD_SIZE_T copy_ctor_throw_count_
Definition rw_value.h:164
static _RWSTD_SIZE_T count_
Definition rw_value.h:120
static _RWSTD_SIZE_T op_assign_throw_count_
Definition rw_value.h:166
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