const char* type_info::name () const { // silence warning: _C_name declared but never used #ifdef _RWSTD_NO_STD_TYPE_INFO _RWSTD_UNUSED (::_C_name); #else _RWSTD_UNUSED (std::_C_name); #endif // _RWSTD_NO_STD_TYPE_INFO return _C_name; }
static void test_max_size_ctor1 () { rw_info (0, __FILE__, __LINE__, "21.3.1, p7"); // establish a chekpoint for memory leaks rwt_check_leaks (0, 0); int thrown = 0; try { // throws std::out_of_range if n > max_size () (*) // (*) see also lwg issue 83 String s1 (s0.data (), s0.max_size () + 1); } catch (int id) { thrown = _RWSTD_ERROR_LENGTH_ERROR == id; } catch (...) { /* empty */ } std::size_t nbytes; /* uninitialized */ std::size_t nblocks = rwt_check_leaks (&nbytes, 0); _RWSTD_UNUSED (nblocks); rw_assert (1 == thrown, __FILE__, __LINE__, "string::string (const char_type*, size_type) " "failed to use __rw::__rw_throw()"); rw_assert (0 == nbytes, __FILE__, __LINE__, "string::string (const char_type*, size_type)" "leaked %u bytes", nbytes); rw_assert (s == s0, __FILE__, __LINE__, "original const string modified"); }
void test_std_swap () { static bool tested = false; if (tested) return; tested = true; rw_info (0, 0, 0, "Testing std::swap (std::list&, std::list&) " "calls std::list::swap"); // verify the signature of the function specialization void (*pswap)(ListType&, ListType&) = &std::swap<ListValueType, ListAllocator>; _RWSTD_UNUSED (pswap); // verify that std::swap() calls std::list::swap() ListType lst; std::swap (lst, lst); rw_assert (1 == list_swap_called, 0, __LINE__, "std::swap (std::list<T, A>&, std::list<T, A>&) called " "std::list<T, A>::swap (std::list<T, A>&) exactly once; " "got %d times", list_swap_called); }
bool is_forward (const Iterator &it) { _RWSTD_UNUSED (it); return is_forward_category (_RWSTD_ITERATOR_CATEGORY (Iterator, it)); }
static void test_replace3 () { rw_info (0, __FILE__, __LINE__, "21.3.5.6, p5"); int thrown = 0; String s1 (s0); const String::const_pointer s1_data = s1.data (); const String::size_type s1_size = s1.size (); const String::size_type s1_cap = s1.capacity (); // establish a chekpoint for memory leaks rwt_check_leaks (0, 0); try { // make sure max_size() isn't too big assert (s1.max_size () == _RWSTD_NEW_CAPACITY (String, &s1, 0)); thrown = -1; // must not throw String s2 (s1.max_size () - s1.size () + 2, Char ()); thrown = 0; // throws std::length_error if: // size () - xlen >= max_size () - rlen (*) // where xlen = min (n1, this->size () - pos1) // and rlen = min (n2, str.size () - pos2) // (*) see also lwg issue 86 s1.replace (0, 1, s2, 0, s2.size ()); } catch (int id) { thrown = 0 == thrown && _RWSTD_ERROR_LENGTH_ERROR == id; } catch (...) { /* empty */ } std::size_t nbytes; /* uninitialized */ std::size_t nblocks = rwt_check_leaks (&nbytes, 0); _RWSTD_UNUSED (nblocks); rw_assert (1 == thrown, __FILE__, __LINE__, "string::replace (size_type, size_type, const string&, " "size_type, size_type) failed to use __rw::__rw_throw()"); // verify that string wasn't modified rw_assert (s1_data == s1.data () && s1_size == s1.size () && s1_cap == s1.capacity (), __FILE__, __LINE__, "string::replace (size_type, size_type, const string&, " "size_type, size_type) modified *this"); // tests not only replace() but also string ctor (s2 above) rw_assert (1 == thrown, __FILE__, __LINE__, "string::replace (size_type, size_type, const string&, " "size_type, size_type) leaked %u bytes", nbytes); }
static void test_default_ctor () { rw_info (0, __FILE__, __LINE__, "default constructor"); std::tuple<> et; _RWSTD_UNUSED (et); // TODO: enable this test after implementing empty space optimization //rw_assert (sizeof (et) == 0, __FILE__, __LINE__, //"sizeof (std::tuple<>); got %u, expected 0", //sizeof (et)); std::tuple<int> it; _RWSTD_UNUSED (it); std::tuple<const int> ct; _RWSTD_UNUSED (ct); // ill-formed for tuples with element types containing references std::tuple<long, const char*> pt; _RWSTD_UNUSED (pt); std::tuple<std::tuple<int> > nt; _RWSTD_UNUSED (nt); std::tuple<bool, char, int, double, void*, UserDefined> bt; _RWSTD_UNUSED (bt); UserDefined::reset (); std::tuple<UserDefined> ut; _RWSTD_UNUSED (ut); rw_assert (1 == UserDefined::actual.dflt_ctor, __FILE__, __LINE__, "std::tuple<UserDefined> ut; called %d default ctors, " "expected 1", UserDefined::actual.dflt_ctor); }
static int run_test (int /*argc*/, char* /*argv*/ []) { const void* p = _RWSTD_STATIC_CAST (const void*, &std::ignore); _RWSTD_UNUSED (p); test_make_tuple (); test_tie (); test_tuple_cat (); return 0; }
static void test_homo_copy_assign () { rw_info (0, __FILE__, __LINE__, "copy assignment operator (homogenous tuples)"); const std::tuple<> et1 = std::tuple<> (); std::tuple<> et2; et2 = et1; _RWSTD_UNUSED (et2); int i = std::rand (); const std::tuple<int> it1 (i); std::tuple<int> it2; it2 = it1; test (__LINE__, it2, i); // copy assignment ill-formed for constant element types const std::tuple<int&> rt1 (i); int j = -1; // outside range of rand() std::tuple<int&> rt2 (j); // note, different reference rt2 = rt1; test (__LINE__, rt2, i); std::tuple<std::tuple<int> > nt1 (it1); std::tuple<std::tuple<int> > nt2; nt2 = nt1; test (__LINE__, nt2, it1); const std::tuple<long, const char*> pt1 (long (i), "string"); std::tuple<long, const char*> pt2; pt2 = pt1; test (__LINE__, pt2, long (i), (const char*) "string"); const UserDefined ud (i); const std::tuple<UserDefined> ut1 (ud); std::tuple<UserDefined> ut2; UserDefined::reset (); ut2 = ut1; ++UserDefined::expect.copy_asgn; test (__LINE__, ut2, ud); const std::tuple<bool, char, int, double, void*, UserDefined> bt1 (true, 'a', i, 3.14159, (void* const) &i, ud); ++UserDefined::expect.copy_ctor; std::tuple<bool, char, int, double, void*, UserDefined> bt2; ++UserDefined::expect.dflt_ctor; bt2 = bt1; ++UserDefined::expect.copy_asgn; test (__LINE__, bt2, true, 'a', i, 3.14159, (void* const) &i, ud); }
static void test_size_ctor () { rw_info (0, __FILE__, __LINE__, "21.3.1, p4 (size)"); // establish a chekpoint for memory leaks rwt_check_leaks (0, 0); int thrown = 0; try { // throws std::out_of_range if pos > str.size () String s1 (s0, s0.size () + 1); } #ifndef _RWSTD_NO_EXCEPTIONS catch (std::out_of_range&) { thrown = 1; } #else // if defined (_RWSTD_NO_EXCEPTIONS) catch (int id) { thrown = id == _RWSTD_ERROR_OUT_OF_RANGE; } #endif // _RWSTD_NO_EXCEPTIONS catch (...) { thrown = -1; } std::size_t nbytes; /* uninitialized */ std::size_t nblocks = rwt_check_leaks (&nbytes, 0); _RWSTD_UNUSED (nblocks); rw_assert (1 == thrown, __FILE__, __LINE__, ("string::string (const string&, size_type, size_type, " "const allocator_type&) failed to throw std::out_of_range")); rw_assert (s == s0, __FILE__, __LINE__, "original const string modified"); rw_assert (0 == nbytes, __FILE__, __LINE__, "string::string (const string&, size_type, size_type, " "const allocator_type&) leaked %u bytes", nbytes); }
static void test_homo_copy_ctor () { rw_info (0, __FILE__, __LINE__, "copy constructor (homogenous tuples)"); std::tuple<> et1, et2 (et1); _RWSTD_UNUSED (et2); const int ci = std::rand (); const std::tuple<int> it1 (ci); std::tuple<int> it2 (it1); test (__LINE__, it2, ci); const std::tuple<const int>& ct1 = it1; // same as copy ctor std::tuple<const int> ct2 (ct1); test (__LINE__, ct2, ci); int i = ci; const std::tuple<int&> rt1 (i); std::tuple<int&> rt2 (rt1); test (__LINE__, rt2, ci); const std::tuple<std::tuple<int> > nt1 (it1); std::tuple<std::tuple<int> > nt2 (nt1); test (__LINE__, nt2, it1); const std::tuple<long, const char*> pt1 (1234567890L, "string"); std::tuple<long, const char*> pt2 (pt1); test (__LINE__, pt2, 1234567890L, (const char*) "string"); UserDefined ud (ci); const std::tuple<UserDefined> ut1 (ud); UserDefined::reset (); std::tuple<UserDefined> ut2 (ut1); ++UserDefined::expect.copy_ctor; test (__LINE__, ut2, ud); const std::tuple<bool, char, int, double, void*, UserDefined> bt1 (true, 'a', ci, 3.14159, (void* const) &i, ud); ++UserDefined::expect.move_ctor; // moved ud to bt1 std::tuple<bool, char, int, double, void*, UserDefined> bt2 (bt1); ++UserDefined::expect.copy_ctor; // copied to bt2 test (__LINE__, bt2, true, 'a', ci, 3.14159, (void* const) &i, ud); }
static void test_homo_move_assign () { rw_info (0, __FILE__, __LINE__, "move assignment operator (homogenous tuples)"); std::tuple<> et1, et2; et2 = std::move (et1); _RWSTD_UNUSED (et2); int i = std::rand (); std::tuple<int> it1 (i); std::tuple<int> it2; it2 = std::move (it1); test (__LINE__, it2, i); // move assignment ill-formed for constant element types std::tuple<std::tuple<int> > nt1 (it2); std::tuple<std::tuple<int> > nt2; nt2 = std::move (nt1); test (__LINE__, nt2, it2); std::tuple<long, const char*> pt1 (1234567890L, "string"); std::tuple<long, const char*> pt2; pt2 = std::move (pt1); test (__LINE__, pt2, 1234567890L, (const char*) "string"); const UserDefined ud (i); std::tuple<UserDefined> ut1 (ud); std::tuple<UserDefined> ut2; UserDefined::reset (); ut2 = std::move (ut1); ++UserDefined::expect.move_asgn; test (__LINE__, ut2, ud); std::tuple<bool, char, int, double, void*, UserDefined> bt1 (true, 'a', i, 3.14159, (void* const) &i, ud); std::tuple<bool, char, int, double, void*, UserDefined> bt2; UserDefined::reset (); bt2 = std::move (bt1); ++UserDefined::expect.move_asgn; test (__LINE__, bt2, true, 'a', i, 3.14159, (void* const) &i, ud); }
static void* test_global (void*) { for (std::size_t i = 0; i != opt_nloops; ++i) { const std::size_t inx = i % nlocales; const std::locale last (std::locale::global (locales [inx])); _RWSTD_UNUSED (last); // FIXME: verify the consistency of the returned locale // by making sure that it matches the locale passed to // global() made by the last call to the function by // the last thread } return 0; }
static void test_homo_move_ctor () { rw_info (0, __FILE__, __LINE__, "move constructor (homogenous tuples)"); std::tuple<> et (std::tuple<> ()); _RWSTD_UNUSED (et); const int ci = std::rand (); std::tuple<int> it1 (ci); std::tuple<int> it2 (std::move (it1)); test (__LINE__, it2, ci); std::tuple<const int> ct1 (ci); std::tuple<const int> ct2 = std::move (ct1); test (__LINE__, ct2, ci); std::tuple<std::tuple<int> > nt1 (it1); std::tuple<std::tuple<int> > nt2 = std::move (nt1); test (__LINE__, nt2, it1); std::tuple<long, const char*> pt1 (1234567890L, "string"); std::tuple<long, const char*> pt2 (std::move (pt1)); test (__LINE__, pt2, 1234567890L, (const char*) "string"); const UserDefined ud (ci); std::tuple<UserDefined> ut1 (ud); UserDefined::reset (); std::tuple<UserDefined> ut2 (std::move (ut1)); ++UserDefined::expect.move_ctor; test (__LINE__, ut2, ud); std::tuple<bool, char, int, double, void*, UserDefined> bt1 (true, 'a', ci, 3.14159, (void*) &ci, ud); ++UserDefined::expect.copy_ctor; std::tuple<bool, char, int, double, void*, UserDefined> bt2 (std::move (bt1)); ++UserDefined::expect.move_ctor; test (__LINE__, bt2, true, 'a', ci, 3.14159, (void*) &ci, ud); }
static void* test_classic (void*) { static volatile int nthreads; // cast nthreads to int& (see STDCXX-792) // casting should be removed after fixing STDCXX-794 _RWSTD_ATOMIC_PREINCREMENT (_RWSTD_CONST_CAST (int&, nthreads), false); // spin until all threads have been created in order to icrease // the odds that at least two of them will hit the tested function // (and the lazy one-time initialization done by it) at the same // time while (nthreads < opt_nthreads); const std::locale classic (std::locale::classic ()); _RWSTD_UNUSED (classic); return 0; }
void test_std_swap () { rw_info (0, 0, 0, "Testing std::swap (std::deque&, std::deque&) " "calls std::deque::swap"); // verify the signature of the function specialization void (*pswap)(DequeType&, DequeType&) = &std::swap<DequeValueType, DequeAllocator>; _RWSTD_UNUSED (pswap); // verify that std::swap() calls std::deque::swap() DequeType d; std::swap (d, d); rw_assert (1 == deque_swap_called, 0, __LINE__, "std::swap (std::deque<T, A>&, std::deque<T, A>&) called " "std::deque<T, A>::swap (std::deque<T, A>&) exactly once; " "got %d times", deque_swap_called); }
static void test_npos_ctor () { rw_info (0, __FILE__, __LINE__, "21.3.1, p4 (npos)"); _RW::__rw_throw_proc = user_throw; // establish a chekpoint for memory leaks rwt_check_leaks (0, 0); int thrown = 0; try { // throws std::out_of_range if pos > str.size () String s1 (s0, String::npos); } catch (int id) { thrown = _RWSTD_ERROR_OUT_OF_RANGE == id; } catch (...) { /* empty */ } std::size_t nbytes; /* uninitialized */ std::size_t nblocks = rwt_check_leaks (&nbytes, 0); _RWSTD_UNUSED (nblocks); rw_assert (1 == thrown, __FILE__, __LINE__, "string::string (const string&, size_type, size_type, " "const allocator_type&) failed to use __rw::__rw_throw()"); rw_assert (0 == nbytes, __FILE__, __LINE__, "string::string (const string&, size_type, size_type, " "const allocator_type&) leaked %u bytes", nbytes); rw_assert (s == s0, __FILE__, __LINE__, "original const string modified"); }
void run_test (intT, thr_args_base::tag_t tag) { static const char* const tname = rw_any_t (intT ()).type_name (); if (!rw_enabled (tname)) { rw_note (0, 0, 0, "%s test disabled", tname); return; } #ifdef _RWSTD_REENTRANT static const char* const fun = "__rw_atomic_exchange"; rw_info (0, 0, 0, "__rw::%s (%s&, %2$s): %d iterations in %d threads", fun, tname, rw_opt_nloops, rw_opt_nthreads); rw_thread_t tid [MAX_THREADS]; typedef thr_args<intT> Args; Args::nthreads_ = unsigned (rw_opt_nthreads); Args::type_tag_ = tag; Args::nincr_ = unsigned (rw_opt_nloops); Args::shared_ [0] = intT (1); Args::shared_ [1] = intT (1); _RWSTD_ASSERT (Args::nthreads_ < sizeof tid / sizeof *tid); Args args [sizeof tid / sizeof *tid]; for (unsigned long i = 0; i != Args::nthreads_; ++i) { args [i].threadno_ = i; args [i].niter_ = 0; args [i].nxchg_ = 0; rw_fatal (0 == rw_thread_create (tid + i, 0, thread_routine, args + i), 0, __LINE__, "thread_create() failed"); } for (unsigned long i = 0; i != Args::nthreads_; ++i) { rw_error (0 == rw_thread_join (tid [i], 0), 0, __LINE__, "thread_join() failed"); if (args [i].niter_) { // compute the percantage of thread iterations that resulted // in increments of one of the shared variables const unsigned long incrpcnt = (100U * Args::nincr_) / args [i].niter_; printf ("thread %lu performed %lu exchanges in %lu iterations " "(%lu%% increments)\n", args [i].threadno_, args [i].nxchg_, args [i].niter_, incrpcnt); } } // compute the expected result, "skipping" zeros by incrementing // expect twice when it overflows and wraps around to 0 (zero is // used as the lock variable in thread_routine() above) intT expect = intT (1); const unsigned long nincr = (Args::nthreads_ * Args::nincr_) / 2U; for (unsigned long i = 0; i != nincr; ++i) { if (intT () == ++expect) ++expect; } // verify that the final value of the variables shared among all // threads equals the number of increments performed by the threads rw_assert (Args::shared_ [0] == expect, 0, __LINE__, "1. %s (%s&, %2$s); %s == %s failed", fun, tname, TOSTR (Args::shared_ [0]), TOSTR (expect)); rw_assert (Args::shared_ [1] == expect, 0, __LINE__, "2. %s (%s&, %2$s); %s == %s failed", fun, tname, TOSTR (Args::shared_ [1]), TOSTR (expect)); #else // if !defined (_RWSTD_REENTRANT) _RWSTD_UNUSED (tag); #endif // _RWSTD_REENTRANT }
const minus<T>& operator- (const minus<T>& lhs, const minus<T>& rhs) { _RWSTD_UNUSED(rhs); return lhs; }
void test_extractor (CharT*, Traits*, ArithmeticType*, const char *cname, const char *tname, const char *aname, int line, // printf formatting directive for ArithmeticType const char *valfmt, // character buffer (input sequence) const char *cbuf, // number of characters in buffer: std::size_t cbuf_size, // ctype and numpunct data const LocaleData &locale_data, // stream flags(): int flags, // initial stream rdstate(): int init_state, // unmasked exceptions: int exceptions, // expected exception: int expect_exception, // expected stream state after extraction: int expect_state, // expected number of extracted characters: int expect_extract, // have streambuf fail (or throw) after so many calls // to underflow() (each call extracts a single chracter): int fail_when, // initial value of the argument to extractor: ArithmeticType init_value, // expected value of the argument after extraction: ArithmeticType expect_value) { _RWSTD_UNUSED (cname); _RWSTD_UNUSED (tname); typedef std::basic_istream<CharT, Traits> Istream; typedef MyStreambuf<CharT, Traits> Streambuf; const char *fail_desc = 0; int fail_how = 0; if (fail_when < 0) { // have the stream buffer object's underflow() fail (by throwing // an exception if possible) after `fail_when' characters have // been extracted (this object calls underflow() for every char) fail_how = Underflow | Throw; fail_when = -fail_when; fail_desc = "threw"; } else if (0 < fail_when) { // have the stream buffer object's underflow() fail by returning // eof after `fail_when' characters have been extracted (this // object calls underflow() for every char) fail_how = Underflow; fail_desc = "returned EOF"; } // construct a stream buffer object and initialize its read sequence // with the character buffer Streambuf sb (cbuf, cbuf_size, fail_how, fail_when); // construct an istream object and initialize it with the user // defined streambuf object Istream is (&sb); if (-1 == flags) { // get the initial stream object's format control flags flags = is.flags (); } else { // set the stream object's format control flags is.flags (std::ios::fmtflags (flags)); } if (-1 == exceptions) { // get the initial stream object's exceptions exceptions = is.exceptions (); } else { // unmask the stream objects exceptions (must be done // before calling setstate() to prevent the latter from // throwing ios::failure) is.exceptions (std::ios::iostate (exceptions)); } if (-1 == init_state) { // get the initial stream object's state init_state = is.rdstate (); } else { // set the stream object's initial state #ifndef _RWSTD_NO_EXCEPTIONS try { is.setstate (std::ios::iostate (init_state)); } catch (...) { // ignore exceptions } #else // if defined ( _RWSTD_NO_EXCEPTIONS) is.setstate (std::ios::iostate (init_state)); #endif // _RWSTD_NO_EXCEPTIONS } // construct a locale object that treats only the specified `white' // characters as whitespace (all others are treated normally) const std::locale loc = is.imbue (make_locale ((CharT*)0, (Traits*)0, locale_data)); // imbue the previous locale into the stream buffer to verify that // the ws manipulator uses the locale imbued in the stream object // and not the one in the stream buffer sb.pubimbue (loc); // initialize the variable to the initial value to detect // the extractor setting it when it's not supposed to ArithmeticType value = init_value; // format the FUNCALL environment variable w/o writing out any output rw_fprintf (0, "%{$FUNCALL!:@}", "%{$CLASS}(%{*Ac}).operator>>(%s& = %{@}): " "initial flags() = %{If}, rdstate() = %{Is}, " "exceptions() = %{Is}, whitespace = %{#s}, numpunct = { " ".dp=%{#c}, .ts=%{#c}, .grp=%{#s}, .fn=%{#s}, .tn=%{#s} }", int (sizeof *cbuf), cbuf, aname, valfmt, init_value, flags, init_state, exceptions, locale_data.whitespace, locale_data.decimal_point, locale_data.thousands_sep, locale_data.grouping, locale_data.falsename, locale_data.truename); #ifndef _RWSTD_NO_EXCEPTIONS int caught = 0; try { is >> value; } catch (Exception&) { caught = 1; } catch (std::ios_base::failure &ex) { caught = 2; rw_assert (caught == expect_exception, 0, line, "line %d. %{$FUNCALL}: unexpectedly threw " "ios_base::failure(%{#s})", __LINE__, ex.what ()); } catch (...) { caught = -1; rw_assert (false, 0, line, "line %d. %{$FUNCALL}: unexpectely threw an exception " "of unknown type", __LINE__); } ////////////////////////////////////////////////////////////////// // verify that the function propagates exceptions thrown from the // streambuf object only when badbit is set in the stream object's // exceptions() rw_assert (caught == expect_exception, 0, line, "line %d. %{$FUNCALL}: " "%{?}failed to throw" "%{:}unexpectedly propagated" "%{;} exception", __LINE__, expect_exception); #else // if defined (_RWSTD_NO_EXCEPTIONS) is >> value; #endif // _RWSTD_NO_EXCEPTIONS // clear the text describing the type of failure when streambuf // didn't actually fail (or throw) if (sb.failed_ == None && sb.threw_ == None) fail_desc = 0; ////////////////////////////////////////////////////////////////// // verify that the expected number of characters have been // extracted from the stream const int extracted = int (sb.pubgptr () - sb.pubeback ()); rw_assert (expect_extract == extracted, 0, line, "%d. %{$FUNCALL}: expected to extract %d characters, " "got %d%{?} (underflow() %s at extraction %u)%{;}", __LINE__, expect_extract, extracted, 0 != fail_desc, fail_desc, fail_when); ////////////////////////////////////////////////////////////////// // verify that gcount() is not affected if (0 == opt_no_gcount) rw_assert (0 == is.gcount (), 0, line, "%d. %{$FUNCALL}: gcount() == 0, got %d " "%{?} (underflow() %s at extraction %u)%{;}", __LINE__, is.gcount (), 0 != fail_desc, fail_desc, fail_when); ////////////////////////////////////////////////////////////////// // verify the state of the stream object after the function call rw_assert (is.rdstate () == expect_state, 0, line, "line %d. %{$FUNCALL}: rdstate() == %{Is}, got %{Is}" "%{?} (underflow() %s at extraction %u)%{;}", __LINE__, expect_state, is.rdstate(), 0 != fail_desc, fail_desc, fail_when); ////////////////////////////////////////////////////////////////// // verify the extracted value matches the expected value rw_assert (expect_value == value, 0, line, "line %d. %{$FUNCALL}: expected value %{@}, got %{@}", __LINE__, valfmt, expect_value, valfmt, value); }
void test_assign (charT, const char *cname) { _RWSTD_UNUSED (cname); rw_info (0, 0, 0, "Assign member with string parameter"); typedef std::char_traits<charT> Traits; typedef std::allocator<charT> Allocator; typedef std::basic_string<charT, Traits, Allocator> String; typedef typename String::size_type size_type; #ifndef _RWSTD_NO_EXCEPTIONS { bool threw_error = false; String ts(Lit<charT>::testString), nl(Lit<charT>::abc); try { ts.assign(nl, nl.length() + 1, String::npos); } catch (std::out_of_range) { threw_error = true; } if(!(threw_error==true)) { failures++; std_log(LOG_FILENAME_LINE,"Reason: pos is too large"); } // Threw exception when pos too large rw_assert ((threw_error==true), 0, __LINE__, "A1"); } #endif // _RWSTD_NO_EXCEPTIONS /*{ String s1, s2, s3, nl; s1.assign(nl); s2.assign(nl, 0, 5); s3.assign(nl, 0, 0); // Assigned nullString to nullString #ifndef __SYMBIAN32__ rw_assert ((s1==nl) && (s2==nl) && (s3==nl), 0, __LINE__, "A2"); rw_assert ( String ().data () == s1.data () && String ().data () == s2.data () && String ().data () == s3.data (), 0, __LINE__, "A3"); #else if if(!((s1==nl) && (s2==nl) && (s3==nl))) { failures++; std_log(LOG_FILENAME_LINE,"Reason: Failing"); } // Correctly references nullString if(!(String ().data () == s1.data () //Result is same on linux && String ().data () == s2.data () && String ().data () == s3.data ())) { failures++; std_log(LOG_FILENAME_LINE,"Reason: Failing"); } #endif }*/ { String s1, s2, s3, s4, s5, ts(Lit<charT>::testString); s1.assign (ts); // Whole string s2.assign (ts, 0, 0); // None of the string s3.assign (ts, 0, 3); // First three letters s4.assign (ts, 5, 6); // Second word s5.assign (ts, 2, 2); // Middle // General Assignments rw_assert (s1 == ts, 0, __LINE__, "A4.1"); if(!(s1 == ts)) { failures++; std_log(LOG_FILENAME_LINE,"Reason: Failing"); } rw_assert (s2 == Lit<charT>::null, 0, __LINE__, "A4.2"); if(!(s2 == Lit<charT>::null)) { failures++; std_log(LOG_FILENAME_LINE,"Reason: Failing"); } rw_assert (s3 == Lit<charT>::tes, 0, __LINE__, "A4.3"); if(!(s3 == Lit<charT>::tes)) { failures++; std_log(LOG_FILENAME_LINE,"Reason: Failing"); } rw_assert (s4 == Lit<charT>::string, 0, __LINE__, "A4.4"); if(!(s4 == Lit<charT>::string) ) { failures++; std_log(LOG_FILENAME_LINE,"Reason: Failing"); } rw_assert (s5 == Lit<charT>::st, 0, __LINE__, "A4.5"); if(!(s5 == Lit<charT>::st) ) { failures++; std_log(LOG_FILENAME_LINE,"Reason: Failing"); } } rw_info (0, 0, 0, "Assign member with char pointer and maybe count"); { String s1, s2, s3; s1.assign (Lit<charT>::null); s2.assign (Lit<charT>::null, 0, 5); s3.assign (Lit<charT>::null, 0, 0); // Assigned nullString to nullString rw_assert ( (s1==Lit<charT>::null) && (s2==Lit<charT>::null) && (s3==Lit<charT>::null), 0, __LINE__, "A5"); if(!((s1==Lit<charT>::null)&& (s2==Lit<charT>::null)&& (s3==Lit<charT>::null))) { failures++; std_log(LOG_FILENAME_LINE,"Reason: Failing"); } // Correctly references nullString rw_assert ( String ().data () == s1.data () && String ().data () == s2.data () && String ().data () == s3.data (), 0, __LINE__, "A6"); if(( String ().data () == s1.data () && String ().data () == s2.data () && String ().data () == s3.data ())) { failures++; std_log(LOG_FILENAME_LINE,"Reason: Failing"); } } { const charT * ts = Lit<charT>::testString; String s1, s2, s3; s1.assign(ts); // Whole string s2.assign(ts, 0, 0); // None of the string s3.assign(ts, 0, 3); // First three letters // General Assignments rw_assert (s1 == ts && s2 == Lit<charT>::null && s3 == Lit<charT>::tes, 0, __LINE__, "A7"); if(!(s1 == ts && s2 == Lit<charT>::null && s3 == Lit<charT>::tes)) { failures++; std_log(LOG_FILENAME_LINE,"Reason: Failing"); } rw_info (0, 0, 0, "Assign member with char and repetition count"); { String s1; s1.assign(0, Lit<charT>::space[0]); // Assigned nullString to nullString rw_assert ((s1==Lit<charT>::null), 0, __LINE__, "A8"); if(!(s1==Lit<charT>::null)) { failures++; std_log(LOG_FILENAME_LINE,"Reason: Failing"); } // Correctly references nullString rw_assert (String ().data () == s1.data (), 0, __LINE__, "A9"); if((String ().data () == s1.data ())) { failures++; std_log(LOG_FILENAME_LINE,"Reason: Failing"); } } { String s1, s2, s3; s1.assign(1, Lit<charT>::x[0]); s2.assign(0, Lit<charT>::x[0]); s3.assign(3, Lit<charT>::x[0]); // General Assignments rw_assert ( (s1 == Lit<charT>::x) && (s2 == Lit<charT>::null) && (s3 == Lit<charT>::xxx), 0, __LINE__, "A10"); if(!((s1 == Lit<charT>::x) && (s2 == Lit<charT>::null) && (s3 == Lit<charT>::xxx))) { failures++; std_log(LOG_FILENAME_LINE,"Reason: Failing"); } } } }
// escape every occurrence of the double quote character in the string // pointed to by buf by prepending to it the escape character specified // by the last acrgument // returns the new buffer if the size of the existing buffer isn't // sufficient and sets *pbufsize to the size of the newly allocated // buffer, otherwise the original value of buf and leaves *pbufsize // unchanged static char* _rw_escape (char *buf, size_t bufsize, char esc) { // handle null buffer if (0 == buf) return buf; // count the number of embedded quotes char *quote = buf; size_t nquotes = 0; #ifdef __ARMCC__ #pragma diag_suppress 1293 #endif while ((quote = strchr (quote, '"'))) { ++nquotes; ++quote; } // no quotes found, return the original buffer if (0 == nquotes) return buf; // conpute the size of the buffer that will be needed to escape // all the double quotes size_t newbufsize = strlen (buf) + nquotes + 1; char *newbuf = 0; if (0 /* newbufsize <= bufsize */) { // FIXME: escape embedded quotes in place w/o reallocation _RWSTD_UNUSED (bufsize); } else { newbuf = (char*)malloc (newbufsize); if (0 == newbuf) { return 0; } // set the next pointer to the beginning of the new buffer // as the destination where to copy the string argument char *next = newbuf; // set quote to initially point to the beginning of // the source buffer and then just past the last quote quote = buf; for (char *q = buf; ; ++q) { // look for the next (or first) quote q = strchr (q, '"'); // compute the number of characters, excluding the quote // to copy to the destination buffer const size_t nchars = q ? size_t (q - quote) : strlen (quote); memcpy (next, quote, nchars); if (q) { // append the escape character to the destination buffer next [nchars] = esc; // append the quote from the source string next [nchars + 1] = '"'; // advance the destination pointer past the quote next += nchars + 2; // advance the source pointer past the embedded quote quote = q + 1; } else { // NUL-terminate the destination buffer *next = '\0'; break; } } } return newbuf; }
void do_test (int line, // line number of test case const char *src, // source sequence std::size_t resoff, // offset of result ForwardIterator dummy_iter, const T*, const char* predname) { static const char* const itname = type_name (dummy_iter, (T*)0); const std::size_t nsrc = std::strlen (src); if (std::size_t (-1) == resoff) resoff = nsrc; // have the UserClass default ctor initialize objects from `src' xinit_begin = src; UserClass::gen_ = xinit; UserClass* const xsrc = new UserClass [nsrc]; const ForwardIterator first = make_iter (xsrc, xsrc, xsrc + nsrc, dummy_iter); const ForwardIterator last = make_iter (xsrc + nsrc, xsrc, xsrc + nsrc, dummy_iter); // reset predicate counters UserClass::n_total_op_eq_ = 0; EqualityPredicate<T, T>::funcalls_ = 0; // construct a predicate object const EqualityPredicate<T, T> pred (0, 0); const ForwardIterator res = predname ? std::adjacent_find (first, last, pred) : std::adjacent_find (first, last); // silence a bogus EDG eccp remark #550-D: // variable "res" was set but never used _RWSTD_UNUSED (res); const std::size_t n_total_pred = predname ? EqualityPredicate<T, T>::funcalls_ : UserClass::n_total_op_eq_; // verify that the returned iterator is set as expected int success = res.cur_ == first.cur_ + resoff; rw_assert (success, 0, line, "line %d: adjacent_find<%s>(it = \"%s\", ...)" " == (it + %zu), got (it + %td)", __LINE__, itname, src, resoff, res.cur_ - first.cur_); // verify the number of applications of the predicate (lwg issue 240): // Complexity: For a nonempty range, exactly // min((i - first) + 1, (last - first) - 1) // applications of the corresponding predicate, where i is // adjacent_find's return value. // compute the expected number of invocations of the predicate std::size_t n_expect_pred = 0; if (nsrc) { // test iterators are guaranteed to be in range _RWSTD_ASSERT (first.cur_ <= res.cur_ && res.cur_ <= last.cur_); n_expect_pred = std::size_t (res.cur_ - first.cur_) + 1; const std::size_t tmp = std::size_t (last.cur_ - first.cur_) - 1; if (tmp < n_expect_pred) n_expect_pred = tmp; } success = std::size_t (n_expect_pred) == n_total_pred; rw_assert (success, 0, line, "line %d: adjacent_find<%s>(\"%s\", ...) " "invoked %s %zu times, expected %td", __LINE__, itname, src, predname ? predname : "operator==()", n_total_pred, n_expect_pred); }
void do_test (int line, // line number of test case const char *src, // source sequence std::size_t resoff, // offset of result ForwardIterator dummy_iter, const T*, const char* predicate) { static const char* const itname = type_name (dummy_iter, (T*)0); #ifdef __SYMBIAN32__ const size_t nsrc = strlen (src); #else const std::size_t nsrc = std::strlen (src); #endif //__SYMBIAN32__ if (std::size_t (-1) == resoff) resoff = nsrc; // have the X default ctor initialize objects from `src' xinit_begin = src; #ifndef __SYMBIAN32__ X::gen_ = xinit; #else gen_ = xinit; #endif X* const xsrc = new X [nsrc]; const ForwardIterator first = make_iter (xsrc, xsrc, xsrc + nsrc, dummy_iter); const ForwardIterator last = make_iter (xsrc + nsrc, xsrc, xsrc + nsrc, dummy_iter); // compute the number of invocations of the predicate #ifndef __SYMBIAN32__ std::size_t n_total_pred = X::n_total_op_eq_; #else std::size_t n_total_pred = n_total_op_eq_; #endif const ForwardIterator res = predicate ? std::adjacent_find (first, last, std::equal_to<X>()) : std::adjacent_find (first, last); // silence a bogus EDG eccp remark #550-D: // variable "res" was set but never used _RWSTD_UNUSED (res); #ifndef __SYMBIAN32__ n_total_pred =X::n_total_op_eq_ - n_total_pred; #else n_total_pred = n_total_op_eq_ - n_total_pred; #endif // verify that the returned iterator is set as expected int success = res.cur_ == first.cur_ + resoff; if(!success) { failures++; std_log(LOG_FILENAME_LINE,"Reason: Failing as expected iterator is not returned"); } rw_assert (success, 0, line, "line %d: adjacent_find<%s>(it = \"%s\", ...)" " == (it + %zu), got (it + %td)", __LINE__, itname, src, resoff, res.cur_ - first.cur_); // verify the number of applications of the predicate (lwg issue 240): // Complexity: For a nonempty range, exactly // min((i - first) + 1, (last - first) - 1) // applications of the corresponding predicate, where i is // adjacent_find's return value. // compute the expected number of invocations of the predicate std::size_t n_expect_pred = 0; if (nsrc) { // test iterators are guaranteed to be in range _RWSTD_ASSERT (first.cur_ <= res.cur_ && res.cur_ <= last.cur_); n_expect_pred = std::size_t (res.cur_ - first.cur_) + 1; const std::size_t tmp = std::size_t (last.cur_ - first.cur_) - 1; if (tmp < n_expect_pred) n_expect_pred = tmp; } success = std::size_t (n_expect_pred) == n_total_pred; if(!success) { failures ++; std_log(LOG_FILENAME_LINE,"Reason: Failing as iteratoris not in range"); } rw_assert (success, 0, line, "line %d: adjacent_find<%s>(\"%s\", ...) " "invoked %s %zu times, expected %td", __LINE__, itname, src, predicate ? predicate : "operator==()", n_total_pred, n_expect_pred); }
bool operator() (const T &a, const T &b) const { _RWSTD_UNUSED (a); _RWSTD_UNUSED (b); return true; }
const plus<T>& operator+ (const plus<T>& lhs, const plus<T>& rhs) { _RWSTD_UNUSED (rhs); return lhs; }