Author: sebor
Date: Tue Apr 25 12:01:26 2006
New Revision: 396952
URL: http://svn.apache.org/viewcvs?rev=396952&view=rev
Log:
2006-04-25 Anton Pevtsov <[EMAIL PROTECTED]>
STDCXX-4
* 21.string.plus_equal.cpp: Enhanced and ported to new test driver.
Modified:
incubator/stdcxx/trunk/tests/strings/21.string.op.plus.equal.cpp
Modified: incubator/stdcxx/trunk/tests/strings/21.string.op.plus.equal.cpp
URL:
http://svn.apache.org/viewcvs/incubator/stdcxx/trunk/tests/strings/21.string.op.plus.equal.cpp?rev=396952&r1=396951&r2=396952&view=diff
==============================================================================
--- incubator/stdcxx/trunk/tests/strings/21.string.op.plus.equal.cpp (original)
+++ incubator/stdcxx/trunk/tests/strings/21.string.op.plus.equal.cpp Tue Apr 25
12:01:26 2006
@@ -6,292 +6,476 @@
*
***************************************************************************
*
- * Copyright (c) 1994-2005 Quovadx, Inc., acting through its Rogue Wave
- * Software division. 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.
+ * 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 <string>
-
-#include <cmdopt.h>
-#include <driver.h>
+#include <string> // for string
+#include <cstdlib> // for free(), size_t
+#include <stdexcept> // for out_of_range, length_error
+
+#include <cmdopt.h> // for rw_enabled()
+#include <driver.h> // for rw_test()
+
+#include <rw_printf.h> // for rw_asnprintf()
+#include <rw_char.h> // for rw_widen()
+#include <alg_test.h> // for InputIter<>
+
+#include <21.strings.h>
+
+#ifndef _RWSTD_NO_REPLACEABLE_NEW_DELETE
+# include <rw_new.h> // for bad_alloc, replacement operator new
+#else
+# include <new> // for bad_alloc
+#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;
/**************************************************************************/
-template <class _CharT>
-class Lit { };
+// 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"
+};
-_RWSTD_SPECIALIZED_CLASS
-class Lit<char>
-{
-public:
- static const char null[];
- static const char abcdefg[];
- static const char dummy[];
- static const char testString[];
- static const char differentString[];
- static const char veryLongTestString[];
- static const char a[];
- static const char b[];
- static const char longTestString[];
- static const char anotherTestString[];
- static const char testStringAnotherTestString[];
- static const char reallyLong[];
- static const char t[];
- static const char s[];
- static const char testStrings[];
+// 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),
-const char Lit<char>:: null[] = "\0";
-const char Lit<char>:: abcdefg[] = "abcdefg";
-const char Lit<char>:: dummy[] = "dummy";
-const char Lit<char>:: testString[] = "test string";
-const char Lit<char>:: differentString[]= "different string";
-const char Lit<char>:: veryLongTestString[] = "very long test string";
-const char Lit<char>:: a[] = "a";
-const char Lit<char>:: b[] = "b";
-const char Lit<char>:: longTestString[] = "long test string";
-const char Lit<char>:: anotherTestString[] = "another test string";
-const char Lit<char>:: testStringAnotherTestString[] = "test stringanother
test string";
-
-const char Lit<char>:: reallyLong[] = "Really, really long test string that
seems to never stop";
-const char Lit<char>:: t[] = "t";
-const char Lit<char>:: s[] = "s";
-const char Lit<char>:: testStrings[] = "test strings";
-
-
-#ifndef _RWSTD_NO_WCHAR_T
-_RWSTD_SPECIALIZED_CLASS
-class Lit<wchar_t>
-{
-public:
- static const wchar_t null[];
- static const wchar_t abcdefg[];
- static const wchar_t dummy[];
- static const wchar_t testString[];
- static const wchar_t differentString[];
- static const wchar_t veryLongTestString[];
- static const wchar_t a[];
- static const wchar_t b[];
- static const wchar_t longTestString[];
- static const wchar_t anotherTestString[];
- static const wchar_t testStringAnotherTestString[];
- static const wchar_t reallyLong[];
- static const wchar_t t[];
- static const wchar_t s[];
- static const wchar_t testStrings[];
+ TEST ("last", "test", "lasttest", 0)
};
-const wchar_t Lit<wchar_t>:: null[] = L"\0";
-const wchar_t Lit<wchar_t>:: abcdefg[] = L"abcdefg";
-const wchar_t Lit<wchar_t>:: dummy[] = L"dummy";
-const wchar_t Lit<wchar_t>:: testString[] = L"test string";
-const wchar_t Lit<wchar_t>:: differentString[] = L"different string";
-const wchar_t Lit<wchar_t>:: veryLongTestString[] = L"very long test string";
-const wchar_t Lit<wchar_t>:: a[] = L"a";
-const wchar_t Lit<wchar_t>:: b[] = L"b";
-const wchar_t Lit<wchar_t>:: longTestString[] = L"long test string";
-const wchar_t Lit<wchar_t>:: anotherTestString[] = L"another test string";
-const wchar_t Lit<wchar_t>:: testStringAnotherTestString[] = L"test
stringanother test string";
-const wchar_t Lit<wchar_t>:: reallyLong[] = L"Really, really long test string
that seems to never stop";
-const wchar_t Lit<wchar_t>:: t[] = L"t";
-const wchar_t Lit<wchar_t>:: s[] = L"s";
-const wchar_t Lit<wchar_t>:: testStrings[] = L"test strings";
-#endif
-
/**************************************************************************/
-template<typename T>
-void test_plus_equal (T, const char*)
-{
- typedef std::char_traits<T> Traits;
- typedef std::allocator<T> Allocator;
- typedef std::basic_string<T, Traits, Allocator> String;
-
- rw_info (0, 0, 0, "Plus-equal operator with string parameter");
-
- {
- String t1;
- String t2;
-
- // Assigning nullString plus-equal nullString
- t1 += t2;
-
- rw_assert ((t1 == Lit<T>::null), 0, __LINE__, "B27");
-
- // Correctly references nullString
- rw_assert (t1.data () == String ().data (), 0, __LINE__, "B28");
-
- // Correctly returns length
- rw_assert ((t1.length() == 0), 0, __LINE__, "B29");
- }
-
- {
- String t1;
- String t2(Lit<T>::testString);
-
-
- t1 += t2;
-
- // Assigning nullString plus-equal char string
- rw_assert ((t1 == t2), 0, __LINE__, "B30");
-
- // Correctly returns length
- rw_assert ((t1.length() == t2.length()), 0, __LINE__, "B31");
- }
-
- {
- String t1(Lit<T>::testString);
- String t2;
-
- t1 += t2;
+// 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),
- // Assigning char string plus-equal nullString
- rw_assert ((t1==Lit<T>::testString), 0, __LINE__, "B32");
-
- // Correctly returns length
- rw_assert ((t1.length() == 11), 0, __LINE__, "B33");
- }
-
- {
- String t1 (Lit<T>::testString);
- String t2 (Lit<T>::anotherTestString);
-
- typename String::size_type t1_len = t1.length ();
- typename String::size_type t2_len = t2.length ();
-
- t1 += t2;
-
- // Assigning char string plus-equal char string
- rw_assert ((t1 == Lit<T>::testStringAnotherTestString),
- 0, __LINE__, "B34");
-
- // Correctly returns length
- rw_assert ((t1.length() == (t1_len+t2_len)), 0, __LINE__, "B35");
- }
+ TEST ("", LSTR, LSTR, -1),
- rw_info (0, 0, 0, "Plus-equal operator with const char pointer");
-
- {
- String t1;
-
- t1 += Lit<T>::null;
-
- // Assigning nullString plus-equal nullString
- rw_assert ((t1 == Lit<T>::null), 0, __LINE__, "B36");
-
- // Correctly references nullString
- rw_assert (t1.data () == String ().data (), 0, __LINE__, "B37");
-
- // Correctly returns length
- rw_assert ((t1.length() == 0), 0, __LINE__, "B38");
- }
-
- {
- String t1;
- t1 += Lit<T>::testString;
-
- // Assigning nullString plus-equal char string
- rw_assert ((t1==Lit<T>::testString), 0, __LINE__, "B39");
-
- // Correctly returns length
- rw_assert ((t1.length() == 11), 0, __LINE__, "B40");
- }
-
- {
- String t1(Lit<T>::testString);
- t1 += Lit<T>::null;
-
- // Assigning char string plus-equal nullString
- rw_assert ((t1 == Lit<T>::testString), 0, __LINE__, "B41");
-
- // Correctly returns length
- rw_assert ((t1.length() == 11), 0, __LINE__, "B42");
- }
-
- {
- String t1(Lit<T>::testString);
-
- typename String::size_type t1_len = t1.length();
- typename String::size_type t2_len =
- std::char_traits<T>::length(Lit<T>::anotherTestString);
+ TEST ("last", "test", "lasttest", 0)
+};
- t1 += Lit<T>::anotherTestString;
+/**************************************************************************/
- // Assigning char string plus-equal char string
- rw_assert ((t1 == Lit<T>::testStringAnotherTestString),
- 0, __LINE__, "B43");
+// used to exercise
+// operator+= (value_type 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),
- // Correctly returns length
- rw_assert ((t1.length() == (t1_len+t2_len)), 0, __LINE__, "B44");
- }
+ TEST ("last", 't', "lastt", 0)
+};
- rw_info (0, 0, 0, "Plus-equal operator with char parameter");
- {
- String t1;
- t1 += Lit<T>::null[0];
+/**************************************************************************/
- // Assigning nullString plus-equal zero
- rw_assert ((t1 != Lit<T>::null), 0, __LINE__, "B45");
+template <class charT, class Traits>
+void test_op_plus_eq (charT, Traits*,
+ OpPlusEqOverload which,
+ const TestCase &cs)
+{
+ typedef std::allocator<charT> Allocator;
+ typedef std::basic_string <charT, Traits, Allocator> 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);
- // Correctly returns length
- rw_assert ((t1.length() == 1), 0, __LINE__, "B46");
- }
+#endif // _RWSTD_NO_EXCEPTIONS
- {
- String t1;
+}
- t1 += Lit<T>::t[0];
+/**************************************************************************/
- // Assigning nullString plus-equal char
- rw_assert ((t1 == Lit<T>::t), 0, __LINE__, "B47");
+DEFINE_TEST_DISPATCH (test_op_plus_eq);
- // Correctly returns length
- rw_assert ((t1.length() == 1), 0, __LINE__, "B48");
+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';
}
- {
- String t1(Lit<T>::testString);
-
- t1 += Lit<T>::s[0];
+ static const StringMembers::Test
+ tests [] = {
- // Assigning char string plus-equal char
- rw_assert ((t1 == Lit<T>::testStrings), 0, __LINE__, "B49");
-
- // Correctly returns length
- rw_assert ((t1.length() == 12), 0, __LINE__, "B50");
+#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)
+ };
-int run_test (int, char*[])
-{
- if (rw_enabled ("char"))
- test_plus_equal (char (), "char");
- else
- rw_note (0, __FILE__, __LINE__, "char test disabled");
-
-#ifndef _RWSTD_NO_WCHAR_T
-
- if (rw_enabled ("wchar_t"))
- test_plus_equal (wchar_t (), "wchar_t");
- else
- rw_note (0, __FILE__, __LINE__, "wchar_t test disabled");
+ const std::size_t test_count = sizeof tests / sizeof *tests;
-#endif // _RWSTD_NO_WCHAR_T
+ StringMembers::run_test (test_op_plus_eq, tests, test_count);
return 0;
-
}
/**************************************************************************/
@@ -301,5 +485,26 @@
return rw_test (argc, argv, __FILE__,
"lib.string.op+=",
0 /* no comment */, run_test,
- 0 /* co command line options */);
+ "|-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);
}