Return-Path: Delivered-To: apmail-incubator-stdcxx-commits-archive@www.apache.org Received: (qmail 55573 invoked from network); 7 Jun 2006 01:47:03 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (209.237.227.199) by minotaur.apache.org with SMTP; 7 Jun 2006 01:47:03 -0000 Received: (qmail 11283 invoked by uid 500); 7 Jun 2006 01:47:02 -0000 Delivered-To: apmail-incubator-stdcxx-commits-archive@incubator.apache.org Received: (qmail 11270 invoked by uid 500); 7 Jun 2006 01:47:02 -0000 Mailing-List: contact stdcxx-commits-help@incubator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: stdcxx-dev@incubator.apache.org Delivered-To: mailing list stdcxx-commits@incubator.apache.org Received: (qmail 11249 invoked by uid 99); 7 Jun 2006 01:47:02 -0000 Received: from asf.osuosl.org (HELO asf.osuosl.org) (140.211.166.49) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 06 Jun 2006 18:47:02 -0700 X-ASF-Spam-Status: No, hits=-9.4 required=10.0 tests=ALL_TRUSTED,NO_REAL_NAME X-Spam-Check-By: apache.org Received-SPF: pass (asf.osuosl.org: local policy) Received: from [140.211.166.113] (HELO eris.apache.org) (140.211.166.113) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 06 Jun 2006 18:47:01 -0700 Received: by eris.apache.org (Postfix, from userid 65534) id 1B2821A983A; Tue, 6 Jun 2006 18:46:41 -0700 (PDT) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r412250 - /incubator/stdcxx/trunk/tests/strings/21.string.replace.cpp Date: Wed, 07 Jun 2006 01:46:40 -0000 To: stdcxx-commits@incubator.apache.org From: sebor@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20060607014641.1B2821A983A@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org X-Spam-Rating: minotaur.apache.org 1.6.2 0/1000/N Author: sebor Date: Tue Jun 6 18:46:40 2006 New Revision: 412250 URL: http://svn.apache.org/viewvc?rev=412250&view=rev Log: 2006-06-06 Anton Pevtsov Martin Sebor * 21.string.replace.cpp: Added test cases. (ReplaceBase, ReplaceRange, ReplaceRangeOverload): New class templates to abstract out the invocation of the replace member template and its overloads. (test_replace): Added ReplaceBase& argument and eliminated test_replace_range (obviated by the addition of the argument). (test_replace): Dispatched to the appropriate specialization based on the iterator id (if any). Modified: incubator/stdcxx/trunk/tests/strings/21.string.replace.cpp Modified: incubator/stdcxx/trunk/tests/strings/21.string.replace.cpp URL: http://svn.apache.org/viewvc/incubator/stdcxx/trunk/tests/strings/21.string.replace.cpp?rev=412250&r1=412249&r2=412250&view=diff ============================================================================== --- incubator/stdcxx/trunk/tests/strings/21.string.replace.cpp (original) +++ incubator/stdcxx/trunk/tests/strings/21.string.replace.cpp Tue Jun 6 18:46:40 2006 @@ -25,13 +25,12 @@ * **************************************************************************/ -#include // for string -#include // for out_of_range, length_error -#include // for ptrdiff_t, size_t +#include // for string +#include // for out_of_range, length_error +#include // for ptrdiff_t, size_t #include <21.strings.h> #include // for InputIter -#include // for rw_enabled() #include // for rw_test() #include // for UserAlloc #include // for bad_alloc, replacement operator new @@ -556,13 +555,13 @@ TEST ("x@4096", 2047, 2048, "x@4096", 0, 2048, "x@4096", 0), TEST ("\0", 2, 0, "", 0, 0, "\0", 1), - TEST ("\0", 0, 0, "\0", 2, 0, "", 2), + TEST ("\0", 0, 0, "\0", 2, 0, "\0", 2), TEST ("a", 10, 0, "", 0, 0, "a", 1), - TEST ("a", 0, 0, "a", 10, 0, "", 2), + TEST ("a", 0, 0, "a", 10, 0, "a", 2), TEST ("x@4096", 4106, 0, "", 0, 0, "x@4096", 1), - TEST ("x@4096", 0, 0, "x@4096", 4106, 0, "", 2), + TEST ("x@4096", 0, 0, "x@4096", 4106, 0, "x@4096", 2), TEST ("a", 0, 1, "x@4096", 0, 4095, "x@4095", 0), @@ -717,90 +716,151 @@ /**************************************************************************/ +template +struct ReplaceBase { + typedef std::basic_string String; + typedef typename String::iterator StringIter; + + ReplaceBase () { } + + virtual ~ReplaceBase () { /* silence warnings */ } + + virtual String& + operator() (String &str, const StringTestCaseData&) const { + RW_ASSERT (!"logic error: should be never called"); + return str; + } +}; + +/**************************************************************************/ + +// invokes specializations of the member function template +// on the required iterator categories template -void test_replace_range (const StringTestCaseData &tdata, - Traits*, Allocator*, const Iterator &it) -{ - typedef std::basic_string String; - typedef typename String::iterator StringIter; +struct ReplaceRange: ReplaceBase { + typedef std::basic_string String; + typedef typename String::iterator StringIter; - const StringTestCase &tcase = tdata.tcase_; + ReplaceRange () { } - const char* const itname = - tcase.arg ? type_name (it, (charT*)0) : "basic_string::iterator"; + virtual String& + operator() (String &str, const StringTestCaseData& tdata) const { - // construct the string object to be modified - String str (tdata.str_, tdata.strlen_); + const StringTestCase &tcase = tdata.tcase_; + + // create a pair of iterators into the string object being modified + const StringIter first1 (str.begin () + tdata.off1_); + const StringIter last1 (first1 + tdata.ext1_); - // create a pair of iterators into the string object being modified - const StringIter first1 (str.begin () + tdata.off1_); - const StringIter last1 (first1 + tdata.ext1_); + const String &cstr = str; + + // when (0 == tcase.arg) exercise self-referential modification + // (i.e., replacing a range of elements with a subrange of its + // own elements) + const charT* const beg = + (tcase.arg ? tdata.arg_ : cstr.data ()) + tdata.off2_; - if (tcase.arg) { - const charT* const beg = tdata.arg_ + tdata.off2_; const charT* const end = beg + tdata.ext2_; const Iterator first2 (beg, beg, end); const Iterator last2 (end, beg, end); - str.replace (first1, last1, first2, last2); + return str.replace (first1, last1, first2, last2); } - else { - // self-referential modification (replacing a range - // of elements with a subrange of its own elements) - const StringIter first2 (str.begin () + tdata.off2_); - const StringIter last2 (first2 + tdata.ext2_); +}; + +/**************************************************************************/ - str.replace (first1, last1, first2, last2); +// invokes possible overloads of the member function template +// on common RandomAccessIterator types +template +struct ReplaceRangeOverload: ReplaceBase +{ + typedef std::basic_string String; + typedef typename String::pointer StringPtr; + typedef typename String::const_pointer StringConstPtr; + typedef typename String::iterator StringIter; + typedef typename String::const_iterator StringConstIter; + typedef typename String::reverse_iterator StringRevIter; + typedef typename String::const_reverse_iterator StringConstRevIter; + + ReplaceRangeOverload () { } + + static StringPtr + begin (String &str, StringPtr*) { + return _RWSTD_CONST_CAST (StringPtr, str.data ()); } - // detrmine whether the produced sequence matches the exepceted result - const std::size_t match = rw_match (tcase.res, str.data (), tcase.nres); + static StringConstPtr + begin (const String &str, StringConstPtr*) { + return str.data (); + } - rw_assert (match == tdata.reslen_, 0, tcase.line, - "line %d. %{$FUNCALL} expected %{#*s}, got %{/*.*Gs}, " - "difference at offset %zu for %s", - __LINE__, int (tcase.nres), tcase.res, - int (sizeof (charT)), int (str.size ()), str.c_str (), - match, itname); -} +#ifndef _RWSTD_NO_DEBUG_ITER -/**************************************************************************/ + // when debugging iterators are enabled string::iterator and + // string::pointer are distinct types; otherwise they are the + // same type + + static StringIter + begin (String &str, StringIter*) { + return str.begin (); + } -template -void test_replace_range (const StringTestCaseData &tdata, - Traits*, Allocator*) -{ - if (tdata.tcase_.bthrow) { - // FIXME: exercise exceptions - return; + static StringConstIter + begin (const String &str, StringConstIter*) { + return str.begin (); } - // exercise InputIterator *or* string::iterator (i.e., self - // referential modification), depending on the value of tcase.arg - test_replace_range (tdata, (Traits*)0, (Allocator*)0, - InputIter(0, 0, 0)); - - if (0 == tdata.tcase_.arg) { - // avoid exercising the same function multiple times - return; +#endif // _RWSTD_NO_DEBUG_ITER + + static StringRevIter + begin (String &str, StringRevIter*) { + return str.rbegin (); } - test_replace_range (tdata, (Traits*)0, (Allocator*)0, - ConstFwdIter(0, 0, 0)); + static StringConstRevIter + begin (const String &str, StringConstRevIter*) { + return str.rbegin (); + } - test_replace_range (tdata, (Traits*)0, (Allocator*)0, - ConstBidirIter(0, 0, 0)); + virtual String& + operator() (String &str, const StringTestCaseData& tdata) const { - test_replace_range (tdata, (Traits*)0, (Allocator*)0, - ConstRandomAccessIter(0, 0, 0)); -} + const StringTestCase &tcase = tdata.tcase_; + + // create a pair of iterators into the string object being modified + const StringIter first1 (str.begin () + tdata.off1_); + const StringIter last1 (first1 + tdata.ext1_); + + const std::size_t off = tdata.off2_; + const std::size_t ext = tdata.ext2_; + + if (0 == tcase.arg) { + // exercise self-referential modification (i.e., replacing + // a range of elements with a subrange of its own elements) + + const Iterator first2 (begin (str, (Iterator*)0) + off); + const Iterator last2 (first2 + ext); + + return str.replace (first1, last1, first2, last2); + } + + String str_arg (tdata.arg_, tdata.arglen_); + + const Iterator first2 (begin (str_arg, (Iterator*)0) + off); + const Iterator last2 (first2 + ext); + + return str.replace (first1, last1, first2, last2); + } +}; /**************************************************************************/ template void test_replace (charT*, Traits*, Allocator*, - const StringTestCaseData &tdata) + const ReplaceBase &rep, + const StringTestCaseData &tdata) { typedef std::basic_string String; typedef typename String::iterator StringIter; @@ -809,13 +869,6 @@ const StringFunc &func = tdata.func_; const StringTestCase &tcase = tdata.tcase_; - if (Replace (iter_iter_range) == func.which_) { - // special processing for the replace() template member - // function to exercise all iterator categories - test_replace_range (tdata, (Traits*)0, (Allocator*)0); - return; - } - // construct the string object to be modified // and the (possibly unused) argument string /* const */ String str (tdata.str_, tdata.strlen_); @@ -879,7 +932,7 @@ if (1 == tcase.bthrow && !use_iters) expected = exceptions [1]; // out_of_range - else if (2 == tcase.bthrow) + else if (2 == tcase.bthrow && !use_iters) expected = exceptions [1]; // out_of_range else if (3 == tcase.bthrow && !use_iters) expected = exceptions [2]; // length_error @@ -948,6 +1001,10 @@ ret_ptr = &str.replace (first, last, arg_size2, arg_val); break; + case Replace (iter_iter_range): + ret_ptr = &rep (str, tdata); + break; + default: RW_ASSERT (!"logic error: unknown replace overload"); } @@ -970,7 +1027,7 @@ "line %d. %{$FUNCALL} expected %{/*.*Gs} with " "length %zu, got %{/*.*Gs} with length %zu", __LINE__, - cwidth, int (tdata.reslen_), tdata.res_, + cwidth, int (tdata.reslen_), tdata.res_, tdata.reslen_, cwidth, int (str.size ()), str.data (), str.size ()); @@ -1074,19 +1131,90 @@ #else // if defined (_RWSTD_NO_REPLACEABLE_NEW_DELETE) const std::size_t expect_throws = StringIds::UserAlloc == func.alloc_id_ ? - str_state.capacity_ < str.capacity (): 0; + str_state.capacity_ < str.capacity () : 0; #endif // _RWSTD_NO_REPLACEABLE_NEW_DELETE - rw_assert (expect_throws == throw_count, 0, tcase.line, - "line %d: %{$FUNCALL}: expected exactly 1 %s exception " - "while changing capacity from %zu to %zu, got %zu", - __LINE__, exceptions [3], - str_state.capacity_, str.capacity (), throw_count); + // verify number of exceptions thrown + // for range version the allocation may take place several times + if (Replace (iter_iter_range) != func.which_) + rw_assert (expect_throws == throw_count, 0, tcase.line, + "line %d: %{$FUNCALL}: expected exactly 1 %s exception " + "while changing capacity from %zu to %zu, got %zu", + __LINE__, exceptions [3], + str_state.capacity_, str.capacity (), throw_count); + else + rw_assert (expect_throws <= throw_count, 0, tcase.line, + "line %d: %{$FUNCALL}: expected at least 1 %s exception " + "while changing capacity from %zu to %zu, got %zu", + __LINE__, exceptions [3], + str_state.capacity_, str.capacity (), throw_count); // disable bad_alloc exceptions *pst->throw_at_calls_ [0] = 0; pal->throw_at_calls_ [pal->m_allocate] = 0; +} + +/**************************************************************************/ + +template +void test_replace (charT*, Traits*, Allocator*, + const StringTestCaseData &tdata) +{ + if (tdata.func_.which_ == Replace (iter_iter_range)) { + + typedef std::basic_string String; + + switch (tdata.func_.iter_id_) { + + // exercise possible overloads of the member function template + // on common RandomAccessIterator types +#undef TEST +#define TEST(Iterator) do { \ + typedef typename String::Iterator Iter; \ + static const \ + ReplaceRangeOverload rep; \ + test_replace ((charT*)0, (Traits*)0, (Allocator*)0, rep, tdata); \ + } while (0) + + case StringIds::Pointer: TEST (pointer); break; + case StringIds::ConstPointer: TEST (const_pointer); break; + case StringIds::Iterator: TEST (iterator); break; + case StringIds::ConstIterator: TEST (const_iterator); break; + + // disabled for now + case StringIds::ReverseIterator: + // TEST (reverse_iterator); + break; + + case StringIds::ConstReverseIterator: + // TEST (const_reverse_iterator); + break; + + // exercise specializations of the member function template + // on the required iterator categories +#undef TEST +#define TEST(Iterator) do { \ + typedef Iterator Iter; \ + static const \ + ReplaceRange rep; \ + test_replace ((charT*)0, (Traits*)0, (Allocator*)0, rep, tdata); \ + } while (0) + + case StringIds::Input: TEST (InputIter); break; + case StringIds::Forward: TEST (ConstFwdIter); break; + case StringIds::Bidir: TEST (ConstBidirIter); break; + case StringIds::Random: TEST (ConstRandomAccessIter); break; + + default: + rw_error (0, 0, __LINE__, "bad iterator id"); + } + } + else { + // exercise ordinary overloads of the member function + static const ReplaceBase rep; + test_replace ((charT*)0, (Traits*)0, (Allocator*)0, rep, tdata); + } } /**************************************************************************/