From stdcxx-commits-return-730-apmail-incubator-stdcxx-commits-archive=incubator.apache.org@incubator.apache.org Sun May 28 23:59:56 2006 Return-Path: Delivered-To: apmail-incubator-stdcxx-commits-archive@www.apache.org Received: (qmail 39704 invoked from network); 28 May 2006 23:59:56 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (209.237.227.199) by minotaur.apache.org with SMTP; 28 May 2006 23:59:56 -0000 Received: (qmail 83961 invoked by uid 500); 28 May 2006 23:59:56 -0000 Delivered-To: apmail-incubator-stdcxx-commits-archive@incubator.apache.org Received: (qmail 83939 invoked by uid 500); 28 May 2006 23:59:55 -0000 Mailing-List: contact stdcxx-commits-help@incubator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: stdcxx-dev@incubator.apache.org Delivered-To: mailing list stdcxx-commits@incubator.apache.org Received: (qmail 83925 invoked by uid 99); 28 May 2006 23:59:55 -0000 Received: from asf.osuosl.org (HELO asf.osuosl.org) (140.211.166.49) by apache.org (qpsmtpd/0.29) with ESMTP; Sun, 28 May 2006 16:59:55 -0700 X-ASF-Spam-Status: No, hits=-9.4 required=10.0 tests=ALL_TRUSTED,NO_REAL_NAME X-Spam-Check-By: apache.org Received-SPF: pass (asf.osuosl.org: local policy) Received: from [140.211.166.113] (HELO eris.apache.org) (140.211.166.113) by apache.org (qpsmtpd/0.29) with ESMTP; Sun, 28 May 2006 16:59:54 -0700 Received: by eris.apache.org (Postfix, from userid 65534) id 76DE91A983A; Sun, 28 May 2006 16:59:33 -0700 (PDT) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r410005 - in /incubator/stdcxx/trunk/tests: include/21.strings.h src/21.strings.cpp Date: Sun, 28 May 2006 23:59:32 -0000 To: stdcxx-commits@incubator.apache.org From: sebor@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20060528235933.76DE91A983A@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org X-Spam-Rating: minotaur.apache.org 1.6.2 0/1000/N 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 * 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 (, ): 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 // for rw_expand() #include /**************************************************************************/ +// 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 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*, Allocator*, \ + const StringTestCaseData&) + +#define TFUNC_ADDR(fname, charT, Traits, Allocator) \ + (VoidFunc*)(TFUNC (charT, Traits, Allocator)) \ + &fname, Allocator > + +#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 not allowed */ \ + (VoidFunc*)0, /* std::char_traits 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 not allowed */ \ + (VoidFunc*)0, /* std::char_traits 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 // for allocator +#include // for char_traits + #include <21.strings.h> -#include // for rw_enabled() -#include // for rw_info() -#include // for rw_putenv() -#include // for rw_expand() -#include // for rw_asnprintf() - -#include // for isdigit() -#include // for va_arg, ... -#include // for size_t -#include // for free() -#include // for memset() +#include // for rw_enabled() +#include // for rw_info() +#include // for rw_putenv() +#include // for UserAlloc +#include // for rw_expand() +#include // for rw_asnprintf() + +#include // for isdigit() +#include // for va_arg, ... +#include // for size_t +#include // for free() +#include // for memset() /**************************************************************************/ @@ -926,10 +930,101 @@ /**************************************************************************/ +template +void +_rw_dispatch (charT*, Traits*, Allocator*, + VoidFunc* const *farray, + const StringFunc &func, + const StringTestCase &tcase) +{ + typedef StringTestCaseData 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 +void +_rw_dispatch (charT*, Traits*, + VoidFunc* const *farray, + const StringFunc &func, + const StringTestCase &tcase) +{ + if (StringIds::DefaultAlloc == func.alloc_id_) { + typedef std::allocator Alloc; + _rw_dispatch ((charT*)0, (Traits*)0, (Alloc*)0, farray, func, tcase); + } + else if (StringIds::UserAlloc == func.alloc_id_) { + typedef UserAlloc Alloc; + _rw_dispatch ((charT*)0, (Traits*)0, (Alloc*)0, farray, func, tcase); + } + else { + RW_ASSERT (!"logic error: unknown Allocator argument"); + } +} + + +template +void +_rw_dispatch (charT*, + VoidFunc* const *farray, + const StringFunc &func, + const StringTestCase &tcase) +{ + if (StringIds::DefaultTraits == func.traits_id_) { + typedef std::char_traits Traits; + _rw_dispatch ((charT*)0, (Traits*)0, farray, func, tcase); + } + else if (StringIds::UserTraits == func.traits_id_) { + typedef UserTraits 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 not allowed"); + } + else if (StringIds::UserTraits == func.traits_id_) { + typedef UserTraits 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); }