blob: ef2380b2bb666d8198cb379236c82e0be95f193a [file] [log] [blame]
/***************************************************************************
*
* 23.deque.modifiers.cpp - test exercising [lib.deque.modifiers]
*
* $Id$
*
***************************************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership. The ASF licenses this file to you under the Apache
* License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
* implied. See the License for the specific language governing
* permissions and limitations under the License.
*
* Copyright 1994-2008 Rogue Wave Software, Inc.
*
**************************************************************************/
#ifdef _MSC_VER
// silence warning C4244: 'argument' : conversion from 'T' to
// 'const std::allocator<_TypeT>::value_type', possible loss of data
// issued for deque::assign(InputIterator a, InputIterator b) and
// deque::insert(iterator, InputIterator a, InputIterator b) due
// the implicit conversion of a to size_type and b to value_type
// required by DR 438:
// http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#438
# pragma warning (disable: 4244)
#endif
#include <deque> // for deque
#include <cstdlib> // for free()
#ifndef _RWSTD_NO_REPLACEABLE_NEW_DELETE
// disabled for MSVC since it can't reliably replace the operators
# include <rw_new.h>
#endif // _RWSTD_NO_REPLACEABLE_NEW_DELETE
#include <rw_value.h> // for UserClass
#include <rw_driver.h> // for rw_test(), ...
#include <rw_printf.h> // for rw_asnprintf
/**************************************************************************/
// Runtime options
/* extern */ int rw_opt_no_assign = 0;
/* extern */ int rw_opt_no_erase = 0;
/* extern */ int rw_opt_no_insert = 0;
/* extern */ int rw_opt_no_dr438 = 0;
/* extern */ int rw_opt_no_input_iterator = 0;
/* extern */ int rw_opt_no_forward_iterator = 0;
/* extern */ int rw_opt_no_bidirectional_iterator = 0;
/* extern */ int rw_opt_no_random_iterator = 0;
/* extern */ int rw_opt_no_right_thing = 0;
/**************************************************************************/
// For konvenience
typedef unsigned char UChar;
/**************************************************************************/
typedef std::deque<UserClass, std::allocator<UserClass> > Deque;
Deque::size_type new_capacity;
namespace __rw {
_RWSTD_SPECIALIZED_FUNCTION
inline Deque::size_type
__rw_new_capacity<Deque>(Deque::size_type n, const Deque*)
{
if (n) {
// non-zero size argument indicates a request for an increase
// in the capacity of a deque object's dynamically sizable
// vector of nodes
return n * 2;
}
// zero size argument is a request for the initial size of a deque
// object's dynamically sizable vector of nodes or for the size of
// the objects's fixed-size buffer for elements
return new_capacity;
}
}
/**************************************************************************/
enum {
NewThrows = 0x1 /* cause operator new to throw */,
CopyCtorThrows = 0x2 /* cause element's copy ctor to throw */,
AssignmentThrows = 0x4 /* cause element's assignment to throw */
};
enum MemberFunction {
Assign_n /* deque::assign (size_type, const_reference) */,
AssignRange /* deque::assign (InputIterator, InputIterator) */,
Erase_1 /* deque::erase (iterator) */,
EraseRange /* deque::erase (iterator, iterator) */,
Insert_1 /* deque::insert (iterator, const_reference) */,
Insert_n /* deque::insert (iterator, size_type, const_reference) */,
InsertRange /* deque::insert (iterator, InputIterator, InputIterator) */
};
// causes operator new, deque element's copy ctor, or assignment operator
// to throw an exception and iterates as long as the member function exits
// by throwing an exception; verifies that the exception had no effects
// on the container
template <class Iterator>
void exception_loop (int line /* line number in caller*/,
MemberFunction mfun /* deque member function */,
const char *fcall /* function call string */,
int exceptions /* enabled exceptions */,
Deque &deq /* container to call function on */,
const Deque::iterator &it /* iterator into container */,
int n /* number of elements or offset */,
const UserClass *x /* pointer to an element or 0 */,
const Iterator &first /* beginning of range */,
const Iterator &last /* end of range to insert */,
std::size_t *n_copy /* number of copy ctors */,
std::size_t *n_asgn /* number of assignments */)
{
std::size_t throw_after = 0;
// get the initial size of the container and its begin() iterator
// to detect illegal changes after an exception (i.e., violations
// if the strong exception guarantee)
const std::size_t size = deq.size ();
const Deque::const_iterator begin = deq.begin ();
const Deque::const_iterator end = deq.end ();
#ifdef DEFINE_REPLACEMENT_NEW_AND_DELETE
rwt_free_store* const pst = rwt_get_free_store (0);
#endif // DEFINE_REPLACEMENT_NEW_AND_DELETE
// repeatedly call the specified member function until it returns
// without throwing an exception
for ( ; ; ) {
// detect objects constructed but not destroyed after an exception
std::size_t x_count = UserClass::count_;
_RWSTD_ASSERT (n_copy);
_RWSTD_ASSERT (n_asgn);
*n_copy = UserClass::n_total_copy_ctor_;
*n_asgn = UserClass::n_total_op_assign_;
#ifndef _RWSTD_NO_EXCEPTIONS
// iterate for `n=throw_after' starting at the next call to operator
// new, forcing each call to throw an exception, until the insertion
// finally succeeds (i.e, no exception is thrown)
# ifdef DEFINE_REPLACEMENT_NEW_AND_DELETE
if (exceptions & NewThrows) {
*pst->throw_at_calls_ [0] = pst->new_calls_ [0] + throw_after + 1;
}
# endif // DEFINE_REPLACEMENT_NEW_AND_DELETE
if (exceptions & CopyCtorThrows) {
UserClass::copy_ctor_throw_count_ =
UserClass::n_total_copy_ctor_ + throw_after;
}
if (exceptions & AssignmentThrows) {
UserClass::op_assign_throw_count_ =
UserClass::n_total_op_assign_ + throw_after;
}
#endif // _RWSTD_NO_EXCEPTIONS
_TRY {
// convert an int to size_type to avoid conversion
// warnings when passing it to member functions
// that expect an unsigned argument
const Deque::size_type nelems (n);
switch (mfun) {
case Assign_n:
_RWSTD_ASSERT (x);
deq.assign (nelems, *x);
break;
case AssignRange:
deq.assign (first, last);
break;
case Erase_1:
deq.erase (it);
break;
case EraseRange: {
const Deque::iterator erase_end (it + n);
deq.erase (it, erase_end);
break;
}
case Insert_1:
_RWSTD_ASSERT (x);
deq.insert (it, *x);
break;
case Insert_n:
_RWSTD_ASSERT (x);
deq.insert (it, nelems, *x);
break;
case InsertRange:
deq.insert (it, first, last);
break;
}
}
_CATCH (...) {
// verify that an exception thrown from the member function
// didn't cause a change in the state of the container
rw_assert (deq.size () == size, 0, line,
"line %d: %s: size unexpectedly changed "
"from %zu to %zu after an exception",
__LINE__, fcall, size, deq.size ());
rw_assert (deq.begin () == begin, 0, line,
"line %d: %s: begin() unexpectedly "
"changed after an exception by %td",
__LINE__, fcall, deq.begin () - begin);
rw_assert (deq.end () == end, 0, line,
"line %d: %s: end() unexpectedly "
"changed after an exception by %td",
__LINE__, fcall, deq.end () - end);
// count the number of objects to detect leaks
x_count = UserClass::count_ - x_count;
rw_assert (x_count == deq.size () - size, 0, line,
"line %d: %s: leaked %zu objects after an exception",
__LINE__, fcall, x_count - (deq.size () - size));
if (exceptions) {
// increment to allow this call to operator new to succeed
// and force the next one to fail, and try to insert again
++throw_after;
}
else
break;
continue;
}
// count the number of objects to detect leaks
x_count = UserClass::count_ - x_count;
rw_assert (x_count == deq.size () - size, 0, line,
"line %d: %s: leaked %zu objects "
"after a successful insertion",
__LINE__, fcall, x_count - (deq.size () - size));
break;
}
#ifdef DEFINE_REPLACEMENT_NEW_AND_DELETE
// disable exceptions from replacement operator new
*pst->throw_at_calls_ [0] = _RWSTD_SIZE_MAX;
#endif // DEFINE_REPLACEMENT_NEW_AND_DELETE
UserClass::copy_ctor_throw_count_ = 0;
UserClass::op_assign_throw_count_ = 0;
// compute the number of calls to UserClass copy ctor and assignment
// operator and set `n_copy' and `n_assgn' to the value of the result
*n_copy = UserClass::n_total_copy_ctor_ - *n_copy;
*n_asgn = UserClass::n_total_op_assign_ - *n_asgn;
}
// used to determine whether insert() can or cannot use
// an algorithm optimized for BidirectionalIterators
bool is_bidirectional (std::input_iterator_tag) { return false; }
bool is_bidirectional (std::bidirectional_iterator_tag) { return true; }
// returns the number of invocations of the assignment operators
// for a call to deque::insert(iterator, InputIterator, InputIterator)
// (the value depends on the iterator category)
template <class Iterator>
std::size_t insert_assignments (Iterator it,
int nelems,
std::size_t off,
std::size_t seqlen,
std::size_t inslen)
{
if (is_bidirectional (_RWSTD_ITERATOR_CATEGORY (Iterator, it)))
return 0 == nelems ? 0 : off < seqlen - off ? off : seqlen - off;
if (0 < nelems)
--nelems;
if (0 == nelems || 0 == inslen)
return 0;
// compute the number of assignments done
// to insert the first element in the sequence
const std::size_t first = off < seqlen - off ? off : seqlen - off;
// recursively compute the numner of assignments
// for the rest of the elements in the sequence
const std::size_t rest =
insert_assignments (it, nelems, off + 1, seqlen + 1, inslen - 1);
return first + rest;
}
template <class Iterator>
void test_insert (int line, int exceptions,
const Iterator &dummy, int nelems,
const char *seq, std::size_t seqlen, std::size_t off,
const char *ins, std::size_t inslen,
const char *res, std::size_t reslen)
{
// Ensure that xsrc, xins are always dereferenceable
const UserClass* const xseq = UserClass::from_char (seq, seqlen + 1);
UserClass* const xins = UserClass::from_char (ins, inslen + 1);
Deque deq = seqlen ? Deque (xseq, xseq + seqlen) : Deque ();
// offset must be valid
_RWSTD_ASSERT (off <= deq.size ());
const Deque::iterator iter = deq.begin () + off;
// only insert() at either end of the container is exception safe
// insertions into the middle of the container are not (i.e., the
// container may grow or may even become inconsistent)
if (off && off < deq.size ())
exceptions = 0;
// format a string describing the function call being exercised
// (used in diagnostic output below)
char* funcall = 0;
std::size_t len = 0;
static const int cwidth = sizeof (*xseq);
rw_asnprintf (&funcall, &len, "deque(\"%{X=*.*}\").insert("
"%{?}begin(), %{:}%{?}end (), %{:}begin () + %zu%{;}%{;}"
"%{?}%d)%{:}%{?}\"%{X=*.*}\")%{:}%d, %d)%{;}%{;}",
cwidth, int (seqlen), -1, xseq, 0 == off, seqlen == off,
off, nelems == -2, *ins, nelems == -1,
cwidth, int (inslen), -1, xins, nelems, *ins);
std::size_t n_copy = UserClass::n_total_copy_ctor_;
std::size_t n_asgn = UserClass::n_total_op_assign_;
if (-2 == nelems) { // insert(iterator, const_reference)
exception_loop (line, Insert_1, funcall, exceptions,
deq, iter, nelems, xins, dummy, dummy,
&n_copy, &n_asgn);
}
else if (-1 == nelems) { // insert(iterator, Iterator, Iterator)
if (inslen > 1)
exceptions = 0;
const Iterator first =
make_iter (xins, xins, xins + inslen, dummy);
const Iterator last =
make_iter (xins + inslen, xins, xins + inslen, dummy);
exception_loop (line, InsertRange, funcall, exceptions,
deq, iter, nelems, 0, first, last,
&n_copy, &n_asgn);
}
else { // insert(iterator, size_type, const_reference)
if (nelems > 1)
exceptions = 0;
exception_loop (line, Insert_n, funcall, exceptions,
deq, iter, nelems, xins, dummy, dummy,
&n_copy, &n_asgn);
}
// verify the expected size of the deque after insertion
rw_assert (deq.size () == reslen, __FILE__, line,
"line %d: %s: size == %zu, got %zu\n",
__LINE__, funcall, reslen, deq.size ());
// verify the expected contents of the deque after insertion
const Deque::const_iterator resbeg = deq.begin ();
const Deque::const_iterator resend = deq.end ();
for (Deque::const_iterator it = resbeg; it != resend; ++it) {
if ((*it).data_.val_ != UChar (res [it - resbeg])) {
char* const got = new char [deq.size () + 1];
for (Deque::const_iterator i = resbeg; i != resend; ++i) {
got [i - resbeg] = char ((*i).data_.val_);
}
got [deq.size ()] = '\0';
rw_assert (false, __FILE__, line,
"line %d: %s: expected %s, got %s\n",
__LINE__, funcall, res, got);
delete[] got;
break;
}
}
// verify the complexity of the operation in terms of the number
// of calls to the copy ctor and assignment operator on value_type
const std::size_t expect_copy = nelems < 0 ? inslen : nelems;
rw_assert (n_copy == expect_copy, __FILE__, line,
"line %d: %s: expected %zu invocations "
"of UserClass::UserClass(const UserClass&), got %d\n",
__LINE__, funcall, expect_copy, n_copy);
// compute the number of calls to the assignment operator
const std::size_t expect_asgn =
insert_assignments (dummy, nelems, off, seqlen, inslen);
rw_assert (n_asgn == expect_asgn, __FILE__, line,
"line %d: %s: expected %zu invocations "
"of UserClass::operator=(const UserClass&), got %d\n",
__LINE__, funcall, expect_asgn, n_asgn);
// Free funcall storage
std::free (funcall);
delete[] xins;
// cast away constness to work around an HP aCC 6.16 bug
// see http://issues.apache.org/jira/browse/STDCXX-802
delete[] _RWSTD_CONST_CAST (UserClass*, xseq);
}
/**************************************************************************/
template <class Iterator>
void test_insert_range (const Iterator &it, const char* itname)
{
rw_info (0, 0 ,0,
"std::deque<UserClass>::insert(iterator, %s, %s)", itname, itname);
#undef TEST
#define TEST(seq, off, ins, res) \
test_insert (__LINE__, -1, \
it, -1, \
seq, sizeof seq - 1, \
std::size_t (off), \
ins, sizeof ins - 1, \
res, sizeof res - 1)
// +---------------------------------------- seq
// | +--------------------------------- off
// | | +----------------------------- ins
// | | | +---------------------- res
// | | | |
// v v v v
TEST ("", +0, "", "");
TEST ("", +0, "a", "a");
TEST ("", +0, "ab", "ab");
TEST ("", +0, "abc", "abc");
TEST ("a", +0, "", "a");
TEST ("b", +0, "a", "ab");
TEST ("c", +0, "ab", "abc");
TEST ("cd", +0, "ab", "abcd");
TEST ("def", +0, "abc", "abcdef");
TEST ("a", +1, "", "a");
TEST ("a", +1, "b", "ab");
TEST ("a", +1, "bc", "abc");
TEST ("a", +1, "bcd", "abcd");
TEST ("ab", +1, "", "ab");
TEST ("ac", +1, "b", "abc");
TEST ("acd", +1, "b", "abcd");
TEST ("ab", +2, "", "ab");
TEST ("ab", +2, "c", "abc");
TEST ("ab", +2, "cd", "abcd");
TEST ("abc", +2, "", "abc");
TEST ("abd", +2, "c", "abcd");
TEST ("abe", +2, "cd", "abcde");
TEST ("abf", +2, "cde", "abcdef");
TEST ("abc", +3, "", "abc");
TEST ("abc", +3, "d", "abcd");
TEST ("abc", +3, "de", "abcde");
TEST ("abc", +3, "def", "abcdef");
#define UPPER "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
#define LOWER "abcdefghijklmnopqrstuvwxyz"
TEST (UPPER, +0, LOWER, "" LOWER "ABCDEFGHIJKLMNOPQRSTUVWXYZ");
TEST (UPPER, +1, LOWER, "A" LOWER "BCDEFGHIJKLMNOPQRSTUVWXYZ");
TEST (UPPER, +2, LOWER, "AB" LOWER "CDEFGHIJKLMNOPQRSTUVWXYZ");
TEST (UPPER, +3, LOWER, "ABC" LOWER "DEFGHIJKLMNOPQRSTUVWXYZ");
TEST (UPPER, +4, LOWER, "ABCD" LOWER "EFGHIJKLMNOPQRSTUVWXYZ");
TEST (UPPER, +5, LOWER, "ABCDE" LOWER "FGHIJKLMNOPQRSTUVWXYZ");
TEST (UPPER, +6, LOWER, "ABCDEF" LOWER "GHIJKLMNOPQRSTUVWXYZ");
TEST (UPPER, +7, LOWER, "ABCDEFG" LOWER "HIJKLMNOPQRSTUVWXYZ");
TEST (UPPER, +8, LOWER, "ABCDEFGH" LOWER "IJKLMNOPQRSTUVWXYZ");
TEST (UPPER, +9, LOWER, "ABCDEFGHI" LOWER "JKLMNOPQRSTUVWXYZ");
TEST (UPPER, +10, LOWER, "ABCDEFGHIJ" LOWER "KLMNOPQRSTUVWXYZ");
TEST (UPPER, +11, LOWER, "ABCDEFGHIJK" LOWER "LMNOPQRSTUVWXYZ");
TEST (UPPER, +12, LOWER, "ABCDEFGHIJKL" LOWER "MNOPQRSTUVWXYZ");
TEST (UPPER, +13, LOWER, "ABCDEFGHIJKLM" LOWER "NOPQRSTUVWXYZ");
TEST (UPPER, +14, LOWER, "ABCDEFGHIJKLMN" LOWER "OPQRSTUVWXYZ");
TEST (UPPER, +15, LOWER, "ABCDEFGHIJKLMNO" LOWER "PQRSTUVWXYZ");
TEST (UPPER, +16, LOWER, "ABCDEFGHIJKLMNOP" LOWER "QRSTUVWXYZ");
TEST (UPPER, +17, LOWER, "ABCDEFGHIJKLMNOPQ" LOWER "RSTUVWXYZ");
TEST (UPPER, +18, LOWER, "ABCDEFGHIJKLMNOPQR" LOWER "STUVWXYZ");
TEST (UPPER, +19, LOWER, "ABCDEFGHIJKLMNOPQRS" LOWER "TUVWXYZ");
TEST (UPPER, +20, LOWER, "ABCDEFGHIJKLMNOPQRST" LOWER "UVWXYZ");
TEST (UPPER, +21, LOWER, "ABCDEFGHIJKLMNOPQRSTU" LOWER "VWXYZ");
TEST (UPPER, +22, LOWER, "ABCDEFGHIJKLMNOPQRSTUV" LOWER "WXYZ");
TEST (UPPER, +23, LOWER, "ABCDEFGHIJKLMNOPQRSTUVW" LOWER "XYZ");
TEST (UPPER, +24, LOWER, "ABCDEFGHIJKLMNOPQRSTUVWX" LOWER "YZ");
TEST (UPPER, +25, LOWER, "ABCDEFGHIJKLMNOPQRSTUVWXY" LOWER "Z");
TEST (UPPER, +26, LOWER, "ABCDEFGHIJKLMNOPQRSTUVWXYZ" LOWER "");
}
/**************************************************************************/
template <class T, class IntType>
void test_insert_int_range (const T&, const IntType&,
const char* t_name, const char* int_name)
{
rw_info (0, 0, 0,
"std::deque<%s>::insert(iterator, %s, %s)",
t_name, int_name, int_name);
std::deque<T> d;
typename std::deque<T>::iterator it = d.begin ();
// deque<T>::insert(iterator, size_type, const_reference)
d.insert (it, IntType (1), IntType (0));
rw_assert (1 == d.size (), 0, __LINE__,
"deque<%s>::insert(begin(), %s = 1, %s = 0); size() == 1,"
" got %zu", t_name, int_name, int_name, d.size ());
it = d.begin ();
++it;
d.insert (it, IntType (3), IntType (2));
rw_assert (4 == d.size (), 0, __LINE__,
"deque<%s>::insert(begin() + 1, %s = 3, %s = 2); size() == 4,"
" got %zu", t_name, int_name, int_name, d.size ());
it = d.begin ();
++it;
d.insert (it, IntType (2), IntType (1));
rw_assert (6 == d.size (), 0, __LINE__,
"deque<%s>::insert(begin() + 1, %s = 2, %s = 1); size() == 6,"
" got %zu", t_name, int_name, int_name, d.size ());
}
template <class T>
void test_insert_int_range (const T &dummy, const char* tname)
{
test_insert_int_range (dummy, (signed char)0, tname, "signed char");
test_insert_int_range (dummy, (unsigned char)0, tname, "unsigned char");
test_insert_int_range (dummy, short (), tname, "short");
test_insert_int_range (dummy, (unsigned short)0, tname, "unsigned short");
test_insert_int_range (dummy, int (), tname, "int");
test_insert_int_range (dummy, (unsigned int)0, tname, "unsigned int");
test_insert_int_range (dummy, long (), tname, "long");
test_insert_int_range (dummy, (unsigned long)0, tname, "unsigned long");
#ifdef _RWSTD_LONG_LONG
test_insert_int_range (dummy, (_RWSTD_LONG_LONG)0,
tname, "long long");
test_insert_int_range (dummy, (unsigned _RWSTD_LONG_LONG)0,
tname, "unsigned long long");
#endif // _RWSTD_LONG_LONG
}
/**************************************************************************/
void test_insert ()
{
//////////////////////////////////////////////////////////////////
// exercise deque::insert(iterator, const_reference)
rw_info (0, 0, 0,
"std::deque<UserClass>::insert(iterator, const_reference)");
#undef TEST
#define TEST(seq, off, ins, res) do { \
const char insseq [] = { ins, '\0' }; \
test_insert (__LINE__, -1, \
(UserClass*)0, -2, \
seq, sizeof seq - 1, \
std::size_t (off), \
insseq, 1, \
res, sizeof res - 1); \
} while (0)
// +------------------- original sequence
// | +----------- insertion offset
// | | +------ element to insert
// | | | +-- resulting sequence
// | | | |
// V V V V
TEST ("", +0, 'a', "a");
TEST ("b", +0, 'a', "ab");
TEST ("bc", +0, 'a', "abc");
TEST ("bcd", +0, 'a', "abcd");
TEST ("bcde", +0, 'a', "abcde");
TEST ("a", +1, 'b', "ab");
TEST ("ac", +1, 'b', "abc");
TEST ("acd", +1, 'b', "abcd");
TEST ("acde", +1, 'b', "abcde");
TEST ("ab", +2, 'c', "abc");
TEST ("abd", +2, 'c', "abcd");
TEST ("abde", +2, 'c', "abcde");
TEST ("abc", +3, 'd', "abcd");
TEST ("abce", +3, 'd', "abcde");
TEST ("abcd", +4, 'e', "abcde");
#define A_to_B "AB"
#define A_to_C "ABC"
#define A_to_D "ABCD"
#define A_to_E "ABCDE"
#define A_to_F "ABCDEF"
#define A_to_G "ABCDEFG"
#define A_to_H "ABCDEFGH"
#define A_to_I "ABCDEFGHI"
#define A_to_J "ABCDEFGHIJ"
#define A_to_K "ABCDEFGHIJK"
#define A_to_L "ABCDEFGHIJKL"
#define A_to_M "ABCDEFGHIJKLM"
#define A_to_N "ABCDEFGHIJKLMN"
#define A_to_O "ABCDEFGHIJKLMNO"
#define A_to_P "ABCDEFGHIJKLMNOP"
#define A_to_Q "ABCDEFGHIJKLMNOPQ"
#define A_to_R "ABCDEFGHIJKLMNOPQR"
#define A_to_S "ABCDEFGHIJKLMNOPQRS"
#define A_to_T "ABCDEFGHIJKLMNOPQRST"
#define A_to_U "ABCDEFGHIJKLMNOPQRSTU"
#define A_to_V "ABCDEFGHIJKLMNOPQRSTUV"
#define A_to_W "ABCDEFGHIJKLMNOPQRSTUVW"
#define A_to_X "ABCDEFGHIJKLMNOPQRSTUVWX"
#define A_to_Y "ABCDEFGHIJKLMNOPQRSTUVWXY"
#define A_to_Z "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
#define B_to_Z "BCDEFGHIJKLMNOPQRSTUVWXYZ"
#define C_to_Z "CDEFGHIJKLMNOPQRSTUVWXYZ"
#define D_to_Z "DEFGHIJKLMNOPQRSTUVWXYZ"
#define E_to_Z "EFGHIJKLMNOPQRSTUVWXYZ"
#define F_to_Z "FGHIJKLMNOPQRSTUVWXYZ"
#define G_to_Z "GHIJKLMNOPQRSTUVWXYZ"
#define H_to_Z "HIJKLMNOPQRSTUVWXYZ"
#define I_to_Z "IJKLMNOPQRSTUVWXYZ"
#define J_to_Z "JKLMNOPQRSTUVWXYZ"
#define K_to_Z "KLMNOPQRSTUVWXYZ"
#define L_to_Z "LMNOPQRSTUVWXYZ"
#define M_to_Z "MNOPQRSTUVWXYZ"
#define N_to_Z "NOPQRSTUVWXYZ"
#define O_to_Z "OPQRSTUVWXYZ"
#define P_to_Z "PQRSTUVWXYZ"
#define Q_to_Z "QRSTUVWXYZ"
#define R_to_Z "RSTUVWXYZ"
#define S_to_Z "STUVWXYZ"
#define T_to_Z "TUVWXYZ"
#define U_to_Z "UVWXYZ"
#define V_to_Z "VWXYZ"
#define W_to_Z "WXYZ"
#define X_to_Z "XYZ"
#define Y_to_Z "YZ"
TEST (A_to_Z, + 0, '^', "" "^" A_to_Z);
TEST (A_to_Z, + 1, '^', "A" "^" B_to_Z);
TEST (A_to_Z, + 2, '^', A_to_B "^" C_to_Z);
TEST (A_to_Z, + 3, '^', A_to_C "^" D_to_Z);
TEST (A_to_Z, + 4, '^', A_to_D "^" E_to_Z);
TEST (A_to_Z, + 5, '^', A_to_E "^" F_to_Z);
TEST (A_to_Z, + 6, '^', A_to_F "^" G_to_Z);
TEST (A_to_Z, + 7, '^', A_to_G "^" H_to_Z);
TEST (A_to_Z, + 8, '^', A_to_H "^" I_to_Z);
TEST (A_to_Z, + 9, '^', A_to_I "^" J_to_Z);
TEST (A_to_Z, +10, '^', A_to_J "^" K_to_Z);
TEST (A_to_Z, +11, '^', A_to_K "^" L_to_Z);
TEST (A_to_Z, +12, '^', A_to_L "^" M_to_Z);
TEST (A_to_Z, +13, '^', A_to_M "^" N_to_Z);
TEST (A_to_Z, +14, '^', A_to_N "^" O_to_Z);
TEST (A_to_Z, +15, '^', A_to_O "^" P_to_Z);
TEST (A_to_Z, +16, '^', A_to_P "^" Q_to_Z);
TEST (A_to_Z, +17, '^', A_to_Q "^" R_to_Z);
TEST (A_to_Z, +18, '^', A_to_R "^" S_to_Z);
TEST (A_to_Z, +19, '^', A_to_S "^" T_to_Z);
TEST (A_to_Z, +20, '^', A_to_T "^" U_to_Z);
TEST (A_to_Z, +21, '^', A_to_U "^" V_to_Z);
TEST (A_to_Z, +22, '^', A_to_V "^" W_to_Z);
TEST (A_to_Z, +23, '^', A_to_W "^" X_to_Z);
TEST (A_to_Z, +24, '^', A_to_X "^" Y_to_Z);
TEST (A_to_Z, +25, '^', A_to_Y "^" "Z");
TEST (A_to_Z, +26, '^', A_to_Z "^" "");
//////////////////////////////////////////////////////////////////
// exercise deque::insert(iterator, size_type, const_reference)
rw_info (0, 0, 0,
"std::deque<UserClass>::insert(iterator, size_type, "
"const_reference)");
#undef TEST
#define TEST(seq, off, n, ins, res) do { \
const char insseq [] = { ins, '\0' }; \
test_insert (__LINE__, -1, \
(UserClass*)0, n, \
seq, sizeof seq - 1, \
std::size_t (off), \
insseq, 1, \
res, sizeof res - 1); \
} while (0)
TEST ("", +0, 0, 'a', "");
TEST ("", +0, 1, 'a', "a");
TEST ("", +0, 2, 'b', "bb");
TEST ("", +0, 3, 'c', "ccc");
TEST ("a", +0, 0, 'a', "a");
TEST ("b", +0, 1, 'a', "ab");
TEST ("b", +0, 2, 'a', "aab");
TEST ("b", +0, 3, 'a', "aaab");
TEST ("ab", +1, 0, 'b', "ab");
TEST ("ac", +1, 1, 'b', "abc");
TEST ("ac", +1, 2, 'b', "abbc");
TEST ("ac", +1, 3, 'b', "abbbc");
TEST ("abcd", +2, 0, 'c', "abcd");
TEST ("abde", +2, 1, 'c', "abcde");
TEST ("abde", +2, 2, 'c', "abccde");
TEST ("abde", +2, 3, 'c', "abcccde");
//////////////////////////////////////////////////////////////////
// exercise deque::insert(iterator, InputIterator, InputIterator)
rw_info (0, 0, 0,
"template <class InputIterator> std::deque<UserClass>::"
"insert(iterator, InputIterator, InputIterator)");
if (0 == rw_opt_no_input_iterator)
test_insert_range (InputIter<UserClass>(0, 0, 0),
"InputIter<UserClass>");
else
rw_note (0, 0, __LINE__,
"template <class T> "
"std::deque<UserClass>::insert(iterator, T, T) "
"[with T = InputIterator] test disabled.");
if (0 == rw_opt_no_forward_iterator)
test_insert_range (FwdIter<UserClass>(), "FwdIter<UserClass>");
else
rw_note (0, 0, __LINE__,
"template <class T> "
"std::deque<UserClass>::insert(iterator, T, T) "
"[with T = ForwardIterator] test disabled.");
if (0 == rw_opt_no_bidirectional_iterator)
test_insert_range (BidirIter<UserClass>(), "BidirIter<UserClass>");
else
rw_note (0, 0, __LINE__,
"template <class T> "
"std::deque<UserClass>::insert(iterator, T, T) "
"[with T = BidirectionalIterator] test disabled.");
if (0 == rw_opt_no_random_iterator)
test_insert_range (RandomAccessIter<UserClass>(),
"RandomAccessIter<UserClass>");
else
rw_note (0, 0, __LINE__,
"template <class T> "
"std::deque<UserClass>::insert(iterator, T, T) "
"[with T = RandomAccessIterator] test disabled.");
//////////////////////////////////////////////////////////////////
// exercise deque::insert(iterator, int, int)
rw_info (0, 0, 0,
"template <class IntType> "
"std::deque<IntType>::"
"insert(iterator, IntType, IntType)");
if (0 == rw_opt_no_right_thing) {
test_insert_int_range ((signed char)0, "signed char");
test_insert_int_range ((unsigned char)0, "unsigned char");
test_insert_int_range (short (), "short");
test_insert_int_range ((unsigned short)0, "unsigned short");
test_insert_int_range (int (), "int");
test_insert_int_range ((unsigned int)0, "unsigned int");
test_insert_int_range (long (), "long");
test_insert_int_range ((unsigned long)0, "unsigned long");
#ifdef _RWSTD_LONG_LONG
test_insert_int_range ((_RWSTD_LONG_LONG)0,
"long long");
test_insert_int_range ((unsigned _RWSTD_LONG_LONG)0,
"unsigned long long");
#endif // _RWSTD_LONG_LONG
}
else
rw_note (0, 0, __LINE__,
"template <class T> "
"std::deque<UserClass>::insert(iterator, T, T) "
"[with T = IntegralType] tests disabled.");
}
/**************************************************************************/
template <class Iterator>
void test_assign (int line, int exceptions,
const Iterator &dummy, int nelems,
const char *seq, std::size_t seqlen,
const char *asn, std::size_t asnlen,
const char *res, std::size_t reslen)
{
const UserClass* const xseq = UserClass::from_char (seq, seqlen + 1);
UserClass* const xasn = UserClass::from_char (asn, asnlen + 1);
Deque deq = seqlen ? Deque (xseq, xseq + seqlen) : Deque ();
// format a string describing the function call being exercised
// (used in diagnostic output below)
char* funcall = 0;
std::size_t len = 0;
static const int cwidth = sizeof (*xseq);
rw_asnprintf (&funcall, &len,
"deque(\"%{X=*.*}\").assign("
"%{?}\"%{X=*.*}\")%{:}%d, %d)%{;}",
cwidth, seqlen, -1, xseq,
nelems < 0,
cwidth, asnlen, -1, xasn,
nelems, *asn);
std::size_t n_copy = UserClass::n_total_copy_ctor_;
std::size_t n_asgn = UserClass::n_total_op_assign_;
// create a dummy deque iterator to pass to exception_loop
// (the object will not be used by the functiuon)
const Deque::iterator dummy_it = deq.begin ();
if (nelems < 0) { // assign(Iterator, Iterator)
if (asnlen > 1)
exceptions = 0;
const Iterator first =
make_iter (xasn, xasn, xasn + asnlen, dummy);
const Iterator last =
make_iter (xasn + asnlen, xasn, xasn + asnlen, dummy);
exception_loop (line, AssignRange, funcall, exceptions,
deq, dummy_it, nelems, 0, first, last,
&n_copy, &n_asgn);
}
else { // assign(size_type, const_reference)
if (nelems > 1)
exceptions = 0;
exception_loop (line, Assign_n, funcall, exceptions,
deq, dummy_it, nelems, xasn, dummy, dummy,
&n_copy, &n_asgn);
}
// verify the expected size of the deque after assignment
rw_assert (deq.size () == reslen, 0, line,
"line %d: %s: size == %zu, got %zu\n",
__LINE__, funcall, reslen, deq.size ());
// verify the expected contents of the deque after assignment
const Deque::const_iterator resbeg = deq.begin ();
const Deque::const_iterator resend = deq.end ();
for (Deque::const_iterator it = resbeg; it != resend; ++it) {
const Deque::size_type inx = it - resbeg;
_RWSTD_ASSERT (inx < deq.size ());
if ((*it).data_.val_ != UChar (res [inx])) {
char* const got = new char [deq.size () + 1];
for (Deque::const_iterator i = resbeg; i != resend; ++i) {
const Deque::size_type inx_2 = i - resbeg;
_RWSTD_ASSERT (inx_2 < deq.size ());
got [inx_2] = char ((*i).data_.val_);
}
got [deq.size ()] = '\0';
rw_assert (false, 0, line,
"line %d: %s: expected %s, got %s\n",
__LINE__, funcall, res, got);
delete[] got;
break;
}
}
// set asnlen to the number of elements assigned to the container
if (0 <= nelems)
asnlen = std::size_t (nelems);
// verify the complexity of the operation in terms of the number
// of calls to the copy ctor and assignment operator on value_type
// the number of invocations of the copy ctor and the assignment
// operator depends on whether the implementation of assign()
// strictly follows the requirements in 23.2.1.1, p7 or p8 and
// destroys the existing elements before inserting the new ones,
// or whether it assigns the new elements over the existing ones
#ifndef _RWSTD_NO_EXT_DEQUE_ASSIGN_IN_PLACE
const std::size_t expect_copy = seqlen < asnlen ? asnlen - seqlen : 0;
const std::size_t expect_asgn = asnlen < seqlen ? asnlen : seqlen;
#else // if defined (_RWSTD_NO_EXT_DEQUE_ASSIGN_IN_PLACE)
const std::size_t expect_copy = asnlen;
const std::size_t expect_asgn = 0;
#endif // _RWSTD_NO_EXT_DEQUE_ASSIGN_IN_PLACE
rw_assert (n_copy == expect_copy, __FILE__, line,
"line %d: %s: expected %zu invocations "
"of UserClass::UserClass(const UserClass&), got %d\n",
__LINE__, funcall, expect_copy, n_copy);
rw_assert (n_asgn == expect_asgn, __FILE__, line,
"line %d: %s: expected %zu invocations "
"of UserClass::operator=(const UserClass&), got %d\n",
__LINE__, funcall, expect_asgn, n_asgn);
// Free funcall storage
std::free (funcall);
delete[] xasn;
// cast away constness to work around an HP aCC 6.16 bug
// see http://issues.apache.org/jira/browse/STDCXX-802
delete[] _RWSTD_CONST_CAST (UserClass*, xseq);
}
template <class Iterator>
void test_assign_range (const Iterator &it, const char* itname)
{
rw_info (0, 0, 0, "std::deque<UserClass>::assign(%s, %s)", itname, itname);
static const char seq[] = "abcdefghijklmnopqrstuvwxyz";
static const char asn[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
for (std::size_t i = 0; i != sizeof seq - 1; ++i) {
for (std::size_t j = 0; j != sizeof asn - 1; ++j) {
test_assign (__LINE__, 0, it, -1, seq, i, asn, j, asn, j);
}
}
}
void test_assign ()
{
//////////////////////////////////////////////////////////////////
// exercise
// deque::assign(size_type, const_reference)
rw_info (0, 0, 0,
"std::deque<UserClass>::assign(size_type, const_reference)");
static const char seq[] = "abcdefghijklmnopqrstuvwxyz";
static const char res[] = "AAAAAAAAAAAAAAAAAAAAAAAAAA";
for (std::size_t i = 0; i != sizeof seq - 1; ++i) {
for (std::size_t j = 0; j != sizeof seq - 1; ++j) {
test_assign (__LINE__, -1, (UserClass*)0, int (j),
seq, i, res, 1U, res, j);
}
}
//////////////////////////////////////////////////////////////////
// exercise
// template <class InputIterator>
// deque::assign(InputIterator, InputIterator)
rw_info (0, 0, 0,
"template <class InputIterator> "
"std::deque<UserClass>::assign(InputIterator, InputIterator)");
if (0 == rw_opt_no_input_iterator)
test_assign_range (InputIter<UserClass>(0, 0, 0),
"InputIter<UserClass>");
else
rw_note (0, 0, __LINE__,
"template <class T> "
"std::deque<UserClass>::assign(T, T) [with T = InputIterator]"
"test disabled.");
if (0 == rw_opt_no_forward_iterator)
test_assign_range (FwdIter<UserClass>(), "FwdIter<UserClass>");
else
rw_note (0, 0, __LINE__,
"template <class T> "
"std::deque<UserClass>::assign(T, T) "
"[with T = ForwardIterator] test disabled.");
if (0 == rw_opt_no_bidirectional_iterator)
test_assign_range (BidirIter<UserClass>(), "BidirIter<UserClass>");
else
rw_note (0, 0, __LINE__,
"template <class T> "
"std::deque<UserClass>::assign(T, T) "
"[with T = BidirectionalIterator] test disabled.");
if (0 == rw_opt_no_random_iterator)
test_assign_range (RandomAccessIter<UserClass>(),
"RandomAccessIter<UserClass>");
else
rw_note (0, 0, __LINE__,
"template <class T> "
"std::deque<UserClass>::assign(T, T) "
"[with T = RandomAccessIterator] test disabled.");
}
/**************************************************************************/
void test_erase (int line,
const char *seq, std::size_t seqlen,
std::size_t begoff, std::size_t len,
const char *res, std::size_t reslen)
{
const UserClass* const xseq = UserClass::from_char (seq, seqlen + 1);
Deque deq = seqlen ? Deque (xseq, xseq + seqlen) : Deque ();
const Deque::iterator start = deq.begin () + begoff;
std::size_t n_copy = UserClass::n_total_copy_ctor_;
std::size_t n_asgn = UserClass::n_total_op_assign_;
char* funcall = 0;
std::size_t buflen = 0;
static const int cwidth = sizeof (*xseq);
if (std::size_t (-1) == len) { // erase(iterator)
rw_asnprintf (&funcall, &buflen,
"deque(\"%{X=*.*}\").erase(%{?}end()%{:}"
"%{?}begin () + %zu%{:}begin ()%{;}%{;}",
cwidth, seqlen, -1, xseq,
begoff == deq.size (), begoff, begoff);
exception_loop (line, Erase_1, funcall, 0,
deq, start, 1, 0, (UserClass*)0, (UserClass*)0,
&n_copy, &n_asgn);
}
else { // assign(size_type, const_reference)
const Deque::iterator end = start + len;
rw_asnprintf (&funcall, &buflen,
"deque(\"%{X=*.*}\").erase(%{?}end()%{:}"
"%{?}begin () + %zu%{:}begin ()%{;}%{;}"
"%{?})%{:}%{?}, end ())%{:}%{?}, begin ())"
"%{:}begin () + %zu%{;}%{;}%{;}",
cwidth, seqlen, -1, xseq,
begoff == deq.size (), begoff, begoff,
std::size_t (-1) == len,
end == deq.end (),
end == deq.begin (),
end - deq.begin ());
exception_loop (line, EraseRange, funcall, 0,
deq, start, int (len), 0,
(UserClass*)0, (UserClass*)0,
&n_copy, &n_asgn);
}
// verify the expected size of the deque after erasure
rw_assert (deq.size () == reslen, 0, line,
"line %d: %s: size == %zu, got %zu\n",
__LINE__, funcall, reslen, deq.size ());
// verify the expected contents of the deque after assignment
const Deque::const_iterator resbeg = deq.begin ();
const Deque::const_iterator resend = deq.end ();
for (Deque::const_iterator it = resbeg; it != resend; ++it) {
if ((*it).data_.val_ != UChar (res [it - resbeg])) {
char* const got = new char [deq.size () + 1];
for (Deque::const_iterator i = resbeg; i != resend; ++i) {
got [i - resbeg] = char ((*i).data_.val_);
}
got [deq.size ()] = '\0';
rw_assert (false, 0, line,
"line %d: %s: expected %s, got %s\n",
__LINE__, funcall, res, got);
delete[] got;
break;
}
}
#if 0
// set asnlen to the number of elements assigned to the container
if (0 <= nelems)
asnlen = std::size_t (nelems);
// verify the complexity of the operation in terms of the number
// of calls to the copy ctor and assignment operator on value_type
// the number of invocations of the copy ctor and the assignment
// operator depends on whether the implementation of assign()
// strictly follows the requirements in 23.2.1.1, p7 or p8 and
// destroys the existing elements before inserting the new ones,
// or whether it assigns the new elements over the existing ones
#ifndef _RWSTD_NO_EXT_DEQUE_ASSIGN_IN_PLACE
const std::size_t expect_copy = seqlen < asnlen ? asnlen - seqlen : 0;
const std::size_t expect_asgn = asnlen < seqlen ? asnlen : seqlen;
#else // if defined (_RWSTD_NO_EXT_DEQUE_ASSIGN_IN_PLACE)
const std::size_t expect_copy = asnlen;
const std::size_t expect_asgn = 0;
#endif // _RWSTD_NO_EXT_DEQUE_ASSIGN_IN_PLACE
rw_assert (n_copy == int (expect_copy), 0, line,
"line %d: %s: expected %zu invocations "
"of UserClass::UserClass(const UserClass&), got %d\n",
__LINE__, funcall, expect_copy, n_copy);
rw_assert (n_asgn == int (expect_asgn), 0, line,
"line %d: %s: expected %zu invocations "
"of UserClass::operator=(const UserClass&), got %d\n",
__LINE__, funcall, expect_asgn, n_asgn);
#endif
std::free (funcall);
// cast away constness to work around an HP aCC 6.16 bug
// see http://issues.apache.org/jira/browse/STDCXX-802
delete[] _RWSTD_CONST_CAST (UserClass*, xseq);
}
void test_erase ()
{
//////////////////////////////////////////////////////////////////
// exercise deque::erase(iterator)
rw_info (0, 0, 0, "std::deque<UserClass>::erase(iterator)");
#undef TEST
#define TEST(seq, off, res) do { \
test_erase (__LINE__, \
seq, sizeof seq - 1, \
std::size_t (off), \
std::size_t (-1), \
res, sizeof res - 1); \
} while (0)
TEST ("a", 0, "");
TEST ("ab", 0, "b");
TEST ("ab", 1, "a");
TEST ("abc", 0, "bc");
TEST ("abc", 1, "ac");
TEST ("abc", 2, "ab");
TEST ("abcd", 0, "bcd");
TEST ("abcd", 1, "acd");
TEST ("abcd", 2, "abd");
TEST ("abcd", 3, "abc");
TEST ("abcde", 0, "bcde");
TEST ("abcde", 1, "acde");
TEST ("abcde", 2, "abde");
TEST ("abcde", 3, "abce");
TEST ("abcde", 4, "abcd");
TEST ("abcdef", 0, "bcdef");
TEST ("abcdef", 1, "acdef");
TEST ("abcdef", 2, "abdef");
TEST ("abcdef", 3, "abcef");
TEST ("abcdef", 4, "abcdf");
TEST ("abcdef", 5, "abcde");
TEST ("abcdefg", 0, "bcdefg");
TEST ("abcdefg", 1, "acdefg");
TEST ("abcdefg", 2, "abdefg");
TEST ("abcdefg", 3, "abcefg");
TEST ("abcdefg", 4, "abcdfg");
TEST ("abcdefg", 5, "abcdeg");
TEST ("abcdefg", 6, "abcdef");
TEST ("abcdefgh", 0, "bcdefgh");
TEST ("abcdefgh", 1, "acdefgh");
TEST ("abcdefgh", 2, "abdefgh");
TEST ("abcdefgh", 3, "abcefgh");
TEST ("abcdefgh", 4, "abcdfgh");
TEST ("abcdefgh", 5, "abcdegh");
TEST ("abcdefgh", 6, "abcdefh");
TEST ("abcdefgh", 7, "abcdefg");
//////////////////////////////////////////////////////////////////
// exercise deque::erase(iterator, iterator)
rw_info (0, 0, 0, "std::deque<UserClass>::erase(iterator, iterator)");
}
/**************************************************************************/
#if !defined (_MSC_VER) || _MSC_VER > 1200
struct DR_438
{
static bool cast_used;
DR_438 () { }
explicit DR_438 (std::size_t) { cast_used = true; }
template <class T> DR_438 (T) { }
};
bool DR_438::cast_used;
#else // if MSVC <= 6.0
// avoid an MSVC 6.0 ICE on this code
# define NO_DR_438_TEST "this version of MSVC is too broken"
#endif // !MSVC || MSVC > 6.0
void test_dr_438 ()
{
//////////////////////////////////////////////////////////////////
// exercise the resolution of DR 438:
//////////////////////////////////////////////////////////////////
//
// For every sequence defined in clause [lib.containers]
// and in clause [lib.strings]:
// * If the constructor
//
// template <class InputIterator>
// UserClass (InputIterator f, InputIterator l,
// const allocator_type& a = allocator_type())
//
// is called with a type InputIterator that does not qualify
// as an input iterator, then the constructor will behave
// as if the overloaded constructor:
//
// UserClass (size_type, const value_type& = value_type(),
// const allocator_type& = allocator_type())
//
// were called instead, with the arguments static_cast<size_type>(f),
// l and a, respectively.
//
// * If the member functions of the forms:
//
// template <class InputIterator> // such as insert()
// rt fx1(iterator p, InputIterator f, InputIterator l);
//
// template <class InputIterator> // such as append(), assign()
// rt fx2(InputIterator f, InputIterator l);
//
// template <class InputIterator> // such as replace()
// rt fx3(iterator i1, iterator i2, InputIterator f, InputIterator l);
//
// are called with a type InputIterator that does not qualify
// as an input iterator, then these functions will behave
// as if the overloaded member functions:
//
// rt fx1(iterator, size_type, const value_type&);
//
// rt fx2(size_type, const value_type&);
//
// rt fx3(iterator, iterator, size_type, const value_type&);
//
// were called instead, with the same arguments.
//
// In the previous paragraph the alternative binding will fail
// if f is not implicitly convertible to UserClass::size_type or
// if l is not implicitly convertible to UserClass::value_type.
//
// The extent to which an implementation determines that a type
// cannot be an input iterator is unspecified, except that
// as a minimum integral types shall not qualify as input iterators.
//////////////////////////////////////////////////////////////////
rw_info (0, 0, 0, "resolution of DR 438");
#ifndef NO_DR_438_TEST
std::deque<DR_438, std::allocator<DR_438> > dq;
dq.assign (1, 2);
rw_assert (!DR_438::cast_used, 0, __LINE__,
"deque::assign(InputIterator, InputIterator)"
"[ with InputIterator = <integral type> ] unexpectedly "
"used explicit argument conversion");
dq.insert (dq.begin (), 1, 2);
rw_assert (!DR_438::cast_used, 0, __LINE__,
"deque::insert(iterator, InputIterator, InputIterator) "
"[ with InputIterator = <integral type> ] unexpectedly "
"used explicit argument conversion");
#else // if defined (NO_DR_438_TEST)
rw_warning (0, 0, __LINE__, "%s; skipping test", NO_DR_438_TEST);
#endif // NO_DR_438_TEST
}
/**************************************************************************/
int run_test (int, char**)
{
if (0 == rw_opt_no_dr438)
test_dr_438 ();
static const std::size_t caps[] = {
2, 3, 4, 5, 16, 32
};
for (std::size_t i = 0; i != sizeof caps / sizeof *caps; ++i) {
new_capacity = caps [i];
rw_info (0, 0, 0,
"__rw::__rw_new_capacity<std::deque<UserClass> >(0) = %zu",
_RW::__rw_new_capacity (0, (Deque*)0));
if (0 == rw_opt_no_assign)
test_assign ();
if (0 == rw_opt_no_erase)
test_erase ();
if (0 == rw_opt_no_insert)
test_insert ();
}
return 0;
}
/**************************************************************************/
int main (int argc, char** argv)
{
return rw_test (argc, argv, __FILE__,
"lib.deque.modifiers",
0 /* no comment */, run_test,
"|-no-dr438#"
"|-no-assign#"
"|-no-erase#"
"|-no-insert#"
"|-no-InputIterator#"
"|-no-ForwardIterator#"
"|-no-BidirectionalIterator#"
"|-no-RandomIterator#"
"|-no-right-thing#",
&rw_opt_no_dr438,
&rw_opt_no_assign,
&rw_opt_no_erase,
&rw_opt_no_insert,
&rw_opt_no_input_iterator,
&rw_opt_no_forward_iterator,
&rw_opt_no_bidirectional_iterator,
&rw_opt_no_random_iterator,
&rw_opt_no_right_thing);
}