You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@stdcxx.apache.org by an...@apache.org on 2006/05/15 10:16:10 UTC
svn commit: r406582 -
/incubator/stdcxx/trunk/tests/strings/21.string.access.cpp
Author: antonp
Date: Mon May 15 01:16:06 2006
New Revision: 406582
URL: http://svn.apache.org/viewcvs?rev=406582&view=rev
Log:
2006-05-15 Anton Pevtsov <an...@moscow.vdiweb.com>
STDCXX-4
* 21.string.access.cpp: New test exercising lib.string.access.
Modified:
incubator/stdcxx/trunk/tests/strings/21.string.access.cpp
Modified: incubator/stdcxx/trunk/tests/strings/21.string.access.cpp
URL: http://svn.apache.org/viewcvs/incubator/stdcxx/trunk/tests/strings/21.string.access.cpp?rev=406582&r1=406581&r2=406582&view=diff
==============================================================================
--- incubator/stdcxx/trunk/tests/strings/21.string.access.cpp (original)
+++ incubator/stdcxx/trunk/tests/strings/21.string.access.cpp Mon May 15 01:16:06 2006
@@ -19,282 +19,331 @@
*
**************************************************************************/
-#include <stdexcept> // for out_of_range
-#include <string> // for basic_string
-
-#include <cmdopt.h>
-#include <driver.h>
+#include <string> // for string
+#include <cstdlib> // for free(), size_t
+#include <stdexcept> // for out_of_range
+
+#include <21.strings.h> // for StringMembers
+#include <driver.h> // for rw_test()
+#include <rw_char.h> // for rw_expand()
/**************************************************************************/
-template <class charT>
-class Lit;
-
-_RWSTD_SPECIALIZED_CLASS
-class Lit<char>
-{
-public:
- static const char null[];
- static const char a[];
- static const char e[];
- static const char s[];
- static const char t[];
- static const char x[];
- static const char T[];
- static const char _TypeT[];
- static const char space[];
- static const char testString[];
- static const char testString2[];
- static const char text[];
- static const char testNullString[];
- static const char testStringToBeWipedClean[];
- static const char test[];
- static const char anotherTest[];
- static const char testNull00String[];
- static const char tString[];
- static const char str[];
- static const char tNull00s[];
- static const char more[];
+// for convenience and brevity
+#define NPOS _RWSTD_SIZE_MAX
+#define At(which) StringMembers::at_ ## which
+#define OpIndex(which) StringMembers::op_index_ ## which
+
+typedef StringMembers::OverloadId OverloadId;
+typedef StringMembers::TestCase TestCase;
+typedef StringMembers::Test Test;
+typedef StringMembers::Function MemFun;
+
+static const char* const exceptions[] = {
+ "unknown exception", "out_of_range", "length_error",
+ "bad_alloc", "exception"
};
-const char Lit<char>:: null[] = "\0";
-const char Lit<char>:: a[] = "a";
-const char Lit<char>:: e[] = "e";
-const char Lit<char>:: s[] = "s";
-const char Lit<char>:: t[] = "t";
-const char Lit<char>:: T[] = "T";
-const char Lit<char>:: _TypeT[] = "_TypeT";
-const char Lit<char>:: x[] = "x";
-const char Lit<char>:: space[] = " ";
-const char Lit<char>:: testString[] = "test string";
-const char Lit<char>:: testString2[] = "Test string";
-const char Lit<char>:: text[] = "Text";
-const char Lit<char>:: testNullString[] = "Test\0string";
-const char Lit<char>:: testStringToBeWipedClean[] =
-"Test string to be wiped clean";
-const char Lit<char>:: test[] = "Test";
-const char Lit<char>:: anotherTest[] = "Another test";
-const char Lit<char>:: testNull00String[] = "Test\000 string";
-const char Lit<char>:: tString[] = "t string";
-const char Lit<char>:: str[] = "str";
-const char Lit<char>:: tNull00s[] = "t\000 s";
-const char Lit<char>:: more[] = "more";
-
+/**************************************************************************/
-#ifndef _RWSTD_NO_WCHAR_T
+// used to exercise
+// operator[] (size_type)
+static const TestCase
+op_index_size_test_cases [] = {
+
+#undef TEST
+#define TEST(str, off, res) { \
+ __LINE__, off, -1, -1, -1, -1, \
+ str, sizeof str - 1, \
+ 0, 0, 0, res, 0 \
+ }
-_RWSTD_SPECIALIZED_CLASS
-class Lit<wchar_t>
-{
-public:
- static const wchar_t null[];
- static const wchar_t a[];
- static const wchar_t e[];
- static const wchar_t s[];
- static const wchar_t t[];
- static const wchar_t T[];
- static const wchar_t _TypeT[];
- static const wchar_t x[];
- static const wchar_t space[];
- static const wchar_t testString[];
- static const wchar_t testString2[];
- static const wchar_t text[];
- static const wchar_t testNullString[];
- static const wchar_t testStringToBeWipedClean[];
- static const wchar_t test[];
- static const wchar_t anotherTest[];
- static const wchar_t testNull00String[];
- static const wchar_t tString[];
- static const wchar_t str[];
- static const wchar_t tNull00s[];
- static const wchar_t more[];
+ // +--------------------------------- controlled sequence
+ // | +----------------- index
+ // | | +------------- expected result
+ // | | |
+ // V V V
+ TEST ("a", 0, 'a' ),
+
+ TEST ("\0", 0, '\0'),
+
+ TEST ("abc", 0, 'a' ),
+ TEST ("abc", 1, 'b' ),
+ TEST ("abc", 2, 'c' ),
+
+ TEST ("\0ab\0\0c", 0, '\0'),
+
+ TEST ("a\0b\0\0c", 0, 'a' ),
+ TEST ("a\0b\0\0c", 1, '\0'),
+ TEST ("a\0b\0\0c", 2, 'b' ),
+ TEST ("a\0b\0\0c", 3, '\0'),
+ TEST ("a\0b\0\0c", 4, '\0'),
+ TEST ("a\0b\0\0c", 5, 'c' ),
+
+ TEST ("a\0bc\0\0", 5, '\0'),
+
+ TEST ("x@4096", 0, 'x' ),
+ TEST ("x@4096", 2048, 'x' ),
+ TEST ("x@4096", 4095, 'x' ),
+ TEST ("last", 3, 't' )
};
-const wchar_t Lit<wchar_t>:: null[] = L"\0";
-const wchar_t Lit<wchar_t>:: a[] = L"a";
-const wchar_t Lit<wchar_t>:: e[] = L"e";
-const wchar_t Lit<wchar_t>:: s[] = L"s";
-const wchar_t Lit<wchar_t>:: t[] = L"t";
-const wchar_t Lit<wchar_t>:: T[] = L"T";
-const wchar_t Lit<wchar_t>:: _TypeT[] = L"_TypeT";
-const wchar_t Lit<wchar_t>:: x[] = L"x";
-const wchar_t Lit<wchar_t>:: space[] = L" ";
-const wchar_t Lit<wchar_t>:: testString[] = L"test string";
-const wchar_t Lit<wchar_t>:: testString2[] = L"Test string";
-const wchar_t Lit<wchar_t>:: text[] = L"Text";
-const wchar_t Lit<wchar_t>:: testNullString[] = L"Test\0string";
-const wchar_t Lit<wchar_t>:: testStringToBeWipedClean[] =
-L"Test string to be wiped clean";
-const wchar_t Lit<wchar_t>:: test[] = L"Test";
-const wchar_t Lit<wchar_t>:: anotherTest[] = L"Another test";
-const wchar_t Lit<wchar_t>:: testNull00String[] = L"Test\000 string";
-const wchar_t Lit<wchar_t>:: tString[] = L"t string";
-const wchar_t Lit<wchar_t>:: str[] = L"str";
-const wchar_t Lit<wchar_t>:: tNull00s[] = L"t\000 s";
-const wchar_t Lit<wchar_t>:: more[] = L"more";
+/**************************************************************************/
-#endif // _RWSTD_NO_WCHAR_T
+// used to exercise
+// operator[] (size_type) const
+static const TestCase
+op_index_size_const_test_cases [] = {
+
+#undef TEST
+#define TEST(str, off, res) { \
+ __LINE__, off, -1, -1, -1, -1, \
+ str, sizeof str - 1, \
+ 0, 0, 0, res, 0 \
+ }
-/**************************************************************************/
+ // +--------------------------------- controlled sequence
+ // | +----------------- index
+ // | | +------------- expected result
+ // | | |
+ // V V V
+ TEST ("a", 0, 'a' ),
+ TEST ("a", 1, NPOS),
+
+ TEST ("", 0, NPOS),
+
+ TEST ("\0", 0, '\0'),
+ TEST ("\0", 1, NPOS),
+
+ TEST ("abc", 0, 'a' ),
+ TEST ("abc", 1, 'b' ),
+ TEST ("abc", 2, 'c' ),
+ TEST ("abc", 3, NPOS),
+
+ TEST ("\0ab\0\0c", 0, '\0'),
+
+ TEST ("a\0b\0\0c", 0, 'a' ),
+ TEST ("a\0b\0\0c", 1, '\0'),
+ TEST ("a\0b\0\0c", 2, 'b' ),
+ TEST ("a\0b\0\0c", 3, '\0'),
+ TEST ("a\0b\0\0c", 4, '\0'),
+ TEST ("a\0b\0\0c", 5, 'c' ),
+ TEST ("a\0b\0\0c", 6, NPOS),
+
+ TEST ("a\0bc\0\0", 5, '\0'),
+
+ TEST ("x@4096", 0, 'x' ),
+ TEST ("x@4096", 2048, 'x' ),
+ TEST ("x@4096", 4095, 'x' ),
+ TEST ("x@4096", 4096, NPOS),
-template <class charT>
-void test_at (charT, const char *cname)
-{
- rw_case (0, 0,
- "basic_string<charT>::at(size_type)",
- "charT=%s", cname);
-
- typedef std::char_traits<charT> Traits;
- typedef std::allocator<charT> Allocator;
- typedef std::basic_string<charT, Traits, Allocator> String;
+ TEST ("last", 3, 't' )
+};
-#ifndef _RWSTD_NO_EXCEPTIONS
+/**************************************************************************/
- {
- bool threw_error = false;
- const String cts(Lit<charT>::testString);
- try { cts.at(cts.length()+1); }
- catch (std::out_of_range) { threw_error = true; }
-
- // Const version throws exception past end
- rw_assert (threw_error, 0, __LINE__, "A1");
-
- threw_error = false;
- try { cts.at(cts.length()); }
- catch (std::out_of_range) { threw_error = true; }
-
- // And it throws one on the ending null
- rw_assert (threw_error, 0, __LINE__, "A2");
-
- String ts(Lit<charT>::testString);
- threw_error = false;
- try { ts.at(ts.length()) = Lit<charT>::a[0]; }
- catch (std::out_of_range) { threw_error = true; }
-
- // Non-const version throws exception at end
- rw_assert (threw_error, 0, __LINE__, "A3");
-
- threw_error = false;
- try { ts.at(ts.length()+4) = Lit<charT>::a[0]; }
- catch (std::out_of_range) { threw_error = true; }
-
- // Non-const version does throw exception past end
- rw_assert (threw_error, 0, __LINE__, "A4");
+// used to exercise
+// at (size_type)
+// at (size_type) const
+static const TestCase
+at_size_test_cases [] = {
+
+#define at_size_const_test_cases at_size_test_cases
+
+#undef TEST
+#define TEST(str, off, res, bthrow) { \
+ __LINE__, off, -1, -1, -1, -1, \
+ str, sizeof str - 1, \
+ 0, 0, 0, res, bthrow \
}
-#endif // _RWSTD_NO_EXCEPTIONS
+ // +--------------------------------- controlled sequence
+ // | +----------------- index
+ // | | +-------------- expected result
+ // | | | +-------- exception info
+ // | | | | 0 - no exception
+ // | | | | 1 - out_of_range
+ // | | | |
+ // V V V V
+ TEST ("a", 0, 'a', 0),
+ TEST ("a", 1, NPOS, 1),
+
+ TEST ("", 0, NPOS, 1),
+
+ TEST ("\0", 0, '\0', 0),
+ TEST ("\0", 1, NPOS, 1),
+
+ TEST ("abc", 0, 'a', 0),
+ TEST ("abc", 1, 'b', 0),
+ TEST ("abc", 2, 'c', 0),
+ TEST ("abc", 3, NPOS, 1),
+
+ TEST ("\0ab\0\0c", 0, '\0', 0),
+
+ TEST ("a\0b\0\0c", 0, 'a', 0),
+ TEST ("a\0b\0\0c", 1, '\0', 0),
+ TEST ("a\0b\0\0c", 2, 'b', 0),
+ TEST ("a\0b\0\0c", 3, '\0', 0),
+ TEST ("a\0b\0\0c", 4, '\0', 0),
+ TEST ("a\0b\0\0c", 5, 'c', 0),
+ TEST ("a\0b\0\0c", 6, NPOS, 1),
+
+ TEST ("a\0bc\0\0", 5, '\0', 0),
+
+ TEST ("x@4096", 0, 'x', 0),
+ TEST ("x@4096", 2048, 'x', 0),
+ TEST ("x@4096", 4095, 'x', 0),
+ TEST ("x@4096", 4096, NPOS, 1),
-}
+ TEST ("last", 3, 't', 0)
+};
/**************************************************************************/
-template <class charT>
-void test_operator_index (charT, const char *cname)
+template <class charT, class Traits>
+void test_access (charT, Traits*,
+ OverloadId which,
+ const TestCase &cs)
{
- rw_case (0, 0,
- "basic_string<charT>::operator[](size_type)",
- "charT=%s", cname);
-
- typedef std::char_traits<charT> Traits;
- typedef std::allocator<charT> Allocator;
- typedef std::basic_string<charT, Traits, Allocator> String;
+ typedef std::allocator<charT> Allocator;
+ typedef std::basic_string <charT, Traits, Allocator> String;
+ typedef typename String::reference StrRef;
+ typedef typename String::const_reference StrConstRef;
-#ifndef _RWSTD_NO_EXCEPTIONS
+ static const std::size_t BUFSIZE = 256;
- {
- String ts (10, Lit<charT>::space[0]);
-
- bool threw_error = false;
- try { ts.at(12); }
- catch (std::out_of_range) { threw_error = true; }
-
- // At member range checks
- rw_assert (threw_error, 0, __LINE__, "A7");
-
-# ifdef _RWSTD_BOUNDS_CHECKING
-
- threw_error = false;
- try { ts[14]; /* Index past end. */ }
- catch (std::out_of_range) { threw_error = true; }
-
- // Sqare brackets NOW range check
- rw_assert (threw_error, 0, __LINE__, "A8");
+ static charT wstr_buf [BUFSIZE];
+ std::size_t str_len = sizeof wstr_buf / sizeof *wstr_buf;
+ charT* wstr = rw_expand (wstr_buf, cs.str, cs.str_len, &str_len);
-# endif // _RWSTD_BOUNDS_CHECKING
+ // construct the string object
+ String s_str (wstr, str_len);
- }
+ if (wstr != wstr_buf)
+ delete[] wstr;
-#endif //_RWSTD_NO_EXCEPTIONS
+ wstr = 0;
- {
- String ts (Lit<charT>::test);
-
- // Character index 0 correct
- rw_assert (ts [0] == Lit<charT>::T [0], 0, __LINE__, "A9");
-
- // Character index 1 correct
- rw_assert (ts [1] == Lit<charT>::e [0], 0, __LINE__, "A10");
-
- // Character index 2 correct
- rw_assert (ts [2] == Lit<charT>::s [0], 0, __LINE__, "A11");
-
- // Character index 3 correct
- rw_assert (ts [3] == Lit<charT>::t [0], 0, __LINE__, "A12");
-
- // Character at end correct
- //
- // NOTE: operator[] throws an exception if _RWSTD_BOUNDS_CHECKING
- // is defined. ONLY on constant strings can we step one beyond
- // the size of the string and get eos().
- //
- // rw_assert (ts [4] == '\0', 0, __LINE__, "A15");
-
- ts [2] = Lit<charT>::x [0];
- // Changing character works
- rw_assert (ts == Lit<charT>::text, 0, __LINE__, "A14");
- }
-}
+ // 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_str));
-/**************************************************************************/
+#ifndef _RWSTD_NO_EXCEPTIONS
-template <class charT>
-void test_access (charT, const char *cname)
-{
- test_at (charT (), cname);
+ // is some exception expected ?
+ const char* expected = 1 == cs.bthrow ? exceptions[1] : 0;
+ const char* caught = 0;
- test_operator_index (charT (), cname);
-}
+#endif // _RWSTD_NO_EXCEPTIONS
-/**************************************************************************/
+ try {
-static int
-run_test (int, char*[])
-{
- if (rw_enabled ("char"))
- test_access (char (), "char");
- else
- rw_note (0, __FILE__, __LINE__, "char test disabled");
+ bool success = false;
+ charT cres;
+ char exp_res = NPOS != cs.nres
+ ? (char) cs.nres
+ : typename std::string::value_type();
+
+ switch (which) {
+ case OpIndex (size): {
+ StrRef res = s_str [cs.off];
+
+ success = 1 == rw_match (&exp_res, &res, 1);
+ cres = res;
+ break;
+ }
+ case OpIndex (size_const): {
+ StrConstRef res = const_cast<const String&>(s_str) [cs.off];
+
+ success = 1 == rw_match (&exp_res, &res, 1);
+ cres = res;
+ break;
+ }
+ case At (size): {
+ StrRef res = s_str.at (cs.off);
+
+ success = 1 == rw_match (&exp_res, &res, 1);
+ cres = res;
+ break;
+ }
+ case At (size_const): {
+ StrConstRef res = const_cast<const String&>(s_str).at (cs.off);
+
+ success = 1 == rw_match (&exp_res, &res, 1);
+ cres = res;
+ break;
+ }
+ default:
+ RW_ASSERT ("test logic error: unknown access overload");
+ return;
+ }
+
+ rw_assert (success, 0, cs.line,
+ "line %d. %{$FUNCALL} == %{#c}, got %{#c}",
+ __LINE__, cs.nres, cres);
+ }
-#ifndef _RWSTD_NO_WCHAR_T
+#ifndef _RWSTD_NO_EXCEPTIONS
- if (rw_enabled ("wchar_t"))
- test_access (wchar_t (), "wchar_t");
- else
- rw_note (0, __FILE__, __LINE__, "wchar_t test disabled");
+ catch (const std::out_of_range &ex) {
+ caught = exceptions [1];
+ 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::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);
+ }
-#endif // _RWSTD_NO_WCHAR_T
+#endif // _RWSTD_NO_EXCEPTIONS
- return 0;
+ 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_str),
+ __LINE__, cs.line, caught);
+ }
}
/**************************************************************************/
-int main (int argc, char *argv[])
+DEFINE_TEST_DISPATCH (test_access);
+
+int main (int argc, char** argv)
{
- return rw_test (argc, argv, __FILE__,
- "lib.string.access",
- 0 /* no comment */,
- run_test,
- 0 /* co command line options */);
+ static const StringMembers::Test
+ tests [] = {
+
+#undef TEST
+#define TEST(tag) { \
+ StringMembers::tag, tag ## _test_cases, \
+ sizeof tag ## _test_cases / sizeof *tag ## _test_cases \
+ }
+
+ TEST (op_index_size),
+ TEST (op_index_size_const),
+ TEST (at_size),
+ TEST (at_size_const)
+ };
+
+ const std::size_t test_count = sizeof tests / sizeof *tests;
+
+ return StringMembers::run_test (argc, argv, __FILE__,
+ "lib.string.access",
+ test_access, tests, test_count);
}
+