Author: antonp
Date: Mon May 29 08:24:54 2006
New Revision: 410107
URL: http://svn.apache.org/viewvc?rev=410107&view=rev
Log:
2006-05-29 Anton Pevtsov <[EMAIL PROTECTED]>
STDCXX-4
* 21.string.op.plus.cpp: New test exercising lib.string::op+.
Added:
incubator/stdcxx/trunk/tests/strings/21.string.op.plus.cpp (with props)
Added: incubator/stdcxx/trunk/tests/strings/21.string.op.plus.cpp
URL:
http://svn.apache.org/viewvc/incubator/stdcxx/trunk/tests/strings/21.string.op.plus.cpp?rev=410107&view=auto
==============================================================================
--- incubator/stdcxx/trunk/tests/strings/21.string.op.plus.cpp (added)
+++ incubator/stdcxx/trunk/tests/strings/21.string.op.plus.cpp Mon May 29
08:24:54 2006
@@ -0,0 +1,616 @@
+/***************************************************************************
+ *
+ * 21.string.op.plus.cpp - test exercising [lib.string::op+]
+ *
+ * $Id$
+ *
+ ***************************************************************************
+ *
+ * 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> // for string
+#include <stdexcept> // for out_of_range, length_error
+
+#include <cstddef> // for size_t
+
+#include <21.strings.h> // for StringMembers
+#include <alg_test.h> // for InputIter
+#include <driver.h> // for rw_test()
+#include <rw_allocator.h> // for UserAlloc
+#include <rw_char.h> // for rw_expand()
+#include <rw_new.h> // for bad_alloc, replacement operator new
+
+/**************************************************************************/
+
+// for convenience and brevity
+#define OpPlus(which) StringIds::op_plus_ ## which
+
+static const char* const exceptions[] = {
+ "unknown exception", "out_of_range", "length_error",
+ "bad_alloc", "exception"
+};
+
+/**************************************************************************/
+
+// exercises:
+// operator + (const value_type*, const basic_string&)
+static const StringTestCase
+cptr_cstr_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 \
+ }
+
+ // +----------------------------------------- first sequence
+ // | +--------------------------- second sequence
+ // | | +------------- expected result sequence
+ // | | | +---- exception info
+ // | | | | 0 - no exception
+ // | | | |
+ // | | | +---------+
+ // V V V V
+ TEST ("ab", "c", "abc", 0),
+
+ TEST ("", "", "", 0),
+ TEST ("", "a", "a", 0),
+ TEST ("a", "", "a", 0),
+
+ TEST ("\0", "", "", 0),
+ TEST ("", "\0", "\0", 0),
+ TEST ("\0", "\0", "\0", 0),
+
+ TEST ("abcdefg", "jih", "abcdefgjih", 0),
+ TEST ("jih", "abcdefg", "jihabcdefg", 0),
+
+ TEST ("\0ab\0\0c", "e\0", "e\0", 0),
+ TEST ("e\0", "\0ab\0\0c", "e\0ab\0\0c", 0),
+ TEST ("ab\0\0c\0", "e\0", "abe\0", 0),
+ TEST ("e\0", "ab\0\0c\0", "eab\0\0c\0", 0),
+
+ TEST ("[EMAIL PROTECTED]", "[EMAIL PROTECTED]", "[EMAIL
PROTECTED]", 0),
+ TEST ("[EMAIL PROTECTED]", "[EMAIL PROTECTED]", "[EMAIL
PROTECTED]@2048", 0),
+ TEST ("[EMAIL PROTECTED]", "[EMAIL PROTECTED]", "[EMAIL
PROTECTED]@2048", 0),
+ TEST ("[EMAIL PROTECTED]", "[EMAIL PROTECTED]", "[EMAIL
PROTECTED]@2048\0", 0),
+
+ TEST ("[EMAIL PROTECTED]", "[EMAIL PROTECTED]", "[EMAIL
PROTECTED]", 0),
+ TEST ("[EMAIL PROTECTED]", "[EMAIL PROTECTED]", "[EMAIL
PROTECTED]", 0),
+ TEST ("[EMAIL PROTECTED]", "[EMAIL PROTECTED]", "[EMAIL
PROTECTED]", 0),
+ TEST ("[EMAIL PROTECTED]", "[EMAIL PROTECTED]", "[EMAIL
PROTECTED]", 0),
+ TEST ("[EMAIL PROTECTED]", "[EMAIL PROTECTED]", "[EMAIL
PROTECTED]", 0),
+ TEST ("[EMAIL PROTECTED]", "[EMAIL PROTECTED]", "[EMAIL
PROTECTED]", 0),
+ TEST ("[EMAIL PROTECTED]", "[EMAIL PROTECTED]", "[EMAIL
PROTECTED]", 0),
+ TEST ("[EMAIL PROTECTED]", "[EMAIL PROTECTED]", "[EMAIL
PROTECTED]", 0),
+ TEST ("[EMAIL PROTECTED]", "[EMAIL PROTECTED]", "[EMAIL
PROTECTED]", 0),
+
+ TEST (0, "abc", "abcabc", 0),
+ TEST (0, "\0ab\0", "\0ab\0", 0),
+ TEST (0, "[EMAIL PROTECTED]", "[EMAIL PROTECTED]",
0),
+
+ TEST ("last", "test", "lasttest", 0)
+};
+
+
+/**************************************************************************/
+
+// exercises:
+// operator + (const basic_string&, const basic_string&)
+static const StringTestCase
+cstr_cstr_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 \
+ }
+
+ // +----------------------------------------- first sequence
+ // | +--------------------------- second sequence
+ // | | +------------- expected result sequence
+ // | | | +---- exception info
+ // | | | | 0 - no exception
+ // | | | |
+ // | | | +---------+
+ // V V V V
+ TEST ("ab", "c", "abc", 0),
+
+ TEST ("", "", "", 0),
+ TEST ("", "a", "a", 0),
+ TEST ("a", "", "a", 0),
+
+ TEST ("\0", "", "\0", 0),
+ TEST ("", "\0", "\0", 0),
+ TEST ("\0", "\0", "\0\0", 0),
+
+ TEST ("abcdefg", "jih", "abcdefgjih", 0),
+ TEST ("jih", "abcdefg", "jihabcdefg", 0),
+
+ TEST ("\0ab\0\0c", "e\0", "\0ab\0\0ce\0", 0),
+ TEST ("e\0", "\0ab\0\0c", "e\0\0ab\0\0c", 0),
+ TEST ("ab\0\0c\0", "e\0", "ab\0\0c\0e\0", 0),
+ TEST ("e\0", "ab\0\0c\0", "e\0ab\0\0c\0", 0),
+
+ TEST ("[EMAIL PROTECTED]", "[EMAIL PROTECTED]", "[EMAIL
PROTECTED]", 0),
+ TEST ("[EMAIL PROTECTED]", "[EMAIL PROTECTED]", "[EMAIL
PROTECTED]@2048", 0),
+ TEST ("[EMAIL PROTECTED]", "[EMAIL PROTECTED]", "[EMAIL
PROTECTED]@2048", 0),
+ TEST ("[EMAIL PROTECTED]", "[EMAIL PROTECTED]", "[EMAIL
PROTECTED]@2048\0", 0),
+
+ TEST ("[EMAIL PROTECTED]", "[EMAIL PROTECTED]", "[EMAIL
PROTECTED]", 0),
+ TEST ("[EMAIL PROTECTED]", "[EMAIL PROTECTED]", "[EMAIL
PROTECTED]", 0),
+ TEST ("[EMAIL PROTECTED]", "[EMAIL PROTECTED]", "[EMAIL
PROTECTED]", 0),
+ TEST ("[EMAIL PROTECTED]", "[EMAIL PROTECTED]", "[EMAIL
PROTECTED]", 0),
+ TEST ("[EMAIL PROTECTED]", "[EMAIL PROTECTED]", "[EMAIL
PROTECTED]", 0),
+ TEST ("[EMAIL PROTECTED]", "[EMAIL PROTECTED]", "[EMAIL
PROTECTED]", 0),
+ TEST ("[EMAIL PROTECTED]", "[EMAIL PROTECTED]", "[EMAIL
PROTECTED]", 0),
+ TEST ("[EMAIL PROTECTED]", "[EMAIL PROTECTED]", "[EMAIL
PROTECTED]", 0),
+ TEST ("[EMAIL PROTECTED]", "[EMAIL PROTECTED]", "[EMAIL
PROTECTED]", 0),
+
+ TEST (0, "abc", "abcabc", 0),
+ TEST (0, "\0ab\0", "\0ab\0\0ab\0", 0),
+ TEST (0, "[EMAIL PROTECTED]", "[EMAIL PROTECTED]",
0),
+
+ TEST ("abc", 0, "abcabc", 0),
+ TEST ("\0ab\0", 0, "\0ab\0\0ab\0", 0),
+ TEST ("[EMAIL PROTECTED]", 0, "[EMAIL PROTECTED]",
0),
+
+ TEST ("last", "test", "lasttest", 0)
+};
+
+/**************************************************************************/
+
+// exercises:
+// operator + (const basic_string&, const value_type*)
+static const StringTestCase
+cstr_cptr_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 \
+ }
+
+ // +----------------------------------------- first sequence
+ // | +--------------------------- second sequence
+ // | | +------------- expected result sequence
+ // | | | +---- exception info
+ // | | | | 0 - no exception
+ // | | | |
+ // | | | +---------+
+ // V V V V
+ TEST ("ab", "c", "abc", 0),
+
+ TEST ("", "", "", 0),
+ TEST ("", "a", "a", 0),
+ TEST ("a", "", "a", 0),
+
+ TEST ("\0", "", "\0", 0),
+ TEST ("", "\0", "", 0),
+ TEST ("\0", "\0", "\0", 0),
+
+ TEST ("abcdefg", "jih", "abcdefgjih", 0),
+ TEST ("jih", "abcdefg", "jihabcdefg", 0),
+
+ TEST ("\0ab\0\0c", "e\0", "\0ab\0\0ce", 0),
+ TEST ("e\0", "\0ab\0\0c", "e\0", 0),
+ TEST ("ab\0\0c\0", "e\0", "ab\0\0c\0e", 0),
+ TEST ("e\0", "ab\0\0c\0", "e\0ab", 0),
+
+ TEST ("[EMAIL PROTECTED]", "[EMAIL PROTECTED]", "[EMAIL
PROTECTED]", 0),
+ TEST ("[EMAIL PROTECTED]", "[EMAIL PROTECTED]", "[EMAIL
PROTECTED]@2048", 0),
+ TEST ("[EMAIL PROTECTED]", "[EMAIL PROTECTED]", "[EMAIL
PROTECTED]@2048", 0),
+ TEST ("[EMAIL PROTECTED]", "[EMAIL PROTECTED]", "[EMAIL
PROTECTED]@2048", 0),
+
+ TEST ("[EMAIL PROTECTED]", "[EMAIL PROTECTED]", "[EMAIL
PROTECTED]", 0),
+ TEST ("[EMAIL PROTECTED]", "[EMAIL PROTECTED]", "[EMAIL
PROTECTED]", 0),
+ TEST ("[EMAIL PROTECTED]", "[EMAIL PROTECTED]", "[EMAIL
PROTECTED]", 0),
+ TEST ("[EMAIL PROTECTED]", "[EMAIL PROTECTED]", "[EMAIL
PROTECTED]", 0),
+ TEST ("[EMAIL PROTECTED]", "[EMAIL PROTECTED]", "[EMAIL
PROTECTED]", 0),
+ TEST ("[EMAIL PROTECTED]", "[EMAIL PROTECTED]", "[EMAIL
PROTECTED]", 0),
+ TEST ("[EMAIL PROTECTED]", "[EMAIL PROTECTED]", "[EMAIL
PROTECTED]", 0),
+ TEST ("[EMAIL PROTECTED]", "[EMAIL PROTECTED]", "[EMAIL
PROTECTED]", 0),
+ TEST ("[EMAIL PROTECTED]", "[EMAIL PROTECTED]", "[EMAIL
PROTECTED]", 0),
+
+ TEST ("abc", 0, "abcabc", 0),
+ TEST ("\0ab\0", 0, "\0ab\0", 0),
+ TEST ("[EMAIL PROTECTED]", 0, "[EMAIL PROTECTED]",
0),
+
+ TEST ("last", "test", "lasttest", 0)
+};
+
+/**************************************************************************/
+
+// exercises:
+// operator + (const basic_string&, value_type)
+static const StringTestCase
+cstr_val_test_cases [] = {
+
+#undef TEST
+#define TEST(arg, val, res) \
+ { __LINE__, -1, -1, -1, -1, val, \
+ 0, 0, arg, sizeof arg - 1, \
+ res, sizeof res - 1, 0 \
+ }
+
+ // +----------------------------------------- first sequence
+ // | +--------------------------- character to be added
+ // | | +------------- expected result sequence
+ // | | |
+ // | | |
+ // V V V
+ TEST ("ab", 'c', "abc"),
+
+ TEST ("", 'a', "a"),
+ TEST ("", '\0', "\0"),
+
+ TEST ("\0", 'a', "\0a"),
+ TEST ("\0", '\0', "\0\0"),
+
+ TEST ("\0ab\0\0c", 'e', "\0ab\0\0ce"),
+ TEST ("\0ab\0\0c", '\0', "\0ab\0\0c\0"),
+ TEST ("ab\0\0c\0", 'e', "ab\0\0c\0e"),
+ TEST ("ab\0\0c\0", '\0', "ab\0\0c\0\0"),
+
+ TEST ("abcdefghj", 'i', "abcdefghji"),
+
+ TEST ("[EMAIL PROTECTED]", 'x', "[EMAIL PROTECTED]"),
+ TEST ("[EMAIL PROTECTED]", '\0', "[EMAIL PROTECTED]"),
+
+ TEST ("[EMAIL PROTECTED]", 'x', "[EMAIL PROTECTED]"),
+ TEST ("[EMAIL PROTECTED]", 'x', "[EMAIL PROTECTED]"),
+ TEST ("[EMAIL PROTECTED]", 'x', "[EMAIL PROTECTED]"),
+ TEST ("[EMAIL PROTECTED]", 'x', "[EMAIL PROTECTED]"),
+ TEST ("[EMAIL PROTECTED]", 'x', "[EMAIL PROTECTED]"),
+ TEST ("[EMAIL PROTECTED]", 'x', "[EMAIL PROTECTED]"),
+ TEST ("[EMAIL PROTECTED]", 'x', "[EMAIL PROTECTED]"),
+ TEST ("[EMAIL PROTECTED]", 'x', "[EMAIL PROTECTED]"),
+
+ TEST ("last", 't', "lastt")
+};
+
+/**************************************************************************/
+
+// exercises:
+// operator + (value_type, const basic_string&)
+static const StringTestCase
+val_cstr_test_cases [] = {
+
+#undef TEST
+#define TEST(val, arg, res) \
+ { __LINE__, -1, -1, -1, -1, val, \
+ "", 0, arg, sizeof arg - 1, \
+ res, sizeof res - 1, 0 \
+ }
+
+ // +----------------------------------------- first sequence
+ // | +--------------------------- character to be added
+ // | | +------------- expected result sequence
+ // | | |
+ // | | |
+ // V V V
+ TEST ('c', "ab", "cab"),
+
+ TEST ('a', "", "a"),
+ TEST ('\0', "", "\0"),
+
+ TEST ('a', "\0", "a\0"),
+ TEST ('\0', "\0", "\0\0"),
+
+ TEST ('e', "\0ab\0\0c", "e\0ab\0\0c"),
+ TEST ('\0', "\0ab\0\0c", "\0\0ab\0\0c"),
+ TEST ('e', "ab\0\0c\0", "eab\0\0c\0"),
+ TEST ('\0', "ab\0\0c\0", "\0ab\0\0c\0"),
+
+ TEST ('i', "abcdefghj", "iabcdefghj"),
+
+ TEST ('x', "[EMAIL PROTECTED]", "[EMAIL PROTECTED]"),
+ TEST ('\0', "[EMAIL PROTECTED]", "[EMAIL PROTECTED]"),
+
+ TEST ('x', "[EMAIL PROTECTED]", "[EMAIL PROTECTED]"),
+ TEST ('x', "[EMAIL PROTECTED]", "[EMAIL PROTECTED]"),
+ TEST ('x', "[EMAIL PROTECTED]", "[EMAIL PROTECTED]"),
+ TEST ('x', "[EMAIL PROTECTED]", "[EMAIL PROTECTED]"),
+ TEST ('x', "[EMAIL PROTECTED]", "[EMAIL PROTECTED]"),
+ TEST ('x', "[EMAIL PROTECTED]", "[EMAIL PROTECTED]"),
+ TEST ('x', "[EMAIL PROTECTED]", "[EMAIL PROTECTED]"),
+ TEST ('x', "[EMAIL PROTECTED]", "[EMAIL PROTECTED]"),
+
+ TEST ('t', "last", "tlast")
+};
+
+/**************************************************************************/
+
+template <class charT, class Traits, class Allocator>
+void test_op_plus (charT, Traits*, Allocator*,
+ const StringFunc &func,
+ const StringTestCase &tcase)
+{
+ typedef std::basic_string <charT, Traits, Allocator> String;
+ typedef typename UserTraits<charT>::MemFun UTMemFun;
+
+ static const std::size_t BUFSIZE = 256;
+
+ static charT wstr_buf [BUFSIZE];
+ static charT warg_buf [BUFSIZE];
+
+ std::size_t str_len = sizeof wstr_buf / sizeof *wstr_buf;
+ std::size_t arg_len = sizeof warg_buf / sizeof *warg_buf;
+
+ charT* wstr = rw_expand (wstr_buf, tcase.str, tcase.str_len, &str_len);
+ charT* warg = rw_expand (warg_buf, tcase.arg, tcase.arg_len, &arg_len);
+
+ static charT wres_buf [BUFSIZE];
+ std::size_t res_len = sizeof wres_buf / sizeof *wres_buf;
+ charT* wres = rw_expand (wres_buf, tcase.res, tcase.nres, &res_len);
+
+ // construct the string object to be modified
+ // and the (possibly unused) argument string
+ /* const */ String s_str (wstr, str_len);
+ const String s_arg (warg, arg_len);
+
+ if (wstr != wstr_buf)
+ delete[] wstr;
+
+ if (warg != warg_buf)
+ delete[] warg;
+
+ wstr = 0;
+ warg = 0;
+
+ String s_res;
+
+ // save the state of the string object before the call
+ // to detect wxception safety violations (changes to
+ // the state of the object after an exception)
+ const StringState str_state (rw_get_string_state (s_res));
+
+ const charT* const arg1_ptr = tcase.str ? s_str.c_str () : s_arg.c_str ();
+ const String& arg1_str = tcase.str ? s_str : s_arg;
+ const charT* const arg2_ptr = tcase.arg ? s_arg.c_str () : s_str.c_str ();
+ const String& arg2_str = tcase.arg ? s_arg : s_str;
+ const charT arg_val = make_char (char (tcase.val), (charT*)0);
+
+ std::size_t total_length_calls = 0;
+ std::size_t n_length_calls = 0;
+ std::size_t* const rg_calls = rw_get_call_counters ((Traits*)0, (charT*)0);
+
+ if (rg_calls)
+ total_length_calls = rg_calls [UTMemFun::length];
+
+ rwt_free_store* const pst = rwt_get_free_store (0);
+ SharedAlloc* const pal = SharedAlloc::instance ();
+
+ // iterate for`throw_after' starting at the next call to operator new,
+ // forcing each call to throw an exception, until the function finally
+ // succeeds (i.e, no exception is thrown)
+ std::size_t throw_count;
+ for (throw_count = 0; ; ++throw_count) {
+
+ // (name of) expected and caught exception
+ const char* expected = 0;
+ const char* caught = 0;
+
+#ifndef _RWSTD_NO_EXCEPTIONS
+
+ if (0 == tcase.bthrow) {
+ // by default excercise the exception safety of the function
+ // by iteratively inducing an exception at each call to operator
+ // new or Allocator::allocate() until the call succeeds
+ expected = exceptions [3]; // bad_alloc
+ *pst->throw_at_calls_ [0] = pst->new_calls_ [0] + throw_count + 1;
+ pal->throw_at_calls_ [pal->m_allocate] =
+ pal->throw_at_calls_ [pal->m_allocate] + throw_count + 1;
+ }
+ else {
+ // exceptions disabled for this test case
+ }
+
+#else // if defined (_RWSTD_NO_EXCEPTIONS)
+
+ if (tcase.bthrow) {
+ if (wres != wres_buf)
+ delete[] wres;
+
+ return;
+ }
+
+#endif // _RWSTD_NO_EXCEPTIONS
+
+ // start checking for memory leaks
+ rw_check_leaks (s_res.get_allocator ());
+
+ try {
+
+ switch (func.which_) {
+ case OpPlus (cptr_cstr):
+ s_res = arg1_ptr + arg2_str;
+ if (rg_calls)
+ n_length_calls = rg_calls [UTMemFun::length];
+ break;
+
+ case OpPlus (cstr_cstr):
+ s_res = arg1_str + arg2_str;
+ break;
+
+ case OpPlus (cstr_cptr):
+ s_res = arg1_str + arg2_ptr;
+ if (rg_calls)
+ n_length_calls = rg_calls [UTMemFun::length];
+ break;
+
+ case OpPlus (cstr_val):
+ s_res = arg1_str + arg_val;
+ break;
+
+ case OpPlus (val_cstr):
+ s_res = arg_val + arg2_str;
+ break;
+
+ default:
+ RW_ASSERT ("test logic error: unknown operator+ overload");
+ return;
+ }
+
+ // verfiy that strings length are equal
+ rw_assert (res_len == s_res.size (), 0, tcase.line,
+ "line %d. %{$FUNCALL} expected %{#*s} "
+ "with length %zu, got %{/*.*Gs} with length %zu",
+ __LINE__, int (tcase.nres), tcase.res, res_len,
+ int (sizeof (charT)), int (s_res.size ()),
+ s_res.c_str (), s_res.size ());
+
+ if (res_len == s_res.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 (tcase.res, s_res.c_str(), tcase.nres);
+
+ rw_assert (match == res_len, 0, tcase.line,
+ "line %d. %{$FUNCALL} expected %{#*s}, "
+ "got %{/*.*Gs}, difference at offset %zu",
+ __LINE__, int (tcase.nres), tcase.res,
+ int (sizeof (charT)), int (s_res.size ()),
+ s_res.c_str (), match);
+ }
+
+ // verify that Traits::length was used
+ if ((OpPlus (cptr_cstr) == func.which_
+ || OpPlus (cstr_cptr) == func.which_) && rg_calls) {
+ rw_assert (n_length_calls - total_length_calls > 0,
+ 0, tcase.line, "line %d. %{$FUNCALL} doesn't "
+ "use traits::length()", __LINE__);
+ }
+ }
+
+#ifndef _RWSTD_NO_EXCEPTIONS
+
+ catch (const std::bad_alloc &ex) {
+ caught = exceptions [3];
+ rw_assert (0 == tcase.bthrow, 0, tcase.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, tcase.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, tcase.line,
+ "line %d. %{$FUNCALL} %{?}expected %s,%{:}"
+ "unexpectedly%{;} caught %s",
+ __LINE__, 0 != expected, expected, caught);
+ }
+
+#endif // _RWSTD_NO_EXCEPTIONS
+
+ // FIXME: verify the number of blocks the function call
+ // is expected to allocate and detect any memory leaks
+ rw_check_leaks (s_res.get_allocator (), tcase.line,
+ std::size_t (-1), std::size_t (-1));
+
+ if (caught) {
+ // verify that an exception thrown during allocation
+ // didn't cause a change in the state of the object
+ str_state.assert_equal (rw_get_string_state (s_res),
+ __LINE__, tcase.line, caught);
+
+ if (0 == tcase.bthrow) {
+ // allow this call to operator new to succeed and try
+ // to make the next one to fail during the next call
+ // to the same function again
+ continue;
+ }
+ }
+ else if (0 < tcase.bthrow) {
+ rw_assert (caught == expected, 0, tcase.line,
+ "line %d. %{$FUNCALL} %{?}expected %s, caught %s"
+ "%{:}unexpectedly caught %s%{;}",
+ __LINE__, 0 != expected, expected, caught, caught);
+ }
+
+ break;
+ }
+
+#ifndef _RWSTD_NO_REPLACEABLE_NEW_DELETE
+
+ // verify that if exceptions are enabled and when capacity changes
+ // at least one exception is thrown
+ const std::size_t expect_throws = str_state.capacity_ < s_res.capacity ();
+
+#else // if defined (_RWSTD_NO_REPLACEABLE_NEW_DELETE)
+
+ const std::size_t expect_throws =
+ (StringIds::UserAlloc == func.alloc_id_)
+ ? str_state.capacity_ < s_res.capacity () : 0;
+
+#endif // _RWSTD_NO_REPLACEABLE_NEW_DELETE
+
+ // we may got no more 2 bad_allocs
+ rw_assert (expect_throws <= throw_count && throw_count <= 2, 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_, s_res.capacity (), throw_count);
+
+ // disable bad_alloc exceptions
+ *pst->throw_at_calls_ [0] = 0;
+ pal->throw_at_calls_ [pal->m_allocate] = 0;
+
+ if (wres != wres_buf)
+ delete[] wres;
+}
+
+/**************************************************************************/
+
+DEFINE_STRING_TEST_DISPATCH (test_op_plus);
+
+int main (int argc, char** argv)
+{
+ static const StringTest
+ tests [] = {
+
+#undef TEST
+#define TEST(tag) { \
+ StringIds::op_plus_ ## tag, tag ## _test_cases, \
+ sizeof tag ## _test_cases / sizeof *tag ## _test_cases \
+ }
+
+ TEST (cptr_cstr),
+ TEST (cstr_cptr),
+ TEST (cstr_cstr),
+ TEST (cstr_val),
+ TEST (val_cstr)
+ };
+
+ const std::size_t test_count = sizeof tests / sizeof *tests;
+
+ return rw_run_string_test (argc, argv, __FILE__,
+ "lib.string::op+",
+ test_op_plus, tests, test_count);
+}
Propchange: incubator/stdcxx/trunk/tests/strings/21.string.op.plus.cpp
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/stdcxx/trunk/tests/strings/21.string.op.plus.cpp
------------------------------------------------------------------------------
svn:keywords = Id