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);
 }