Return-Path: Delivered-To: apmail-incubator-stdcxx-dev-archive@www.apache.org Received: (qmail 70333 invoked from network); 25 Apr 2006 15:12:43 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (209.237.227.199) by minotaur.apache.org with SMTP; 25 Apr 2006 15:12:43 -0000 Received: (qmail 14575 invoked by uid 500); 25 Apr 2006 15:12:42 -0000 Delivered-To: apmail-incubator-stdcxx-dev-archive@incubator.apache.org Received: (qmail 14561 invoked by uid 500); 25 Apr 2006 15:12:42 -0000 Mailing-List: contact stdcxx-dev-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-dev@incubator.apache.org Received: (qmail 14550 invoked by uid 99); 25 Apr 2006 15:12:42 -0000 Received: from asf.osuosl.org (HELO asf.osuosl.org) (140.211.166.49) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 25 Apr 2006 08:12:42 -0700 X-ASF-Spam-Status: No, hits=-0.0 required=10.0 tests=SPF_PASS X-Spam-Check-By: apache.org Received-SPF: pass (asf.osuosl.org: domain of AntonP@moscow.vdiweb.com designates 195.210.189.132 as permitted sender) Received: from [195.210.189.132] (HELO exmsk.moscow.vdiweb.com) (195.210.189.132) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 25 Apr 2006 08:12:41 -0700 Received: from [10.11.0.132] ([10.11.0.132]) by exmsk.moscow.vdiweb.com with Microsoft SMTPSVC(6.0.3790.1830); Tue, 25 Apr 2006 19:12:14 +0400 Message-ID: <444E3C6F.2070006@moscow.vdiweb.com> Date: Tue, 25 Apr 2006 19:12:47 +0400 From: Anton Pevtsov User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.7) Gecko/20040514 X-Accept-Language: en-us, en MIME-Version: 1.0 To: stdcxx-dev@incubator.apache.org Subject: test for 21.string.op.plus.eq Content-Type: multipart/mixed; boundary="------------080404060705060504030402" X-OriginalArrivalTime: 25 Apr 2006 15:12:14.0080 (UTC) FILETIME=[A20E9000:01C6687A] X-Virus-Checked: Checked by ClamAV on apache.org X-Spam-Rating: minotaur.apache.org 1.6.2 0/1000/N --------------080404060705060504030402 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit The updated test for lib.string.op.plus.eq is attached. Also I added necessary data to 21.strings.h and 21.strings.cpp, diff files are attached too. Change Log: 2006-04-25 Anton Pevtsov * 21.strings.h (SignatureId): Added missed signature sig_val. (MemberId): Added new element mem_op_plus_eq. (OverloadId): Added new elements for += overloads. * 21.strings.cpp (setvars): Updated to support += overloads, minor formatting bugs fixed. I see small issue with MemberId enum: we have more than 15 methods to be tested. For example, there are six versions of find methods: find, rfind, find_first_of, etc. I think it is possible to use something like this: mem_find = 9 << 11, mem_rfind = 10 << 11, etc, to identify each method in the group of similar methods. I'll update tests for find methods using this way, OK? Thanks, Anton Pevtsov --------------080404060705060504030402 Content-Type: text/plain; name="21.strings.h.diff" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="21.strings.h.diff" Index: 21.strings.h =================================================================== --- 21.strings.h (revision 396881) +++ 21.strings.h (working copy) @@ -78,6 +78,8 @@ sig_size_size_str_size_size, // (size_type, size_type, size_type, value_type) sig_size_size_size_val, + // (value_type) + sig_val, // (InputIterator, InputIterator) sig_range, // (iterator, value_type) @@ -102,13 +104,15 @@ }; enum MemberId { - mem_append = 1 << 5, - mem_assign = 1 << 6, - mem_erase = 1 << 7, - mem_insert = 1 << 8, - mem_replace = 1 << 9, - mem_mask = - mem_append | mem_assign | mem_erase | mem_insert | mem_replace + mem_append = 1 << 5, + mem_assign = 1 << 6, + mem_erase = 1 << 7, + mem_insert = 1 << 8, + mem_replace = 1 << 9, + mem_op_plus_eq = 1 << 10, + mem_mask = + mem_append | mem_assign | mem_erase | mem_insert | + mem_replace | mem_op_plus_eq }; // unique identifiers for all overloads of each member function @@ -189,7 +193,14 @@ // (iterator, iterator, size_type, value_type) replace_iter_iter_size_val = mem_replace + sig_iter_iter_size_val, // (iterator, iterator, InputIterator, InputIterator) - replace_iter_iter_range = mem_replace + sig_iter_iter_range + replace_iter_iter_range = mem_replace + sig_iter_iter_range, + + // operator += (const charT* s) + op_plus_eq_ptr = mem_op_plus_eq + sig_ptr, + // operator += (const basic_string& str) + op_plus_eq_str = mem_op_plus_eq + sig_str, + // operator += (charT c) + op_plus_eq_val = mem_op_plus_eq + sig_val }; struct Function { --------------080404060705060504030402 Content-Type: text/plain; name="21.strings.cpp.diff" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="21.strings.cpp.diff" Index: 21.strings.cpp =================================================================== --- 21.strings.cpp (revision 396881) +++ 21.strings.cpp (working copy) @@ -122,6 +122,8 @@ fname ="insert"; else if (fun.which_ & mem_replace) fname ="replace"; + else if (fun.which_ & mem_op_plus_eq) + fname ="operator +="; free (buf); buf = 0; @@ -152,6 +154,7 @@ "size_type, size_type, const value_type*, size_type", "size_type, size_type, const value_type*, size_type, size_type", "size_type, size_type, size_type, value_type", + "value_type", "InputIterator, InputIterator", "iterator, value_type", "iterator, size_type, value_type", @@ -189,6 +192,7 @@ switch (fun.which_) { case append_ptr: case assign_ptr: + case op_plus_eq_ptr: rw_asnprintf (&buf, &bufsize, "%{+}(%{?}%{#*s}%{;}%{?}this->c_str ()%{;})", !self, int (pcase->arg_len), pcase->arg, self); @@ -196,6 +200,7 @@ case append_str: case assign_str: + case op_plus_eq_str: rw_asnprintf (&buf, &bufsize, "%{+}(%{?}string (%{#*s})%{;}%{?}*this%{;})", !self, int (pcase->arg_len), pcase->arg, self); @@ -220,13 +225,13 @@ case append_size_val: case assign_size_val: rw_asnprintf (&buf, &bufsize, - "%{+} %s (%zu, %#c)", pcase->size, pcase->val); + "%{+} (%zu, %#c)", pcase->size, pcase->val); break; case append_range: case assign_range: rw_asnprintf (&buf, &bufsize, "%{+}(" - "%{?}%{#*s}%{;}%{?}this->%{;}begin() + %zu, " + "%{?}%{#*s}%{;}%{?}this->%{;}.begin() + %zu, " "%{?}%{#*s}%{;}%{?}this->%{;}.begin() + %zu)", !self, int (pcase->arg_len), pcase->arg, self, pcase->off, !self, int (pcase->arg_len), pcase->arg, @@ -361,6 +366,11 @@ pcase->off2 + pcase->size2); break; + case op_plus_eq_val: + rw_asnprintf (&buf, &bufsize, + "%{+} (%#c)", pcase->val); + break; + default: RW_ASSERT (!"test logic error: unknown overload"); } --------------080404060705060504030402 Content-Type: text/plain; name="21.string.op.plus.equal.cpp" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="21.string.op.plus.equal.cpp" /*************************************************************************** * * 21.string.plus.equal.cpp - test exercising [lib.string.op+=] * * $Id: 21.string.op.plus.equal.cpp 368132 2006-01-11 21:14:52Z sebor $ * *************************************************************************** * * Copyright 2006 The Apache Software Foundation or its licensors, * as applicable. * * Copyright 2006 Rogue Wave Software. * * Licensed 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. * **************************************************************************/ #include // for placement operator new() #include // for string #include // for free(), size_t #include // for out_of_range, length_error #include // for rw_enabled() #include // for rw_test() #include // for rw_asnprintf() #include // for rw_widen() #include // for InputIter<> #include <21.strings.h> #ifndef _RWSTD_NO_REPLACEABLE_NEW_DELETE // disabled for compilers such as IBM VAC++ or MSVC // that can't reliably replace the operators # include #else # include #endif // _RWSTD_NO_REPLACEABLE_NEW_DELETE #define OpPlusEqOverload StringMembers::OverloadId #define OpPlusEq(which) StringMembers::op_plus_eq_ ## which typedef StringMembers::TestCase TestCase; typedef StringMembers::Test Test; typedef StringMembers::Function MemFun; /**************************************************************************/ // for convenience and brevity #define LSTR long_string #define LLEN long_string_len static const std::size_t long_string_len = 4096; static char long_string [long_string_len]; static const char* const exceptions[] = { "unknown exception", "out_of_range", "length_error", "bad_alloc", "exception" }; // used to exercise // operator += (const charT* s) static const TestCase ptr_test_cases [] = { #undef TEST #define TEST(str, src, res, bthrow) \ { __LINE__, -1, -1, -1, -1, -1, str, sizeof str - 1, src, \ sizeof src - 1, res, sizeof res - 1, bthrow } // +----------------------------------------- controlled sequence // | +--------------------------- sequence to be appended // | | +------------- expected result sequence // | | | +---- exception info // | | | | 0 - no exception // | | | | 1 - length_error // | | | | -1 - exc. safety // | | | | // | | | +--------------+ // V V V V TEST ("ab", "c", "abc", 0), TEST ("", "", "", 0), TEST ("", "\0", "", 0), TEST ("", "abc", "abc", 0), TEST ("\0", "", "\0", 0), TEST ("\0", "a", "\0a", 0), TEST ("\0", "\0\0", "\0", 0), TEST ("ab", "cd", "abcd", 0), TEST ("bcd", "a", "bcda", 0), TEST ("cde", "ab", "cdeab", 0), TEST ("abc", "", "abc", 0), TEST ("ab", "c\0e", "abc", 0), TEST ("\0\0ab", "cdefghij", "\0\0abcdefghij", 0), TEST ("a\0\0b", "cdefghij", "a\0\0bcdefghij", 0), TEST ("ab\0\0", "cdefghij", "ab\0\0cdefghij", 0), TEST ("a\0b\0\0c", "e\0", "a\0b\0\0ce", 0), TEST ("\0ab\0\0c", "e\0", "\0ab\0\0ce", 0), TEST ("abcdefghij", "abcdefghij", "abcdefghijabcdefghij", 0), TEST ("", LSTR, LSTR, 0), TEST (LSTR, "", LSTR, 0), TEST ("", 0, "", 0), TEST ("abc", 0, "abcabc", 0), TEST ("a\0\0bc", 0, "a\0\0bca", 0), TEST ("\0\0abc", 0, "\0\0abc", 0), TEST ("abc\0\0", 0, "abc\0\0abc", 0), TEST ("", LSTR, LSTR, -1), TEST ("last", "test", "lasttest", 0) }; /**************************************************************************/ // used to exercise // operator += (const basic_string& str) static const TestCase str_test_cases [] = { #undef TEST #define TEST(str, src, res, bthrow) \ { __LINE__, -1, -1, -1, -1, -1, str, sizeof str - 1, src, \ sizeof src - 1, res, sizeof res - 1, bthrow } // +----------------------------------------- controlled sequence // | +------------------------- sequence to be appended // | | +------------- expected result sequence // | | | +---- exception info // | | | | 0 - no exception // | | | | 1 - length_error // | | | | -1 - exc. safety // | | | | // | | | +--------------+ // V V V V TEST ("ab", "c", "abc", 0), TEST ("", "", "", 0), TEST ("", "\0", "\0", 0), TEST ("", "abc", "abc", 0), TEST ("\0", "", "\0", 0), TEST ("\0", "a", "\0a", 0), TEST ("\0", "\0\0", "\0\0\0", 0), TEST ("ab", "cd", "abcd", 0), TEST ("bcd", "a", "bcda", 0), TEST ("cde", "ab", "cdeab", 0), TEST ("abc", "", "abc", 0), TEST ("ab", "c\0e", "abc\0e", 0), TEST ("\0\0ab", "cdefghij", "\0\0abcdefghij", 0), TEST ("a\0\0b", "cdefghij", "a\0\0bcdefghij", 0), TEST ("ab\0\0", "cdefghij", "ab\0\0cdefghij", 0), TEST ("a\0b\0\0c", "e\0", "a\0b\0\0ce\0", 0), TEST ("\0ab\0\0c", "e\0", "\0ab\0\0ce\0", 0), TEST ("ab\0\0c\0", "\0e", "ab\0\0c\0\0e", 0), TEST ("abcdefghij", "abcdefghij", "abcdefghijabcdefghij", 0), TEST ("", LSTR, LSTR, 0), TEST (LSTR, "", LSTR, 0), TEST ("", 0, "", 0), TEST ("abc", 0, "abcabc", 0), TEST ("a\0\0bc", 0, "a\0\0bca\0\0bc", 0), TEST ("\0\0abc", 0, "\0\0abc\0\0abc", 0), TEST ("abc\0\0", 0, "abc\0\0abc\0\0", 0), TEST ("", LSTR, LSTR, -1), TEST ("last", "test", "lasttest", 0) }; /**************************************************************************/ // used to exercise // operator += (charT c) static const TestCase val_test_cases [] = { #undef TEST #define TEST(str, val, res, bthrow) \ { __LINE__, -1, -1, -1, -1, val, str, sizeof str - 1, 0, 0, \ res, sizeof res - 1, bthrow } // +---------------------------------- controlled sequence // | +--------------------- character to be appended // | | +----------------- expected result sequence // | | | +----- exception info // | | | | 0 - no exception // | | | | 1 - length_error // | | | | -1 - exc. safety // | | | | // | | | +----+ // V V V V TEST ("ab", 'c', "abc", 0), TEST ("", 'a', "a", 0), TEST ("", '\0', "\0", 0), TEST ("\0", 'a', "\0a", 0), TEST ("\0", '\0', "\0\0", 0), TEST ("cde", 'a', "cdea", 0), TEST ("abc", '\0', "abc\0", 0), TEST ("a\0b\0\0c", '\0', "a\0b\0\0c\0", 0), TEST ("\0ab\0\0c", '\0', "\0ab\0\0c\0", 0), TEST ("a\0bc\0\0", 'a', "a\0bc\0\0a", 0), TEST ("last", 't', "lastt", 0) }; /**************************************************************************/ template void test_op_plus_eq (charT, Traits*, OpPlusEqOverload which, const TestCase &cs) { typedef std::allocator Allocator; typedef std::basic_string TestString; typedef typename TestString::iterator StringIter; typedef typename TestString::const_iterator ConstStringIter; static charT wstr [LLEN]; static charT warg [LLEN]; rw_widen (wstr, cs.str, cs.str_len); rw_widen (warg, cs.arg, cs.arg_len); TestString s_str (wstr, cs.str_len); TestString s_arg (warg, cs.arg_len); std::size_t res_off = 0; std::size_t throw_after = 0; const std::size_t size = s_str.size (); const std::size_t capacity = s_str.capacity (); const ConstStringIter begin = s_str.begin (); const charT* const arg_ptr = cs.arg ? warg : s_str.c_str (); const TestString& arg_str = cs.arg ? s_arg : s_str; const charT arg_val = make_char (char (cs.val), (charT*)0); #ifndef _RWSTD_NO_REPLACEABLE_NEW_DELETE rwt_free_store* const pst = rwt_get_free_store (0); #endif // _RWSTD_NO_REPLACEABLE_NEW_DELETE // iterate for`n=throw_after' starting at the next call to operator // new, forcing each call to throw an exception, until the appendion // finally succeeds (i.e, no exception is thrown) for ( ; ; ) { #ifndef _RWSTD_NO_EXCEPTIONS # ifndef _RWSTD_NO_REPLACEABLE_NEW_DELETE if (-1 == cs.bthrow) *pst->throw_at_calls_ [0] = pst->new_calls_ [0] + throw_after + 1; # endif // _RWSTD_NO_REPLACEABLE_NEW_DELETE #endif // _RWSTD_NO_EXCEPTIONS #ifndef _RWSTD_NO_EXCEPTIONS // is some exception expected ? const char* expected = 0; if (1 == cs.bthrow) expected = exceptions [2]; // length_error if (-1 == cs.bthrow) expected = exceptions [3]; // bad_alloc const char* caught = 0; #else // if defined (_RWSTD_NO_EXCEPTIONS) if (cs.bthrow) return; #endif // _RWSTD_NO_EXCEPTIONS try { switch (which) { case OpPlusEq (ptr): { const TestString& s_res = s_str += arg_ptr; res_off = &s_res - &s_str; break; } case OpPlusEq (str): { const TestString& s_res = s_str += arg_str; res_off = &s_res - &s_str; break; } case OpPlusEq (val): { const TestString& s_res = s_str += arg_val; res_off = &s_res - &s_str; break; } default: RW_ASSERT ("test logic error: unknown operator += overload"); return; } // verify the returned value rw_assert (0 == res_off, 0, cs.line, "line %d. %{$FUNCALL} returned invalid reference, " "offset is %zu", __LINE__, res_off); // verfiy that strings length are equal rw_assert (cs.res_len == s_str.size (), 0, cs.line, "line %d. %{$FUNCALL} expected %{#*s} " "with length %zu, got %{/*.*Gs} with length %zu", __LINE__, int (cs.res_len), cs.res, cs.res_len, int (sizeof (charT)), int (s_str.size ()), s_str.c_str (), s_str.size ()); if (cs.res_len == s_str.size ()) { // if the result length matches the expected length // (and only then), also verify that the modified // string matches the expected result const std::size_t match = rw_match (cs.res, s_str.c_str(), cs.res_len); rw_assert (match == cs.res_len, 0, cs.line, "line %d. %{$FUNCALL} expected %{#*s}, " "got %{/*.*Gs}, difference at offset %zu", __LINE__, int (cs.res_len), cs.res, int (sizeof (charT)), int (s_str.size ()), s_str.c_str (), match); } } #ifndef _RWSTD_NO_EXCEPTIONS catch (const std::length_error &ex) { caught = exceptions [2]; rw_assert (caught == expected, 0, cs.line, "line %d. %{$FUNCALL} %{?}expected %s,%{:}" "unexpectedly%{;} caught std::%s(%#s)", __LINE__, 0 != expected, expected, caught, ex.what ()); } catch (const std::bad_alloc &ex) { caught = exceptions [3]; rw_assert (-1 == cs.bthrow, 0, cs.line, "line %d. %{$FUNCALL} %{?}expected %s,%{:}" "unexpectedly%{;} caught std::%s(%#s)", __LINE__, 0 != expected, expected, caught, ex.what ()); } catch (const std::exception &ex) { caught = exceptions [4]; rw_assert (0, 0, cs.line, "line %d. %{$FUNCALL} %{?}expected %s,%{:}" "unexpectedly%{;} caught std::%s(%#s)", __LINE__, 0 != expected, expected, caught, ex.what ()); } catch (...) { caught = exceptions [0]; rw_assert (0, 0, cs.line, "line %d. %{$FUNCALL} %{?}expected %s,%{:}" "unexpectedly%{;} caught %s", __LINE__, 0 != expected, expected, caught); } #else // if defined (_RWSTD_NO_EXCEPTIONS) _RWSTD_UNUSED (should_throw); #endif // _RWSTD_NO_EXCEPTIONS if (caught) { // verify that an exception thrown during allocation // didn't cause a change in the state of the object rw_assert (s_str.size () == size, 0, cs.line, "line %d: %{$FUNCALL}: size unexpectedly changed " "from %zu to %zu after an exception", __LINE__, size, s_str.size ()); rw_assert (s_str.capacity () == capacity, 0, cs.line, "line %d: %{$FUNCALL}: capacity unexpectedly " "changed from %zu to %zu after an exception", __LINE__, capacity, s_str.capacity ()); rw_assert (s_str.begin () == begin, 0, cs.line, "line %d: %{$FUNCALL}: begin() unexpectedly " "changed from after an exception by %d", __LINE__, s_str.begin () - begin); if (-1 == cs.bthrow) { // increment to allow this call to operator new to succeed // and force the next one to fail, and try calling the same // function again ++throw_after; continue; } } else if (-1 != cs.bthrow) { rw_assert (caught == expected, 0, cs.line, "line %d. %{$FUNCALL} %{?}expected %s, caught %s" "%{:}unexpectedly caught %s%{;}", __LINE__, 0 != expected, expected, caught, caught); } break; } #ifndef _RWSTD_NO_EXCEPTIONS # ifndef _RWSTD_NO_REPLACEABLE_NEW_DELETE // verify that if exceptions are enabled and when capacity changes // at least one exception is thrown rw_assert ( *pst->throw_at_calls_ [0] == std::size_t (-1) || throw_after, 0, cs.line, "line %d: %{$FUNCALL}: failed to throw an expected exception", __LINE__); *pst->throw_at_calls_ [0] = std::size_t (-1); # endif // _RWSTD_NO_REPLACEABLE_NEW_DELETE #else // if defined (_RWSTD_NO_EXCEPTIONS) _RWSTD_UNUSED (size); _RWSTD_UNUSED (capacity); _RWSTD_UNUSED (throw_after); #endif // _RWSTD_NO_EXCEPTIONS } /**************************************************************************/ DEFINE_TEST_DISPATCH (test_op_plus_eq); static int run_test (int, char*[]) { if ('\0' == LSTR [0]) { // initialize LSTR for (std::size_t i = 0; i != sizeof LSTR - 1; ++i) LSTR [i] = 'x'; } static const StringMembers::Test tests [] = { #undef TEST #define TEST(tag) { \ StringMembers::op_plus_eq_ ## tag, tag ## _test_cases, \ sizeof tag ## _test_cases / sizeof *tag ## _test_cases \ } TEST (ptr), TEST (str), TEST (val) }; const std::size_t test_count = sizeof tests / sizeof *tests; StringMembers::run_test (test_op_plus_eq, tests, test_count); return 0; } /**************************************************************************/ int main (int argc, char** argv) { return rw_test (argc, argv, __FILE__, "lib.string.op+=", 0 /* no comment */, run_test, "|-no-char_traits# " "|-no-user_traits# " "|-no-user_char# " "|-no-exceptions# " "|-no-exception-safety# " "|-no-op-append-ptr# " "|-no-op-append-str# " "|-no-op-append-val#", &StringMembers::opt_no_char_traits, &StringMembers::opt_no_user_traits, &StringMembers::opt_no_user_char, &StringMembers::opt_no_exceptions, &StringMembers::opt_no_exception_safety, &Disabled (OpPlusEq (ptr)), &Disabled (OpPlusEq (str)), &Disabled (OpPlusEq (val)), // sentinel (void*)0); } --------------080404060705060504030402--