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/06/07 03:45:17 UTC

svn commit: r412249 - in /incubator/stdcxx/trunk/tests: include/21.strings.h src/21.strings.cpp

Author: sebor
Date: Tue Jun  6 18:45:17 2006
New Revision: 412249

URL: http://svn.apache.org/viewvc?rev=412249&view=rev
Log:
2006-06-06  Martin Sebor  <se...@roguewave.com>

	* 21.strings.h (IteratorId): New member type of StringIds.
	(StringFunc): Added a new data member.
	* 21.strings.cpp (_rw_iter_names): New.
	(_rw_opt_char_types, ...): Sized based on the corresponding
	_rw_xxx_names arrays.
	(_rw_sigcat): Used _rw_iter_names in function signatures and
	command line option names.
	(_rw_argno): Renamed from _rw_uses_alloc and generalized.
	(_rw_setvars): Simplified the setting of environment variables
	by using the %{paramater!:word} extended directive.
	(_rw_run_cases): New helper.
	(_rw_run_test): Iterated over all IteratorId's and called
	_rw_run_cases.
	(_rw_add_toggles): New helper.
	(_rw_run_test): Called _rw_add_toggles, installed option
	handlers for iterator specializations of member templates.

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=412249&r1=412248&r2=412249&view=diff
==============================================================================
--- incubator/stdcxx/trunk/tests/include/21.strings.h (original)
+++ incubator/stdcxx/trunk/tests/include/21.strings.h Tue Jun  6 18:45:17 2006
@@ -47,6 +47,16 @@
     // identifiers for the Allocator template argument
     enum AllocId { DefaultAlloc, UserAlloc };
 
+    // identifiers for the Iterator template argument
+    // used with meber templates
+    enum IteratorId {
+        None,
+        Input, Forward, Bidir, Random,
+        Pointer, ConstPointer,
+        Iterator, ConstIterator,
+        ReverseIterator, ConstReverseIterator
+    };
+
     // identifies a set of overloaded member or non-member
     // string functions
     enum FuncId {
@@ -582,16 +592,19 @@
     }
 };
 
+/**************************************************************************/
 
 static const _RWSTD_SIZE_T
 NPOS = _RWSTD_SIZE_MAX;
 
+/**************************************************************************/
 
 struct StringFunc
 {
     StringIds::CharId     char_id_;
     StringIds::TraitsId   traits_id_;
     StringIds::AllocId    alloc_id_;
+    StringIds::IteratorId iter_id_;
     StringIds::OverloadId which_;
 };
 
@@ -824,13 +837,13 @@
 
 #define DEFINE_STRING_TEST_DISPATCH(fname)                      \
     static void                                                 \
-    fname (const StringFunc     &fun,                           \
+    fname (const StringFunc     &func,                          \
            const StringTestCase &tcase) {                       \
-        if (StringIds::DefaultAlloc == fun.alloc_id_) {         \
-            TEST_DISPATCH (std::allocator, fname, fun, tcase);  \
+        if (StringIds::DefaultAlloc == func.alloc_id_) {        \
+            TEST_DISPATCH (std::allocator, fname, func, tcase); \
         }                                                       \
-        else if (StringIds::UserAlloc == fun.alloc_id_) {       \
-            TEST_DISPATCH (UserAlloc, fname, fun, tcase);       \
+        else if (StringIds::UserAlloc == func.alloc_id_) {      \
+            TEST_DISPATCH (UserAlloc, fname, func, tcase);      \
         }                                                       \
         else                                                    \
             RW_ASSERT (!"logic error: bad allocator");          \

Modified: incubator/stdcxx/trunk/tests/src/21.strings.cpp
URL: http://svn.apache.org/viewvc/incubator/stdcxx/trunk/tests/src/21.strings.cpp?rev=412249&r1=412248&r2=412249&view=diff
==============================================================================
--- incubator/stdcxx/trunk/tests/src/21.strings.cpp (original)
+++ incubator/stdcxx/trunk/tests/src/21.strings.cpp Tue Jun  6 18:45:17 2006
@@ -35,7 +35,6 @@
 
 #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()
@@ -69,6 +68,18 @@
     "allocator", "UserAlloc"
 };
 
+
+static const char* const
+_rw_iter_names[] = {
+    "",
+    "InputIterator", "ForwardIterator", "BidirectionalIterator",
+    "RandomAccessIterator",
+    "pointer", "const_pointer",
+    "iterator", "const_iterator",
+    "reverse_iterator", "const_reverse_iterator"
+};
+
+
 // order of elements depends on the values of StringIds::FuncId
 static const char* const
 _rw_func_names[] = {
@@ -99,13 +110,16 @@
 _rw_string_test_count;
 
 static int
-_rw_opt_char_types [3];
+_rw_opt_char_types [sizeof _rw_char_names / sizeof *_rw_char_names];
 
 static int
-_rw_opt_traits_types [2];
+_rw_opt_traits_types [sizeof _rw_traits_names / sizeof *_rw_traits_names];
 
 static int
-_rw_opt_alloc_types [2];
+_rw_opt_alloc_types [sizeof _rw_alloc_names / sizeof *_rw_alloc_names];
+
+static int
+_rw_opt_iter_types [sizeof _rw_iter_names / sizeof *_rw_iter_names];
 
 static int
 _rw_opt_no_exceptions;
@@ -252,8 +266,15 @@
         }
     }
 
-    rw_asnprintf (pbuf, pbufsize, "%{+}%{?}%s%{?}_const%{;}%{:}(%{;}",
-                  0 == func, funcname, is_const_member);
+    // iterator name for member templates, empty string for other functions
+    const char* const iname = func ? _rw_iter_names [func->iter_id_] : "";
+
+    rw_asnprintf (pbuf, pbufsize,
+                  "%{+}%{?}%s%{?}_const%{;}%{:}%{?}<%s>%{;}(%{;}",
+                  0 == func, funcname, is_const_member, 0 != *iname, iname);
+
+    char iname_buf [80];
+    *iname_buf = '\0';
 
     // iterate through the map of argument types one field at a time
     // determining and formatting the type of each argument until
@@ -277,7 +298,15 @@
             case Ids::arg_cref:  tname = "const_reference"; break;
             case Ids::arg_iter:  tname = "iterator"; break;
             case Ids::arg_citer: tname = "const_iterator"; break;
-            case Ids::arg_range: tname = "InputIterator, InputIterator"; break;
+            case Ids::arg_range:
+                if ('\0' == *iname_buf) {
+                    strcpy (iname_buf, iname);
+                    strcat (iname_buf, ", ");
+                    strcat (iname_buf, iname);
+                }
+                tname = iname_buf;
+                break;
+
             case Ids::arg_alloc: tname = "const allocator_type&"; break;
             case Ids::arg_cstr:
                 pfx   = "const ";
@@ -330,18 +359,27 @@
 
 /**************************************************************************/
 
-static bool
-_rw_uses_alloc (StringIds::OverloadId which)
+// returns the zero-based index of the argument type specified
+// by arg in the function signature given by which
+static int
+_rw_argno (StringIds::OverloadId which, int arg)
 {
     // get the bitmap describing the function's argument types
     int argmap = (which & ~StringIds::bit_member) >> StringIds::fid_bits;
 
-    for (; argmap; argmap >>= StringIds::arg_bits) {
-        if ((argmap & StringIds::arg_alloc) == StringIds::arg_alloc)
-            return true;
+    int argno = 0;
+
+    // iterate over argument types looking for the first one
+    // that equals arg
+    for (; argmap; argmap >>= StringIds::arg_bits, ++argno) {
+        if ((argmap & StringIds::arg_mask) == arg) {
+            return argno;
+        }
     }
 
-    return false;
+    // return -1 when the function doesn't take an argument
+    // of the specified type
+    return -1;
 }
 
 /**************************************************************************/
@@ -368,14 +406,13 @@
         // set the {charT}, {Traits}, and {Allocator} environment
         // variables to the name of the character type and the
         // Traits and Allocator specializations
-        rw_putenv ("charT=");
-        rw_fprintf (0, "%{$charT:=*}", _rw_char_names [func.char_id_]);
+        rw_fprintf (0, "%{$charT!:*}", _rw_char_names [func.char_id_]);
 
-        rw_putenv ("Traits=");
-        rw_fprintf (0, "%{$Traits:=*}", _rw_traits_names [func.traits_id_]);
+        rw_fprintf (0, "%{$Traits!:*}", _rw_traits_names [func.traits_id_]);
 
-        rw_putenv ("Allocator=");
-        rw_fprintf (0, "%{$Allocator:=*}", _rw_alloc_names [func.alloc_id_]);
+        rw_fprintf (0, "%{$Allocator!:*}", _rw_alloc_names [func.alloc_id_]);
+
+        rw_fprintf (0, "%{$Iterator!:*}", _rw_iter_names [func.iter_id_]);
 
         // set the {CLASS}, {FUNC}, and {FUNCSIG} environment variables
         // to the name of the specialization of the template, the name
@@ -404,8 +441,7 @@
 
         // set the {CLASS} variable to the name of the specialization
         // of basic_string
-        rw_putenv ("CLASS=");
-        rw_fprintf (0, "%{$CLASS:=*}", buf);
+        rw_fprintf (0, "%{$CLASS!:*}", buf);
 
         // determine the string function name
         const size_t funcinx = func.which_ & StringIds::fid_mask;
@@ -431,14 +467,12 @@
         rw_asnprintf (&buf, &bufsize, "%{?}std::%{;}%s",
                       !is_member, funcname);
 
-        rw_putenv ("FUNC=");
-        rw_fprintf (0, "%{$FUNC:=*}", buf);
+        rw_fprintf (0, "%{$FUNC!:*}", buf);
 
         // append the function signature
         _rw_sigcat (&buf, &bufsize, &func);
 
-        rw_putenv ("FUNCSIG=");
-        rw_fprintf (0, "%{$FUNCSIG:=*}", buf);
+        rw_fprintf (0, "%{$FUNCSIG!:*}", buf);
         free (buf);
 
         return;
@@ -496,7 +530,8 @@
     const size_t range1_end = pcase->off + pcase->size;
     const size_t range2_end = pcase->off2 + pcase->size2;
 
-    const bool use_alloc = _rw_uses_alloc (func.which_);
+    // determine whether the function takes an allocator_type argument
+    const bool use_alloc = 0 < _rw_argno (func.which_, StringIds::arg_alloc);
 
     // format and append string function arguments abbreviating complex
     // expressions as much as possible to make them easy to understand
@@ -940,8 +975,7 @@
         RW_ASSERT (!"test logic error: unknown overload");
     }
 
-    rw_putenv ("FUNCALL=");
-    rw_fprintf (0, "%{$FUNCALL:=*}", buf);
+    rw_fprintf (0, "%{$FUNCALL!:*}", buf);
     free (buf);
 
     if (str != str_buf)
@@ -1043,6 +1077,7 @@
 
 /**************************************************************************/
 
+// exercise a single test case for the given function
 static void
 _rw_test_case (const StringFunc     &func,
                const StringTestCase &tcase,
@@ -1110,6 +1145,54 @@
 
 /**************************************************************************/
 
+static StringTestFunc*
+_rw_test_callback;
+
+
+static VoidFunc* const*
+_rw_func_array;
+
+
+// exercise all test cases defined for the given function
+static void
+_rw_run_cases (const StringFunc &func,
+               const StringTest &test)
+{
+    // set the {CLASS}, {FUNC}, and {FUNCSIG} environment
+    // variable to the name of the basic_string specializaton
+    // and the string function being exercised
+    _rw_setvars (func);
+
+    // determine whether the function is a member function
+    const bool is_member = 0 != (StringIds::bit_member & test.which);
+
+    // compute the function overload's 0-based index
+    const size_t siginx = _rw_get_func_inx (test.which);
+
+    // check if tests of the function overload
+    // have been disabled
+    if (0 == rw_note (0 <= _rw_opt_func [siginx], _rw_this_file, __LINE__,
+                      "%{?}%{$CLASS}::%{;}%{$FUNCSIG} tests disabled",
+                      is_member))
+        return;
+
+    rw_info (0, 0, 0, "%{?}%{$CLASS}::%{;}%{$FUNCSIG}", is_member);
+
+    const size_t case_count = test.case_count;
+
+    // iterate over all test cases for this function
+    // overload invoking the test case handler for each
+    // in turn
+    for (size_t n = 0; n != case_count; ++n) {
+
+        const StringTestCase& tcase = test.cases [n];
+
+        _rw_test_case (func, tcase,  _rw_test_callback, _rw_func_array);
+    }
+}
+
+/**************************************************************************/
+
 static void
 _rw_toggle_options (int *opts, size_t count)
 {
@@ -1127,12 +1210,6 @@
     }
 }
 
-static StringTestFunc*
-_rw_test_callback;
-
-static VoidFunc* const*
-_rw_func_array;
-
 
 static int
 _rw_run_test (int, char*[])
@@ -1178,15 +1255,26 @@
         StringIds::DefaultAlloc, StringIds::UserAlloc
     };
 
+    static const StringIds::IteratorId iter_types[] = {
+        StringIds::None,
+        StringIds::Input, StringIds::Forward,
+        StringIds::Bidir, StringIds::Random,
+        StringIds::Pointer, StringIds::ConstPointer,
+        StringIds::Iterator, StringIds::ConstIterator,
+        StringIds::ReverseIterator, StringIds::ConstReverseIterator
+    };
+
     const size_t n_char_types   = sizeof char_types / sizeof *char_types;
     const size_t n_traits_types = sizeof traits_types / sizeof *traits_types;
     const size_t n_alloc_types  = sizeof alloc_types / sizeof *alloc_types;
+    const size_t n_iter_types   = sizeof iter_types / sizeof *iter_types;
 
     // see if any option controlling the basic_string template arguments
     // explicitly enabled and if so disable all those that haven't been
     _rw_toggle_options (_rw_opt_char_types, n_char_types);
     _rw_toggle_options (_rw_opt_traits_types, n_traits_types);
     _rw_toggle_options (_rw_opt_alloc_types, n_alloc_types);
+    _rw_toggle_options (_rw_opt_iter_types, n_iter_types);
 
     // exercise different charT specializations last
     for (size_t i = 0; i != n_char_types; ++i) {
@@ -1227,53 +1315,46 @@
                     continue;
                 }
 
-                for (size_t m = 0; m != _rw_string_test_count; ++m) {
+                for (size_t l = 0; l != n_iter_types; ++l) {
 
-                    const StringTest& test = _rw_string_tests [m];
-
-                    // create an object uniquely identifying the overload
-                    // of the string function exercised by the set of test
-                    // cases defined to exercise it
-                    const StringFunc func = {
-                        char_types [i],
-                        traits_types [j],
-                        alloc_types [k],
-                        test.which
-                    };
-
-                    // set the {CLASS}, {FUNC}, and {FUNCSIG} environment
-                    // variable to the name of the basic_string specializaton
-                    // and the string function being exercised
-                    _rw_setvars (func);
-
-                    // determine whether the function is a member function
-                    const bool is_member =
-                        0 != (StringIds::bit_member & test.which);
-
-                    // compute the function overload's 0-based index
-                    const size_t siginx = _rw_get_func_inx (test.which);
-
-                    // check if tests of the function overload
-                    // have been disabled
-                    if (0 == rw_note (0 <= _rw_opt_func [siginx],
-                                      _rw_this_file, __LINE__,
-                                      "%{?}%{$CLASS}::%{;}%{$FUNCSIG} "
-                                      "tests disabled", is_member))
+                    if (l && _rw_opt_iter_types [l - 1] < 0) {
+                        // issue only the first note
+                        rw_note (-1 > _rw_opt_iter_types [l]--,
+                                 _rw_this_file, __LINE__,
+                                 "%s tests disabled", _rw_iter_names [l]);
                         continue;
+                    }
 
-                    rw_info (0, 0, 0, "%{?}%{$CLASS}::%{;}%{$FUNCSIG}",
-                             is_member);
-
-                    const size_t case_count = test.case_count;
+                    for (size_t m = 0; m != _rw_string_test_count; ++m) {
 
-                    // iterate over all test cases for this function overload
-                    // invoking the test case handler for each in turn
-                    for (size_t n = 0; n != case_count; ++n) {
+                        const StringTest& test = _rw_string_tests [m];
 
-                        const StringTestCase& tcase = test.cases [n];
+                        // determine whether the function is a template
+                        if (-1 < _rw_argno (test.which, StringIds::arg_range)) {
+                            if (StringIds::None == iter_types [l]) {
+                                // skip a non-sensical template specialization
+                                break;
+                            }
+                        }
+                        else if (StringIds::None != iter_types [l]) {
+                            // avoid repeatedly exercising a non-template
+                            // function
+                            continue;
+                        }
+
+                        // create an object uniquely identifying the overload
+                        // of the string function exercised by the set of test
+                        // cases defined to exercise it
+                        const StringFunc func = {
+                            char_types [i],
+                            traits_types [j],
+                            alloc_types [k],
+                            iter_types [l],
+                            test.which
+                        };
 
-                        _rw_test_case (func, tcase,
-                                       _rw_test_callback, _rw_func_array);
+                        // exercise all test cases defined for the function
+                        _rw_run_cases (func, test);
                     }
                 }
             }
@@ -1285,6 +1366,17 @@
 
 /**************************************************************************/
 
+// add a bunch of toggle-type command line options based on the names array
+static void
+_rw_add_toggles (char **pbuf, size_t *pbufsize,
+                 const char* const names[], size_t count)
+{
+    for (size_t i = 0; i != count; ++i) {
+        rw_asnprintf (pbuf, pbufsize, "%{+}|-%s~ ", names [i]);
+    }
+}
+
+
 static int
 _rw_run_test  (int               argc,
                char             *argv [],
@@ -1308,19 +1400,22 @@
     size_t  optbufsize = 0;
 
     rw_asnprintf (&optbuf, &optbufsize,
-                  "|-char~ "
-                  "|-wchar_t~ "
-                  "|-UserChar~ "
-                  "|-char_traits~ "
-                  "|-UserTraits~ "
-                  "|-allocator~ "
-                  "|-UserAlloc~ "
-
                   "|-no-exceptions# "
                   "|-no-exception-safety# "
-
                   "|-self-ref~ ");
 
+    const size_t n_chars  = sizeof _rw_char_names / sizeof *_rw_char_names;
+    const size_t n_traits = sizeof _rw_traits_names / sizeof *_rw_traits_names;
+    const size_t n_allocs = sizeof _rw_alloc_names / sizeof *_rw_alloc_names;
+    const size_t n_iters  = sizeof _rw_iter_names / sizeof *_rw_iter_names;
+
+    // see if any option has been explicitly enabled and if so,
+    // uncodnitionally disable all those that have not been
+    _rw_add_toggles (&optbuf, &optbufsize, _rw_char_names, n_chars);
+    _rw_add_toggles (&optbuf, &optbufsize, _rw_traits_names, n_traits);
+    _rw_add_toggles (&optbuf, &optbufsize, _rw_alloc_names, n_allocs);
+    _rw_add_toggles (&optbuf, &optbufsize, _rw_iter_names + 1, n_iters - 1);
+
     for (size_t i = 0; i != test_count; ++i) {
 
         // for each function append a command line option specification
@@ -1340,21 +1435,46 @@
                  _rw_run_test,   // test callback
                  optbuf,         // option specification
 
+                 // handlers controlling exceptions
+                 &_rw_opt_no_exceptions,
+                 &_rw_opt_no_exception_safety,
+
+                 // handler controlling self-referential modifiers
+                 &_rw_opt_self_ref,
+
                  // handlers controlling specializations of the template
+                 // ...on the charT template parameter
                  _rw_opt_char_types + 0,
                  _rw_opt_char_types + 1,
                  _rw_opt_char_types + 2,
+
+                 // ...on the Traits template parameter
                  _rw_opt_traits_types + 0,
                  _rw_opt_traits_types + 1,
+
+                 // ...on the Allocator template parameter
                  _rw_opt_alloc_types + 0,
                  _rw_opt_alloc_types + 1,
 
-                 // handlers controlling exceptions
-                 &_rw_opt_no_exceptions,
-                 &_rw_opt_no_exception_safety,
+                 // FIXME: add handlers (and options) only for tests
+                 // that exercise member templates
 
-                 // handler controlling self-referential modifiers
-                 &_rw_opt_self_ref,
+                 // handlers controlling specializations of the member
+                 // template (if this is one) on the InputIterator
+                 // template parameter
+                 _rw_opt_iter_types + 0,
+                 _rw_opt_iter_types + 1,
+                 _rw_opt_iter_types + 2,
+                 _rw_opt_iter_types + 3,
+                 _rw_opt_iter_types + 4,
+                 _rw_opt_iter_types + 5,
+                 _rw_opt_iter_types + 6,
+                 _rw_opt_iter_types + 7,
+                 _rw_opt_iter_types + 8,
+                 _rw_opt_iter_types + 9,
+
+                 // FIXME: install exactly as many handlers (and options)
+                 // as there are distinct functions being exercised
 
                  // handlers for up to 32 overloads
                  _rw_opt_func +  0,



Re: svn commit: r412249 - in /incubator/stdcxx/trunk/tests: include/21.strings.h src/21.strings.cpp

Posted by Martin Sebor <se...@roguewave.com>.
sebor@apache.org wrote:
> Author: sebor
> Date: Tue Jun  6 18:45:17 2006
> New Revision: 412249

Anton, as heads up, I believe this change will have the effect
of running all the tests that exercise the range member templates
in a loop iterating over all the IteratorIds hardwired into the
driver. We'll need to implement the same kind of dispatch as I
did in 21.string.replace.cpp to prevent it. I have run out of
time today but I'll do it tomorrow unless you beat me to it.

As usual, comments, suggestions, etc. are welcome :)

Martin

> 
> URL: http://svn.apache.org/viewvc?rev=412249&view=rev
> Log:
> 2006-06-06  Martin Sebor  <se...@roguewave.com>
> 
> 	* 21.strings.h (IteratorId): New member type of StringIds.
> 	(StringFunc): Added a new data member.
> 	* 21.strings.cpp (_rw_iter_names): New.
> 	(_rw_opt_char_types, ...): Sized based on the corresponding
> 	_rw_xxx_names arrays.
> 	(_rw_sigcat): Used _rw_iter_names in function signatures and
> 	command line option names.
> 	(_rw_argno): Renamed from _rw_uses_alloc and generalized.
> 	(_rw_setvars): Simplified the setting of environment variables
> 	by using the %{paramater!:word} extended directive.
> 	(_rw_run_cases): New helper.
> 	(_rw_run_test): Iterated over all IteratorId's and called
> 	_rw_run_cases.
> 	(_rw_add_toggles): New helper.
> 	(_rw_run_test): Called _rw_add_toggles, installed option
> 	handlers for iterator specializations of member templates.
> 
> Modified:
>     incubator/stdcxx/trunk/tests/include/21.strings.h
>     incubator/stdcxx/trunk/tests/src/21.strings.cpp