You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@stdcxx.apache.org by se...@apache.org on 2006/05/29 01:59:32 UTC
svn commit: r410005 - in /incubator/stdcxx/trunk/tests: include/21.strings.h
src/21.strings.cpp
Author: sebor
Date: Sun May 28 16:59:29 2006
New Revision: 410005
URL: http://svn.apache.org/viewvc?rev=410005&view=rev
Log:
2006-05-28 Martin Sebor <se...@roguewave.com>
* 21.strings.h (StringTestCaseData): New helper class template.
(VoidFunc): New helper typedef.
(DEFINE_STRING_TEST_FUNCTIONS): New helper macro to define an
array of pointers to test functions (typically specializations
of the same function template) and to obviate the need for the
definition of the dispatch function in each test.
(rw_run_string_test): Added a new overload taking an array of
VoidFunc.
* 21.strings.cpp (<string>, <rw_allocator.h>): Included headers.
(_rw_dispatch): Added a set of overloaded function templates.
(_rw_test_case): Added a VoidFunc[] argument and invoked
_rw_dispatch.
(_rw_func_array): New global array of pointers to test functions.
(_rw_run_test): Passed _rw_func_array to _rw_test_case.
(_rw_run_test): Moved body of rw_run_string_test here.
(rw_run_string_test): Called _rw_run_test.
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=410005&r1=410004&r2=410005&view=diff
==============================================================================
--- incubator/stdcxx/trunk/tests/include/21.strings.h (original)
+++ incubator/stdcxx/trunk/tests/include/21.strings.h Sun May 28 16:59:29 2006
@@ -28,10 +28,14 @@
#ifndef RW_21_STRINGS_H_INCLUDED
#define RW_21_STRINGS_H_INCLUDED
+#include <rw_char.h> // for rw_expand()
#include <testdefs.h>
/**************************************************************************/
+// defines enumerations identifying basic_string template arguments,
+// sets of overloaded functions, member types used in the declarations
+// of their signatures, and specific overloads of such member functions
struct StringIds {
// identifiers for the charT template argument
@@ -597,6 +601,97 @@
rw_run_string_test (int, char**, const char*, const char*,
StringTestFunc*, const StringTest*, _RWSTD_SIZE_T);
+typedef void VoidFunc ();
+
+_TEST_EXPORT int
+rw_run_string_test (int, char**, const char*, const char*,
+ VoidFunc* const*, const StringTest*, _RWSTD_SIZE_T);
+
+/**************************************************************************/
+
+template <class charT>
+class StringTestCaseData
+{
+private:
+
+ enum { BUFSIZE = 256 };
+
+ // small buffers to avoid expensive dynamic memory allocation
+ // in most test cases (will dynamically allocate sufficient
+ // storage if necessary)
+ charT str_buf_ [BUFSIZE];
+ charT arg_buf_ [BUFSIZE];
+ charT res_buf_ [BUFSIZE];
+
+ // not defined, not copiable, not assignable
+ StringTestCaseData (const StringTestCaseData&);
+ void operator= (const StringTestCaseData&);
+
+ // for convenience
+ typedef _RWSTD_SIZE_T SizeType;
+
+public:
+
+ SizeType strlen_; // the length of the expanded string
+ SizeType arglen_; // the length of the expanded argument
+ SizeType reslen_; // the length of the expanded result
+
+ // the offset and extent (the number of elements) of
+ // the first range into the string object being modified
+ SizeType off1_;
+ SizeType ext1_;
+
+ // the offset and extent (the number of elements) of
+ // the argument of the function call
+ SizeType off2_;
+ SizeType ext2_;
+
+ const charT* const str_; // pointer to the expanded string
+ const charT* const arg_; // pointer to the expanded argument
+ const charT* const res_; // pointer to the expanded result
+
+ const StringFunc &func_;
+ const StringTestCase &tcase_;
+
+ // converts the narrow (and possibly) condensed strings to fully
+ // expanded wide character arrays that can be used to construct
+ // basic_string objects
+ StringTestCaseData (const StringFunc &func, const StringTestCase &tcase)
+ : strlen_ (BUFSIZE), arglen_ (BUFSIZE), reslen_ (BUFSIZE),
+ str_ (rw_expand (str_buf_, tcase.str, tcase.str_len, &strlen_)),
+ arg_ (rw_expand (arg_buf_, tcase.arg, tcase.arg_len, &arglen_)),
+ res_ (rw_expand (res_buf_, tcase.res, tcase.nres, &reslen_)),
+ func_ (func), tcase_ (tcase) {
+ // compute the offset and extent of the string object
+ // representing the controlled sequence and the offset
+ // and extent of the argument of the function call
+ const SizeType argl = tcase_.arg ? arglen_ : strlen_;
+
+ off1_ = SizeType (tcase_.off) < strlen_ ?
+ SizeType (tcase_.off) : strlen_;
+
+ ext1_ = off1_ + tcase_.size < strlen_ ?
+ SizeType (tcase_.size) : strlen_ - off1_;
+
+ off2_ = SizeType (tcase_.off2) < argl ?
+ SizeType (tcase_.off2) : argl;
+
+ ext2_ = off2_ + tcase_.size2 < argl ?
+ SizeType (tcase_.size2) : argl - off2_;
+ }
+
+ ~StringTestCaseData () {
+ // clean up dynamically allocated memory (if any)
+ if (str_ != str_buf_)
+ delete[] _RWSTD_CONST_CAST (charT*, str_);
+ if (arg_ != arg_buf_)
+ delete[] _RWSTD_CONST_CAST (charT*, arg_);
+ if (res_ != res_buf_)
+ delete[] _RWSTD_CONST_CAST (charT*, res_);
+ }
+};
+
+/**************************************************************************/
// encapsulates the state of a string object without regard to type
// used in exception safety tests to determine changes to the state
@@ -696,6 +791,55 @@
else \
RW_ASSERT (!"logic error: bad allocator"); \
} typedef void rw_unused_typedef
-
+
+
+#define TFUNC(charT, Traits, Allocator) \
+ void (*)(charT*, Traits<charT>*, Allocator<charT>*, \
+ const StringTestCaseData<charT>&)
+
+#define TFUNC_ADDR(fname, charT, Traits, Allocator) \
+ (VoidFunc*)(TFUNC (charT, Traits, Allocator)) \
+ &fname<charT, Traits<charT>, Allocator<charT> >
+
+#ifndef _RWSTD_NO_WCHAR_T
+# define DEFINE_STRING_TEST_FUNCTIONS(fname) \
+ static VoidFunc* const fname ## _func_array [] = { \
+ TFUNC_ADDR (fname, char, std::char_traits, std::allocator), \
+ TFUNC_ADDR (fname, char, std::char_traits, UserAlloc), \
+ TFUNC_ADDR (fname, char, UserTraits, std::allocator), \
+ TFUNC_ADDR (fname, char, UserTraits, UserAlloc), \
+ \
+ TFUNC_ADDR (fname, wchar_t, std::char_traits, std::allocator), \
+ TFUNC_ADDR (fname, wchar_t, std::char_traits, UserAlloc), \
+ TFUNC_ADDR (fname, wchar_t, UserTraits, std::allocator), \
+ TFUNC_ADDR (fname, wchar_t, UserTraits, UserAlloc), \
+ \
+ (VoidFunc*)0, /* std::char_traits<UserChar> not allowed */ \
+ (VoidFunc*)0, /* std::char_traits<UserChar> not allowed */ \
+ TFUNC_ADDR (fname, UserChar, UserTraits, std::allocator), \
+ TFUNC_ADDR (fname, UserChar, UserTraits, UserAlloc) \
+ }
+
+#else // if defined (_RWSTD_NO_WCHAR_T)
+# define DEFINE_STRING_TEST_FUNCTIONS(fname) \
+ static VoidFunc* const fname ## _func_array [] = { \
+ TFUNC_ADDR (fname, char, std::char_traits, std::allocator), \
+ TFUNC_ADDR (fname, char, std::char_traits, UserAlloc), \
+ TFUNC_ADDR (fname, char, UserTraits, std::allocator), \
+ TFUNC_ADDR (fname, char, UserTraits, UserAlloc), \
+ \
+ (VoidFunc*)0, /* wchar_t disabled */ \
+ (VoidFunc*)0, /* wchar_t disabled */ \
+ (VoidFunc*)0, /* wchar_t disabled */ \
+ (VoidFunc*)0, /* wchar_t disabled */ \
+ \
+ (VoidFunc*)0, /* std::char_traits<UserChar> not allowed */ \
+ (VoidFunc*)0, /* std::char_traits<UserChar> not allowed */ \
+ TFUNC_ADDR (fname, UserChar, UserTraits, std::allocator), \
+ TFUNC_ADDR (fname, UserChar, UserTraits, UserAlloc) \
+ }
+
+#endif // _RWSTD_NO_WCHAR_T
+
#endif // RW_21_STRINGS_H_INCLUDED
Modified: incubator/stdcxx/trunk/tests/src/21.strings.cpp
URL: http://svn.apache.org/viewvc/incubator/stdcxx/trunk/tests/src/21.strings.cpp?rev=410005&r1=410004&r2=410005&view=diff
==============================================================================
--- incubator/stdcxx/trunk/tests/src/21.strings.cpp (original)
+++ incubator/stdcxx/trunk/tests/src/21.strings.cpp Sun May 28 16:59:29 2006
@@ -28,19 +28,23 @@
// expand _TEST_EXPORT macros
#define _RWSTD_TEST_SRC
+#include <memory> // for allocator
+#include <string> // for char_traits
+
#include <21.strings.h>
-#include <cmdopt.h> // for rw_enabled()
-#include <driver.h> // for rw_info()
-#include <environ.h> // for rw_putenv()
-#include <rw_char.h> // for rw_expand()
-#include <rw_printf.h> // for rw_asnprintf()
-
-#include <ctype.h> // for isdigit()
-#include <stdarg.h> // for va_arg, ...
-#include <stddef.h> // for size_t
-#include <stdlib.h> // for free()
-#include <string.h> // for memset()
+#include <cmdopt.h> // for rw_enabled()
+#include <driver.h> // for rw_info()
+#include <environ.h> // for rw_putenv()
+#include <rw_allocator.h> // for UserAlloc
+#include <rw_char.h> // for rw_expand()
+#include <rw_printf.h> // for rw_asnprintf()
+
+#include <ctype.h> // for isdigit()
+#include <stdarg.h> // for va_arg, ...
+#include <stddef.h> // for size_t
+#include <stdlib.h> // for free()
+#include <string.h> // for memset()
/**************************************************************************/
@@ -926,10 +930,101 @@
/**************************************************************************/
+template <class charT, class Traits, class Allocator>
+void
+_rw_dispatch (charT*, Traits*, Allocator*,
+ VoidFunc* const *farray,
+ const StringFunc &func,
+ const StringTestCase &tcase)
+{
+ typedef StringTestCaseData<charT> Data;
+ typedef void TestFunc (charT, Traits*, Allocator*, const Data&);
+
+ const size_t inx = func.char_id_ * 4 + func.traits_id_ * 2 + func.alloc_id_;
+
+ TestFunc* const tfunc = _RWSTD_REINTERPRET_CAST (TestFunc*, farray [inx]);
+
+ const Data tdata (func, tcase);
+
+ tfunc (charT (), (Traits*)0, (Allocator*)0, tdata);
+}
+
+
+template <class charT, class Traits>
+void
+_rw_dispatch (charT*, Traits*,
+ VoidFunc* const *farray,
+ const StringFunc &func,
+ const StringTestCase &tcase)
+{
+ if (StringIds::DefaultAlloc == func.alloc_id_) {
+ typedef std::allocator<charT> Alloc;
+ _rw_dispatch ((charT*)0, (Traits*)0, (Alloc*)0, farray, func, tcase);
+ }
+ else if (StringIds::UserAlloc == func.alloc_id_) {
+ typedef UserAlloc<charT> Alloc;
+ _rw_dispatch ((charT*)0, (Traits*)0, (Alloc*)0, farray, func, tcase);
+ }
+ else {
+ RW_ASSERT (!"logic error: unknown Allocator argument");
+ }
+}
+
+
+template <class charT>
+void
+_rw_dispatch (charT*,
+ VoidFunc* const *farray,
+ const StringFunc &func,
+ const StringTestCase &tcase)
+{
+ if (StringIds::DefaultTraits == func.traits_id_) {
+ typedef std::char_traits<charT> Traits;
+ _rw_dispatch ((charT*)0, (Traits*)0, farray, func, tcase);
+ }
+ else if (StringIds::UserTraits == func.traits_id_) {
+ typedef UserTraits<charT> Traits;
+ _rw_dispatch ((charT*)0, (Traits*)0, farray, func, tcase);
+ }
+ else {
+ RW_ASSERT (!"logic error: unknown Traits argument");
+ }
+
+}
+
+
+static void
+_rw_dispatch (VoidFunc* const *farray,
+ const StringFunc &func,
+ const StringTestCase &tcase)
+{
+ if (StringIds::Char == func.char_id_) {
+ _rw_dispatch ((char*)0, farray, func, tcase);
+ }
+ else if (StringIds::WChar == func.char_id_) {
+ _rw_dispatch ((wchar_t*)0, farray, func, tcase);
+ }
+ else if (StringIds::UChar == func.char_id_) {
+ if (StringIds::DefaultTraits == func.traits_id_) {
+ RW_ASSERT (!"logic error: std::char_traits<UserChar> not allowed");
+ }
+ else if (StringIds::UserTraits == func.traits_id_) {
+ typedef UserTraits<UserChar> Traits;
+ _rw_dispatch ((UserChar*)0, (Traits*)0, farray, func, tcase);
+ }
+ }
+ else {
+ RW_ASSERT (!"logic error: unknown charT argument");
+ }
+}
+
+/**************************************************************************/
+
static void
_rw_test_case (const StringFunc &func,
const StringTestCase &tcase,
- StringTestFunc *test_callback)
+ StringTestFunc *test_callback,
+ VoidFunc* const *farray)
{
// check to see if this is an exception safety test case
// and avoid running it when exception safety has been
@@ -977,8 +1072,13 @@
// the function call specified by this test case
_rw_setvars (func, &tcase);
- // invoke the test function
- test_callback (func, tcase);
+ if (test_callback) {
+ // invoke the test callback function
+ test_callback (func, tcase);
+ }
+ else {
+ _rw_dispatch (farray, func, tcase);
+ }
}
else
rw_note (0, _rw_this_file, tcase.line,
@@ -1007,6 +1107,10 @@
static StringTestFunc*
_rw_test_callback;
+static VoidFunc* const*
+_rw_func_array;
+
+
static int
_rw_run_test (int, char*[])
{
@@ -1144,7 +1248,8 @@
const StringTestCase& tcase = test.cases [n];
- _rw_test_case (func, tcase, _rw_test_callback);
+ _rw_test_case (func, tcase,
+ _rw_test_callback, _rw_func_array);
}
}
}
@@ -1156,17 +1261,19 @@
/**************************************************************************/
-_TEST_EXPORT int
-rw_run_string_test (int argc,
- char *argv [],
- const char *file,
- const char *clause,
- StringTestFunc *test_callback,
- const StringTest *tests,
- size_t test_count)
+static int
+_rw_run_test (int argc,
+ char *argv [],
+ const char *file,
+ const char *clause,
+ StringTestFunc *test_callback,
+ VoidFunc* const *func_array,
+ const StringTest *tests,
+ size_t test_count)
{
// set the global variables accessed in _rw_run_test
_rw_test_callback = test_callback;
+ _rw_func_array = func_array,
_rw_string_tests = tests;
_rw_string_test_count = test_count;
@@ -1266,4 +1373,31 @@
free (optbuf);
return status;
+}
+
+
+
+_TEST_EXPORT int
+rw_run_string_test (int argc,
+ char *argv [],
+ const char *file,
+ const char *clause,
+ StringTestFunc *callback,
+ const StringTest *tests,
+ size_t count)
+{
+ return _rw_run_test (argc, argv, file, clause, callback, 0, tests, count);
+}
+
+
+_TEST_EXPORT int
+rw_run_string_test (int argc,
+ char *argv [],
+ const char *file,
+ const char *clause,
+ VoidFunc* const *farray,
+ const StringTest *tests,
+ size_t count)
+{
+ return _rw_run_test (argc, argv, file, clause, 0, farray, tests, count);
}