Author: antonp
Date: Mon Jun 19 07:25:16 2006
New Revision: 415343
URL: http://svn.apache.org/viewvc?rev=415343&view=rev
Log:
2006-06-19 Anton Pevtsov <[EMAIL PROTECTED]>
STDCXX-4
* 21.string.iterators.cpp: New test exercising lib.string.iterators.
* 21.strings.h (MemberId): Added new elements for data, c_str,
get_allocator, begin, end, rbegin, rend methods.
(OverloadId): Added new enum elements for these methods and their
overloads.
* 21.strings.cpp (_rw_setvars): Added support for data, c_str,
get_allocator, begin, end, rbegin, rend overloads.
Added:
incubator/stdcxx/trunk/tests/strings/21.string.iterators.cpp (with props)
Modified:
incubator/stdcxx/trunk/tests/include/21.strings.h
incubator/stdcxx/trunk/tests/src/21.strings.cpp
Modified: incubator/stdcxx/trunk/tests/include/21.strings.h
URL:
http://svn.apache.org/viewvc/incubator/stdcxx/trunk/tests/include/21.strings.h?rev=415343&r1=415342&r2=415343&view=diff
==============================================================================
--- incubator/stdcxx/trunk/tests/include/21.strings.h (original)
+++ incubator/stdcxx/trunk/tests/include/21.strings.h Mon Jun 19 07:25:16 2006
@@ -99,6 +99,17 @@
/* 33 */ fid_reserve,
/* 34 */ fid_clear,
/* 35 */ fid_empty,
+ /* 36 */ fid_begin,
+ /* */ fid_begin_const = fid_begin,
+ /* 37 */ fid_end,
+ /* */ fid_end_const = fid_end,
+ /* 38 */ fid_rbegin,
+ /* */ fid_rbegin_const = fid_rbegin,
+ /* 39 */ fid_rend,
+ /* */ fid_rend_const = fid_rend,
+ /* 40 */ fid_c_str,
+ /* 41 */ fid_data,
+ /* 42 */ fid_get_allocator,
/* -- */ fid_bits = 6,
/* -- */ fid_mask = 63
};
@@ -558,7 +569,37 @@
//////////////////////////////////////////////////////////////
// empty ()
- MEMBER_0 (empty, cstr)
+ MEMBER_0 (empty, cstr),
+
+ //////////////////////////////////////////////////////////////
+ // begin ()
+ MEMBER_0 (begin, str),
+ // begin () const
+ MEMBER_0 (begin_const, cstr),
+ // end ()
+ MEMBER_0 (end, str),
+ // end () const
+ MEMBER_0 (end_const, cstr),
+
+ //////////////////////////////////////////////////////////////
+ // rbegin ()
+ MEMBER_0 (rbegin, str),
+ // rbegin () const
+ MEMBER_0 (rbegin_const, cstr),
+ // rend ()
+ MEMBER_0 (rend, str),
+ // rend () const
+ MEMBER_0 (rend_const, cstr),
+
+ //////////////////////////////////////////////////////////////
+ // c_str () const
+ MEMBER_0 (c_str, cstr),
+ // data () const
+ MEMBER_0 (data, cstr),
+
+ //////////////////////////////////////////////////////////////
+ // get_allocator () const
+ MEMBER_0 (get_allocator, cstr)
};
// clean up helper macros used above
Modified: incubator/stdcxx/trunk/tests/src/21.strings.cpp
URL:
http://svn.apache.org/viewvc/incubator/stdcxx/trunk/tests/src/21.strings.cpp?rev=415343&r1=415342&r2=415343&view=diff
==============================================================================
--- incubator/stdcxx/trunk/tests/src/21.strings.cpp (original)
+++ incubator/stdcxx/trunk/tests/src/21.strings.cpp Mon Jun 19 07:25:16 2006
@@ -89,7 +89,8 @@
0 /* special handling for the ctor */, "operator=", "swap", "push_back",
"operator+", "operator==", "operator!=", "operator<", "operator<=",
"operator>", "operator>=", "size", "length", "max_size", "resize",
- "capacity", "reserve", "clear", "empty"
+ "capacity", "reserve", "clear", "empty", "begin", "end", "rbegin",
+ "rend", "c_str", "data", "get_allocator"
};
/**************************************************************************/
@@ -246,6 +247,9 @@
case Ids::fid_find_last_of:
case Ids::fid_rfind:
case Ids::fid_substr:
+ case Ids::fid_c_str:
+ case Ids::fid_data:
+ case Ids::fid_get_allocator:
// prevent appending the "_const" bit to the mnemonics
// of member functions not overloaded on const
is_const_member = false;
@@ -864,8 +868,23 @@
case StringIds::reserve_void:
case StringIds::clear_void:
case StringIds::empty_void:
+ case StringIds::begin_void:
+ case StringIds::end_void:
+ case StringIds::rbegin_void:
+ case StringIds::rend_void:
+ case StringIds::c_str_void:
+ case StringIds::data_void:
+ case StringIds::get_allocator_void:
rw_asnprintf (&buf, &bufsize,
"%{+} ()");
+ break;
+
+ case StringIds::begin_const_void:
+ case StringIds::end_const_void:
+ case StringIds::rbegin_const_void:
+ case StringIds::rend_const_void:
+ rw_asnprintf (&buf, &bufsize,
+ "%{+} () const");
break;
case StringIds::ctor_alloc:
Added: incubator/stdcxx/trunk/tests/strings/21.string.iterators.cpp
URL:
http://svn.apache.org/viewvc/incubator/stdcxx/trunk/tests/strings/21.string.iterators.cpp?rev=415343&view=auto
==============================================================================
--- incubator/stdcxx/trunk/tests/strings/21.string.iterators.cpp (added)
+++ incubator/stdcxx/trunk/tests/strings/21.string.iterators.cpp Mon Jun 19
07:25:16 2006
@@ -0,0 +1,553 @@
+/***************************************************************************
+*
+* 21.string.iterators.cpp - string test exercising lib.string.iterators
+*
+* $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 <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
+
+/**************************************************************************/
+
+static const char* const exceptions[] = {
+ "unknown exception", "bad_alloc", "exception"
+};
+
+/**************************************************************************/
+
+// used to exercise
+// begin () and rend ()
+static const StringTestCase
+begin_void_test_cases [] = {
+
+#undef TEST
+#define TEST(str, res) { \
+ __LINE__, -1, -1, -1, -1, -1, \
+ str, sizeof (str) - 1, \
+ 0, 0, 0, res, 0 \
+}
+
+ // +--------------------------------- controlled sequence
+ // | +---------------- expected result
+ // | |
+ // V V
+ TEST ("a", 'a' ),
+ TEST ("\0", '\0'),
+ TEST ("abc", 'a' ),
+ TEST ("\0ab\0\0c", '\0'),
+ TEST ("a\0b\0\0c", 'a' ),
+ TEST ("a\0bc\0\0", 'a' ),
+ TEST ("[EMAIL PROTECTED]", 'x' ),
+ TEST ("last", 'l' )
+};
+
+/**************************************************************************/
+
+// used to exercise
+// end () and rbegin ()
+static const StringTestCase
+end_void_test_cases [] = {
+
+#undef TEST
+#define TEST(str, res) { \
+ __LINE__, -1, -1, -1, -1, -1, \
+ str, sizeof (str) - 1, \
+ 0, 0, 0, res, 0 \
+}
+
+ // +--------------------------------- controlled sequence
+ // | +---------------- expected result
+ // | |
+ // V V
+ TEST ("a", 'a' ),
+ TEST ("\0", '\0'),
+ TEST ("abc", 'c' ),
+ TEST ("\0ab\0\0c", 'c' ),
+ TEST ("a\0b\0\0c", 'c' ),
+ TEST ("a\0bc\0\0", '\0'),
+ TEST ("[EMAIL PROTECTED]", 'x' ),
+ TEST ("last", 't' )
+};
+
+/**************************************************************************/
+
+// exercises:
+// c_str() and data ()
+static const StringTestCase
+c_str_void_test_cases [] = {
+
+#undef TEST
+#define TEST(str) { \
+ __LINE__, -1, -1, -1, -1, -1, \
+ str, sizeof (str) - 1, 0, 0, \
+ str, sizeof (str) - 1, 0 \
+}
+
+ // +-------------------------------- controlled sequence
+ // |
+ // |
+ // |
+ // |
+ // |
+ // |
+ // |
+ // V
+ TEST ("ab" ),
+
+ TEST ("" ),
+
+ TEST ("\0" ),
+
+ TEST ("abcdefghij" ),
+ TEST ("abcdefghi" ),
+
+ TEST ("abbdefghij" ),
+ TEST ("abcdeeghij" ),
+ TEST ("abcdefghii" ),
+
+ TEST ("bbcdefghij" ),
+ TEST ("eeeeeeghij" ),
+ TEST ("a" ),
+ TEST ("aeeee" ),
+
+ TEST ("bbcdefghij" ),
+ TEST ("abcdffghij" ),
+ TEST ("abcdefghjj" ),
+
+ TEST ("a\0b\0\0c" ),
+ TEST ("abc\0\0\0" ),
+ TEST ("\0ab\0\0c" ),
+
+ TEST ("a\0b" ),
+ TEST ("ab\0" ),
+ TEST ("\0ab" ),
+
+ TEST ("[EMAIL PROTECTED]" ),
+ TEST ("xx" ),
+
+ TEST ("[EMAIL PROTECTED]@2048" ),
+ TEST ("[EMAIL PROTECTED]@2047" ),
+
+ TEST ("last" )
+};
+
+/**************************************************************************/
+
+// exercises:
+// get_allocator ()
+static const StringTestCase
+get_allocator_void_test_cases [] = {
+
+#undef TEST
+#define TEST(str) { \
+ __LINE__, -1, -1, -1, -1, -1, \
+ str, sizeof (str) - 1, \
+ 0, 0, 0, 0, 0 \
+}
+
+ // +------------------------------------------ controlled sequence
+ // |
+ // |
+ // |
+ // |
+ // |
+ // |
+ // |
+ // V
+ TEST ("ab" ),
+ TEST ("" ),
+ TEST ("\0" ),
+ TEST ("[EMAIL PROTECTED]" ),
+ TEST ("a\0b" ),
+ TEST ("[EMAIL PROTECTED]@2047" ),
+ TEST ("last" )
+};
+
+
+/**************************************************************************/
+
+template <class charT, class Traits, class Allocator>
+void test_iterators (charT*, Traits*, Allocator*,
+ const StringTestCaseData<charT> &tdata)
+{
+ typedef std::basic_string <charT, Traits, Allocator> String;
+ typedef typename String::iterator StringIter;
+ typedef typename String::const_iterator StringCIter;
+ typedef typename String::reverse_iterator StringRIter;
+ typedef typename String::const_reverse_iterator StringCRIter;
+
+ const StringFunc &func = tdata.func_;
+ const StringTestCase &tcase = tdata.tcase_;
+
+ const bool test_iters = func.which_ == StringIds::begin_void
+ || func.which_ == StringIds::begin_const_void
+ || func.which_ == StringIds::end_void
+ || func.which_ == StringIds::end_const_void
+ || func.which_ == StringIds::rbegin_void
+ || func.which_ == StringIds::rbegin_const_void
+ || func.which_ == StringIds::rend_void
+ || func.which_ == StringIds::rend_const_void;
+
+ const bool test_const_iters = func.which_ == StringIds::begin_const_void
+ || func.which_ == StringIds::end_const_void
+ || func.which_ == StringIds::rbegin_const_void
+ || func.which_ == StringIds::rend_const_void;
+
+ const bool test_end_iters = func.which_ == StringIds::end_void
+ || func.which_ == StringIds::end_const_void
+ || func.which_ == StringIds::rend_void
+ || func.which_ == StringIds::rend_const_void;
+
+ // allocator object for test get_allocator
+ Allocator alloc;
+
+ // construct the string object
+ String str (tdata.str_, tdata.strlen_, alloc);
+ // construct the constant string object
+ const String cstr (tdata.str_, tdata.strlen_, alloc);
+
+ const std::size_t s_size = test_const_iters ? cstr.size () : str.size ();
+
+ // 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 (str));
+
+ 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
+
+ // 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 [1]; // 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;
+
+#endif // _RWSTD_NO_EXCEPTIONS
+
+ // start checking for memory leaks
+ rw_check_leaks (str.get_allocator ());
+
+ // for data () and c_str ()
+ const charT* ret_ptr = 0;
+
+ // methods result
+ charT res;
+
+ // for begin () and end ()
+ StringIter it;
+ // for begin () const and end () const
+ StringCIter cit;
+ // for rbegin () and rend ()
+ StringRIter rit;
+ // for rbegin () const and rend () const
+ StringCRIter crit;
+
+ // for get_allocator ()
+ Allocator resalloc;
+
+ try {
+
+ bool it_relations = true;
+
+ switch (func.which_) {
+
+ case StringIds::begin_void:
+ it = str.begin();
+ res = s_size ? *it : charT ();
+ it_relations = it == str.rend ().base ();
+ break;
+
+ case StringIds::begin_const_void:
+ cit = cstr.begin();
+ res = s_size ? *cit : charT ();
+ it_relations = cit == cstr.rend ().base ();
+ break;
+
+ case StringIds::end_void:
+ it = str.end();
+ res = s_size ? *(it - 1) : charT ();
+ it_relations = it == str.rbegin ().base ();
+ break;
+
+ case StringIds::end_const_void:
+ cit = cstr.end();
+ res = s_size ? *(cit - 1) : charT ();
+ it_relations = cit == cstr.rbegin ().base ();
+ break;
+
+ case StringIds::rbegin_void:
+ rit = str.rbegin();
+ res = s_size ? *rit : charT ();
+ it_relations = rit.base () == str.end ();
+ break;
+
+ case StringIds::rbegin_const_void:
+ crit = cstr.rbegin();
+ res = s_size ? *crit : charT ();
+ it_relations = crit.base () == cstr.end ();
+ break;
+
+ case StringIds::rend_void:
+ rit = str.rend();
+ res = s_size ? *(rit - 1) : charT ();
+ it_relations = rit.base () == str.begin ();
+ break;
+
+ case StringIds::rend_const_void:
+ crit = cstr.rend();
+ res = s_size ? *(crit - 1) : charT ();
+ it_relations = crit.base () == cstr.begin ();
+ break;
+
+ case StringIds::c_str_void:
+ ret_ptr = cstr.c_str ();
+ break;
+
+ case StringIds::data_void:
+ ret_ptr = cstr.data ();
+ break;
+
+ case StringIds::get_allocator_void:
+ resalloc = cstr.get_allocator ();
+ break;
+
+ default:
+ RW_ASSERT ("test logic error: unknown iterators overload");
+ return;
+ }
+
+ // for convenience
+ static const int cwidth = sizeof (charT);
+
+ if ( func.which_ == StringIds::data_void
+ || func.which_ == StringIds::c_str_void) {
+
+ // 21.3.6
+ // the member returns a non-null pointer
+ rw_assert(0 != ret_ptr, 0, tcase.line,
+ "line %d. %{$FUNCALL} expected non null, got null",
+ __LINE__);
+
+ // 21.3.6.1
+ // if size() is nonzero, the member returns a pointer to the
+ // initial element of an array whose first size() elements
+ // equal the corresponding elements of the string controlled
+ // by *this
+ // 21.3.6.3
+ // if size() is nonzero, the member returns a pointer to the
+ // initial element of an array whose first size() elements
+ // equal the corresponding elements of the string controlled
+ // by *this
+ const std::size_t match =
+ rw_match (tcase.res, ret_ptr, tcase.nres);
+
+ rw_assert (match == tdata.reslen_, 0, tcase.line,
+ "line %d. %{$FUNCALL} expected %{#*s}, "
+ "got %{/*.*Gs}, differ at pos %zu",
+ __LINE__, int (tdata.reslen_), tdata.res_,
+ cwidth, int (s_size), ret_ptr, match);
+
+ if (func.which_ == StringIds::c_str_void) {
+
+ // check the last element is equal to char ()
+ const char null = char ();
+ const bool success =
+ (1 == rw_match (&null, &ret_ptr[s_size], 1));
+
+ rw_assert(success, 0, tcase.line,
+ "line %d. %{$FUNCALL} expected last element "
+ "is a null character %{#c}, got %{#c}",
+ __LINE__, null, ret_ptr[s_size]);
+ }
+ }
+
+ if (test_iters) {
+
+ if (s_size) {
+
+ const char exp_res =
+ (NPOS != tcase.nres ? char (tcase.nres) : char ());
+
+ const bool success = (1 == rw_match (&exp_res, &res, 1));
+
+ rw_assert (success, 0, tcase.line,
+ "line %d. %{$FUNCALL}%{?} - 1%{;} expected "
+ "%{#c}, got %{#c}", __LINE__,
+ test_end_iters, exp_res, res);
+ }
+ else {
+ bool success = true;
+
+ if ( func.which_ == StringIds::begin_void
+ || func.which_ == StringIds::end_void)
+ success = it == str.begin () && it == str.end ();
+
+ if ( func.which_ == StringIds::begin_const_void
+ || func.which_ == StringIds::end_const_void)
+ success = cit == cstr.begin () && cit == cstr.end ();
+
+ if ( func.which_ == StringIds::rbegin_void
+ || func.which_ == StringIds::rend_void)
+ success = rit == str.rbegin () && rit == str.rend ();
+
+ if ( func.which_ == StringIds::rbegin_const_void
+ || func.which_ == StringIds::rend_const_void)
+ success =
+ crit == cstr.rbegin () && crit == cstr.rend ();
+
+ // check the begin () == end (), rbegin () == rend ()
+ rw_assert(success, 0, tcase.line,
+ "line %d. %{$FUNCALL} returned iterator is not "
+ "equal to begin and end for an empty string",
+ __LINE__);
+ }
+
+ // check the iterators relationship
+ rw_assert(it_relations, 0, tcase.line,
+ "line %d. %{$FUNCALL} iterators "
+ "relationship is broken", __LINE__);
+ }
+
+ if (func.which_ == StringIds::get_allocator_void) {
+
+ // verify that the allocator returned from the function
+ // equal to allocator passed to the ctor
+ const bool success = (alloc == resalloc);
+
+ rw_assert(success, 0, tcase.line,
+ "line %d. %{$FUNCALL} expected equal to allocator "
+ "passed to the ctor", __LINE__);
+ }
+ }
+
+#ifndef _RWSTD_NO_EXCEPTIONS
+
+ catch (const std::bad_alloc &ex) {
+ caught = exceptions [1];
+ 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 [2];
+ 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 (str.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 (str),
+ __LINE__, tcase.line, caught);
+
+ // 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;
+ }
+
+ break;
+ }
+
+ rw_assert (0 == throw_count, 0, tcase.line,
+ "line %d: %{$FUNCALL}: expected 0 %s exceptions, got %zu",
+ __LINE__, exceptions [1], throw_count);
+
+ // disable bad_alloc exceptions
+ *pst->throw_at_calls_ [0] = 0;
+ pal->throw_at_calls_ [pal->m_allocate] = 0;
+}
+
+/**************************************************************************/
+
+DEFINE_STRING_TEST_FUNCTIONS (test_iterators);
+
+int main (int argc, char** argv)
+{
+ static const StringTest
+ tests [] = {
+
+#undef TEST
+#define TEST(gsig, sig) { \
+ gsig, sig ## _test_cases, \
+ sizeof sig ## _test_cases / sizeof *sig ## _test_cases \
+}
+
+ TEST (StringIds::begin_void, begin_void),
+ TEST (StringIds::begin_const_void, begin_void),
+ TEST (StringIds::end_void, end_void),
+ TEST (StringIds::end_const_void, end_void),
+ TEST (StringIds::rbegin_void, end_void),
+ TEST (StringIds::rbegin_const_void, end_void),
+ TEST (StringIds::rend_void, begin_void),
+ TEST (StringIds::rend_const_void, begin_void),
+ TEST (StringIds::c_str_void, c_str_void),
+ TEST (StringIds::data_void, c_str_void),
+ TEST (StringIds::get_allocator_void, get_allocator_void)
+ };
+
+ const std::size_t test_count = sizeof tests / sizeof *tests;
+
+ return rw_run_string_test (argc, argv, __FILE__,
+ "lib.string.iterators",
+ test_iterators_func_array, tests, test_count);
+}
Propchange: incubator/stdcxx/trunk/tests/strings/21.string.iterators.cpp
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/stdcxx/trunk/tests/strings/21.string.iterators.cpp
------------------------------------------------------------------------------
svn:keywords = Id