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/04/24 03:58:17 UTC

svn commit: r396375 [2/2] - in /incubator/stdcxx/trunk/tests: include/21.strings.h src/21.strings.cpp strings/21.string.append.cpp strings/21.string.assign.cpp strings/21.string.replace.cpp

Modified: incubator/stdcxx/trunk/tests/strings/21.string.replace.cpp
URL: http://svn.apache.org/viewcvs/incubator/stdcxx/trunk/tests/strings/21.string.replace.cpp?rev=396375&r1=396374&r2=396375&view=diff
==============================================================================
--- incubator/stdcxx/trunk/tests/strings/21.string.replace.cpp (original)
+++ incubator/stdcxx/trunk/tests/strings/21.string.replace.cpp Sun Apr 23 18:58:16 2006
@@ -44,37 +44,12 @@
 #  include <rw_new.h>
 #endif   // _RWSTD_NO_REPLACEABLE_NEW_DELETE
 
-#define ReplaceOverload   StringMembers::MemberFunction
+#define ReplaceOverload   StringMembers::OverloadId
 #define Replace(which)    StringMembers::replace_ ## which
-#define Disabled(which)   StringMembers::opt_memfun_disabled [which]
 
 typedef StringMembers::TestCase TestCase;
 typedef StringMembers::Test     Test;
-
-/**************************************************************************/
-
-const char method_name[] = "replace";
-
-/**************************************************************************/
-
-struct MemFun
-{
-    typedef StringMembers::charT  charT;
-    typedef StringMembers::Traits Traits;
-
-    MemFun (charT cid, const char *cname,
-          Traits tid, const char *tname)
-        : cid_ (cid), tid_ (tid),
-          cname_ (cname), tname_ (tname), aname_ ("allocator"),
-          fname_ ("replace") { /* empty */ }
-
-    charT       cid_;     // character type id (char or wchar_t)
-    Traits      tid_;     // traits type id (default or user-defined)
-    const char *cname_;   // character type name
-    const char *tname_;   // traits name
-    const char *aname_;   // allocator name
-    const char *fname_;   // function name
-};
+typedef StringMembers::Function MemFun;
 
 /**************************************************************************/
 
@@ -93,14 +68,16 @@
 /**************************************************************************/
 
 // used to exercise
-// replace (size_type pos1, size_type n1, const charT* s)
+// replace (size_type, size_type, const value_type*)
 static const TestCase
-off_size_ptr_test_cases [] = {
+size_size_ptr_test_cases [] = {
 
 #undef TEST
-#define TEST(str, off, size, arg, res, bthrow)                               \
-    { Replace (off_size_ptr), __LINE__, off, size, -1, -1, -1,               \
-      str, sizeof str - 1, arg, sizeof arg - 1, res, sizeof res - 1, bthrow }
+#define TEST(str, off, size, arg, res, bthrow) {                \
+        __LINE__, off, size, -1, -1, -1,                        \
+        str, sizeof str - 1,                                    \
+        arg, sizeof arg - 1, res, sizeof res - 1, bthrow        \
+    }
 
     //    +------------------------------------------ controlled sequence
     //    |            +----------------------------- replace() pos1 argument
@@ -184,14 +161,16 @@
 /**************************************************************************/
 
 // used to exercise
-// replace (Iterator i1, Iterator i2, const charT* s)
+// replace (iterator, iterator, const value_type*)
 static const TestCase
-ptr_test_cases [] = {
+iter_iter_ptr_test_cases [] = {
 
 #undef TEST
-#define TEST(str, off, size, arg, res, bthrow)                               \
-    { Replace (ptr), __LINE__, off, size, -1, -1, -1,                        \
-      str, sizeof str - 1, arg, sizeof arg - 1, res, sizeof res - 1, bthrow }
+#define TEST(str, off, size, arg, res, bthrow) {                \
+        __LINE__, off, size, -1, -1, -1,                        \
+        str, sizeof str - 1,                                    \
+        arg, sizeof arg - 1, res, sizeof res - 1, bthrow        \
+    }
 
     //    +------------------------------------------ controlled sequence
     //    |            +----------------------------- replace() pos1 argument
@@ -275,14 +254,16 @@
 /**************************************************************************/
 
 // used to exercise
-// replace (size_type pos1, size_type n1, basic_string& s)
+// replace (size_type, size_type, const basic_string&)
 static const TestCase
-off_size_str_test_cases [] = {
+size_size_str_test_cases [] = {
 
 #undef TEST
-#define TEST(str, off, size, arg, res, bthrow)                               \
-    { Replace (off_size_str), __LINE__, off, size, -1, -1, -1,               \
-      str, sizeof str - 1, arg, sizeof arg - 1, res, sizeof res - 1, bthrow }
+#define TEST(str, off, size, arg, res, bthrow) {                \
+        __LINE__, off, size, -1, -1, -1,                        \
+        str, sizeof str - 1,                                    \
+        arg, sizeof arg - 1, res, sizeof res - 1, bthrow        \
+    }
 
     //    +------------------------------------------ controlled sequence
     //    |            +----------------------------- replace() pos1 argument
@@ -372,14 +353,16 @@
 /**************************************************************************/
 
 // used to exercise
-// replace (Iterator i1, Iterator i2, basic_string& s)
+// replace (iterator, iterator, const basic_string&)
 static const TestCase
-str_test_cases [] = {
+iter_iter_str_test_cases [] = {
 
 #undef TEST
-#define TEST(s, off, size, arg, res, bthrow)                                 \
-    { Replace (str), __LINE__, off, size, -1, -1, -1,                        \
-      s, sizeof s - 1, arg, sizeof arg - 1, res, sizeof res - 1, bthrow }
+#define TEST(s, off, size, arg, res, bthrow) {                  \
+        __LINE__, off, size, -1, -1, -1,                        \
+        s, sizeof s - 1,                                        \
+        arg, sizeof arg - 1, res, sizeof res - 1, bthrow        \
+    }
 
     //    +------------------------------------------ controlled sequence
     //    |            +----------------------------- replace() pos1 argument
@@ -469,14 +452,16 @@
 /**************************************************************************/
 
 // used to exercise
-// replace (size_type pos1, size_type n1, const charT* s, size_type n2)
+// replace (size_type, size_type, const value_type*, size_type)
 static const TestCase
-off_size_ptr_size_test_cases [] = {
+size_size_ptr_size_test_cases [] = {
 
 #undef TEST
-#define TEST(str, off, size, arg, count, res, bthrow)                        \
-    { Replace (off_size_ptr_size), __LINE__, off, size, -1, count, -1,       \
-      str, sizeof str - 1, arg, sizeof arg - 1, res, sizeof res - 1, bthrow }
+#define TEST(str, off, size, arg, count, res, bthrow) {         \
+        __LINE__, off, size, -1, count, -1,                     \
+        str, sizeof str - 1,                                    \
+        arg, sizeof arg - 1, res, sizeof res - 1, bthrow        \
+    }
 
     //    +------------------------------------------ controlled sequence
     //    |            +----------------------------- replace() pos1 argument
@@ -561,14 +546,16 @@
 /**************************************************************************/
 
 // used to exercise
-// replace (Iterator i1, Iterator i2, const charT* s, size_type n2)
+// replace (iterator, iterator, const value_type*, size_type)
 static const TestCase
-ptr_size_test_cases [] = {
+iter_iter_ptr_size_test_cases [] = {
 
 #undef TEST
-#define TEST(str, off, size, arg, count, res, bthrow)                        \
-    { Replace (ptr_size), __LINE__, off, size, -1, count, -1,                \
-      str, sizeof str - 1, arg, sizeof arg - 1, res, sizeof res - 1, bthrow }
+#define TEST(str, off, size, arg, count, res, bthrow) {         \
+        __LINE__, off, size, -1, count, -1,                     \
+        str, sizeof str - 1,                                    \
+        arg, sizeof arg - 1, res, sizeof res - 1, bthrow        \
+    }
 
     //    +------------------------------------------ controlled sequence
     //    |            +----------------------------- replace() pos1 argument
@@ -652,15 +639,16 @@
 /**************************************************************************/
 
 // used to exercise
-// replace (size_type pos1, size_type n1, basic_string& s,
-//          size_type pos2, size_type n2)
+// replace (size_type, size_type, const basic_string&, size_type, size_type)
 static const TestCase
-off_size_str_off_size_test_cases [] = {
+size_size_str_size_size_test_cases [] = {
 
 #undef TEST
-#define TEST(str, off, size, arg, off2, size2, res, bthrow)                  \
-    { Replace (off_size_str_off_size), __LINE__, off, size, off2, size2, -1, \
-      str, sizeof str - 1, arg, sizeof arg - 1, res, sizeof res - 1, bthrow }
+#define TEST(str, off, size, arg, off2, size2, res, bthrow) {   \
+        __LINE__, off, size, off2, size2, -1,                   \
+        str, sizeof str - 1,                                    \
+        arg, sizeof arg - 1, res, sizeof res - 1, bthrow        \
+    }
 
     //    +------------------------------------------ controlled sequence
     //    |            +----------------------------- replace() pos argument
@@ -769,14 +757,16 @@
 /**************************************************************************/
 
 // used to exercise
-// replace (iterator i1, Iterator i2, InputIterator j1, InputIterator j2)
+// replace (iterator, Iterator, InputIterator, InputIterator)
 static const TestCase
-range_test_cases [] = {
+iter_iter_range_test_cases [] = {
 
 #undef TEST
-#define TEST(str, off, size, arg, off2, size2, res, bthrow)                  \
-    { Replace (range), __LINE__, off, size, off2, size2, -1,                 \
-      str, sizeof str - 1, arg, sizeof arg - 1, res, sizeof res - 1, bthrow }
+#define TEST(str, off, size, arg, off2, size2, res, bthrow) {   \
+        __LINE__, off, size, off2, size2, -1,                   \
+        str, sizeof str - 1,                                    \
+        arg, sizeof arg - 1, res, sizeof res - 1, bthrow        \
+    }
 
     //    +------------------------------------------ controlled sequence
     //    |            +----------------------------- replace() pos argument
@@ -884,14 +874,15 @@
 /**************************************************************************/
 
 // used to exercise
-// replace (size_type pos1, size_type n1, charT c, size_type n2)
+// replace (size_type, size_type, value_type, size_type)
 static const TestCase
-off_size_size_val_test_cases [] = {
+size_size_size_val_test_cases [] = {
 
 #undef TEST
-#define TEST(str, off, size, count, val, res, bthrow)                     \
-    { Replace (off_size_size_val), __LINE__, off, size, -1, count, val,   \
-      str, sizeof str - 1, 0, 0, res, sizeof res - 1, bthrow }
+#define TEST(str, off, size, count, val, res, bthrow) {         \
+        __LINE__, off, size, -1, count, val,                    \
+        str, sizeof str - 1, 0, 0, res, sizeof res - 1, bthrow  \
+    }
 
     //    +------------------------------------------ controlled sequence
     //    |            +----------------------------- replace() pos1 argument
@@ -976,14 +967,16 @@
 /**************************************************************************/
 
 // used to exercise
-// replace (iterator i1, Iterator i2, charT c, size_type n2)
+// replace (iterator, iterator, size_type, value_type)
 static const TestCase
-size_val_test_cases [] = {
+iter_iter_size_val_test_cases [] = {
 
 #undef TEST
-#define TEST(str, off, size, count, val, res, bthrow)                     \
-    { Replace (size_val), __LINE__, off, size, -1, count, val,            \
-      str, sizeof str - 1, 0, 0, res, sizeof res - 1, bthrow }
+#define TEST(str, off, size, count, val, res, bthrow) { \
+        __LINE__, off, size, -1, count, val,            \
+        str, sizeof str - 1,                            \
+        0, 0, res, sizeof res - 1, bthrow               \
+    }
 
     //    +------------------------------------------ controlled sequence
     //    |            +----------------------------- replace() pos1 argument
@@ -1068,64 +1061,38 @@
 
 /**************************************************************************/
 
-static const StringMembers::Test
-tests [] = {
-
-#undef TEST
-#define TEST(tag, sig) {                                         \
-        tag ## _test_cases,                                      \
-        sizeof tag ## _test_cases / sizeof *tag ## _test_cases,  \
-        "replace " sig                                           \
-    }
-
-    TEST (off_size_ptr, "(size_type, size_type, const value_type*)"),
-    TEST (off_size_str, "(size_type, size_type, basic_string&)"),
-    TEST (off_size_ptr_size,
-          "(size_type, size_type, const value_type*, size_type)"),
-    TEST (off_size_str_off_size,
-          "size_type, size_type, basic_string&, size_type, size_type)"),
-    TEST (off_size_size_val, "(size_type, size_type, size_type, value_type)"),
-    TEST (ptr, "(iterator, iterator, const value_type*)"),
-    TEST (str, "(iterator, iterator, basic_string&)"),
-    TEST (ptr_size, "(iterator, iterator, const value_type*, size_type)"),
-    TEST (size_val, "(iterator, iterator, size_type, value_type)"),
-    TEST (range, "(iterator, iterator, InputIterator, InputIterator)")
-};
-
-/**************************************************************************/
-
 template <class charT, class Traits>
 void test_exceptions (charT, Traits*,
-                      const TestCase &cs,
-                      const char     *funcall)
+                      ReplaceOverload which,
+                      const TestCase &tcase)
 {
-    typedef std::basic_string <charT, Traits,
-                               std::allocator<charT> > TestString;
-    typedef typename TestString::iterator StringIter;
-    typedef typename TestString::const_iterator ConstStringIter;
+    typedef std::allocator<charT>                        Allocator;
+    typedef std::basic_string <charT, Traits, Allocator> TestString;
+    typedef typename TestString::iterator                StringIter;
+    typedef typename TestString::const_iterator          ConstStringIter;
 
-    const bool use_iters = (Replace (ptr) <= cs.which);
+    const bool use_iters = Replace (iter_iter_ptr) <= which;
 
     static charT wstr [LLEN];
     static charT warg [LLEN];
 
-    rw_widen (wstr, cs.str, cs.str_len);
-    rw_widen (warg, cs.arg, cs.arg_len);
+    rw_widen (wstr, tcase.str, tcase.str_len);
+    rw_widen (warg, tcase.arg, tcase.arg_len);
 
-    /* const */ TestString s_str (wstr, cs.str_len);
-    const       TestString s_arg (warg, cs.arg_len);
+    /* const */ TestString s_str (wstr, tcase.str_len);
+    const       TestString s_arg (warg, tcase.arg_len);
 
-    const int first = use_iters ? cs.off : cs.str_len + 1;
-    const int last  = use_iters ? cs.off + cs.size : cs.str_len + 1;
+    const int first = use_iters ? tcase.off : tcase.str_len + 1;
+    const int last  = use_iters ? tcase.off + tcase.size : tcase.str_len + 1;
 
     const StringIter it_first (std::size_t (first) >= s_str.size () ?
                                s_str.end () : s_str.begin () + first);
     const StringIter it_last  (std::size_t (last) >= s_str.size () ?
                                s_str.end () : s_str.begin () + last);
 
-    const charT* const arg_ptr = cs.arg ? warg : s_str.c_str ();
-    const TestString&  arg_str = cs.arg ? s_arg : s_str;
-    const charT        arg_val = make_char (char (cs.val), (charT*)0);
+    const charT* const arg_ptr = tcase.arg ? warg : s_str.c_str ();
+    const TestString&  arg_str = tcase.arg ? s_arg : s_str;
+    const charT        arg_val = make_char (char (tcase.val), (charT*)0);
 
     std::size_t throw_after = 0;
 
@@ -1153,34 +1120,35 @@
 #endif   // _RWSTD_NO_EXCEPTIONS
 
         _TRY {
-            if (Replace (off_size_ptr) == cs.which)
-                s_str.replace (cs.off, cs.size, arg_ptr);
+            if (Replace (size_size_ptr) == which)
+                s_str.replace (tcase.off, tcase.size, arg_ptr);
 
-            else if (Replace (off_size_str) == cs.which)
-                s_str.replace (cs.off, cs.size, arg_str);
+            else if (Replace (size_size_str) == which)
+                s_str.replace (tcase.off, tcase.size, arg_str);
 
-            else if (Replace (off_size_ptr_size) == cs.which)
-                s_str.replace (cs.off, cs.size, arg_ptr, cs.size2);
+            else if (Replace (size_size_ptr_size) == which)
+                s_str.replace (tcase.off, tcase.size, arg_ptr, tcase.size2);
 
-            else if (Replace (off_size_str_off_size) == cs.which)
-                s_str.replace (cs.off, cs.size, arg_str, cs.off2, cs.size2);
+            else if (Replace (size_size_str_size_size) == which)
+                s_str.replace (tcase.off, tcase.size, arg_str,
+                               tcase.off2, tcase.size2);
 
-            else if (Replace (off_size_size_val) == cs.which)
-                s_str.replace (cs.off, cs.size, cs.size2, arg_val);
+            else if (Replace (size_size_size_val) == which)
+                s_str.replace (tcase.off, tcase.size, tcase.size2, arg_val);
 
-            else if (Replace (ptr) == cs.which)
+            else if (Replace (iter_iter_ptr) == which)
                 s_str.replace (it_first, it_last, arg_ptr);
 
-            else if (Replace (str) == cs.which)
+            else if (Replace (iter_iter_str) == which)
                 s_str.replace (it_first, it_last, arg_str);
 
-            else if (Replace (ptr_size) == cs.which)
-                s_str.replace (it_first, it_last, arg_ptr, cs.size2);
+            else if (Replace (iter_iter_ptr_size) == which)
+                s_str.replace (it_first, it_last, arg_ptr, tcase.size2);
 
-            else if (Replace (size_val) == cs.which)
-                s_str.replace (it_first, it_last, cs.size2, arg_val);
+            else if (Replace (iter_iter_size_val) == which)
+                s_str.replace (it_first, it_last, tcase.size2, arg_val);
 
-            else if (Replace (range) == cs.which)
+            else if (Replace (iter_iter_range) == which)
                 s_str.replace (it_first, it_last, s_arg.begin(), s_arg.end());
 
             break;
@@ -1192,21 +1160,21 @@
             // verify that an exception thrown during allocation
             // doesn't cause a change in the state of the vector
 
-            rw_assert (s_str.size () == size, 0, cs.line,
-                       "line %d: %s: size unexpectedly changed "
+            rw_assert (s_str.size () == size, 0, tcase.line,
+                       "line %d: %{$FUNCALL}: size unexpectedly changed "
                        "from %zu to %zu after an exception",
-                       __LINE__, funcall, size, s_str.size ());
+                       __LINE__, size, s_str.size ());
 
-            rw_assert (s_str.capacity () == capacity, 0, cs.line,
-                       "line %d: %s: capacity unexpectedly "
+            rw_assert (s_str.capacity () == capacity, 0, tcase.line,
+                       "line %d: %{$FUNCALL}: capacity unexpectedly "
                        "changed from %zu to %zu after an exception",
-                       __LINE__, funcall, capacity, s_str.capacity ());
+                       __LINE__, capacity, s_str.capacity ());
 
 
-            rw_assert (s_str.begin () == begin, 0, cs.line,
-                       "line %d: %s: begin() unexpectedly "
+            rw_assert (s_str.begin () == begin, 0, tcase.line,
+                       "line %d: %{$FUNCALL}: begin() unexpectedly "
                        "changed from after an exception by %d",
-                       __LINE__, funcall, s_str.begin () - begin);
+                       __LINE__, s_str.begin () - begin);
 
 
             // increment to allow this call to operator new to succeed
@@ -1225,9 +1193,9 @@
     // at least one exception is thrown
     rw_assert (   *pst->throw_at_calls_ [0] == std::size_t (-1)
                || throw_after,
-               0, cs.line,
-               "line %d: %s: failed to throw an expected exception",
-               __LINE__, funcall);
+               0, tcase.line,
+                  "line %d: %{$FUNCALL}: failed to throw an expected exception",
+               __LINE__);
 
 #  endif   // _RWSTD_NO_REPLACEABLE_NEW_DELETE
 #else   // if defined (_RWSTD_NO_EXCEPTIONS)
@@ -1248,33 +1216,32 @@
 /**************************************************************************/
 
 template <class charT, class Traits, class Iterator>
-void test_replace_range (const charT* wstr,
-                         const charT* warg,
+void test_replace_range (const charT*    wstr,
+                         const charT*    warg,
                          Traits*,
                          const Iterator &it,
-                         const TestCase &cs,
-                         const char     *funcall)
+                         const TestCase &tcase)
 {
     typedef std::allocator<charT>                        Allocator;
     typedef std::basic_string <charT, Traits, Allocator> String;
     typedef typename String::iterator                    StringIter;
 
     const char* const itname =
-        cs.arg ? type_name (it, (charT*)0) : "basic_string::iterator";
+        tcase.arg ? type_name (it, (charT*)0) : "basic_string::iterator";
 
-    /* const */ String s_str (wstr, cs.str_len);
-    const       String s_arg (warg, cs.arg_len);
+    /* const */ String s_str (wstr, tcase.str_len);
+    const       String s_arg (warg, tcase.arg_len);
 
-    std::size_t off_last   = cs.off + cs.size;
-    std::size_t off_first2 = cs.off2;
-    std::size_t off_last2  = cs.off2 + cs.size2;
+    std::size_t off_last   = tcase.off + tcase.size;
+    std::size_t off_first2 = tcase.off2;
+    std::size_t off_last2  = tcase.off2 + tcase.size2;
 
-    const StringIter it_first (std::size_t (cs.off) >= s_str.size () ?
-                               s_str.end () : s_str.begin () + cs.off);
+    const StringIter it_first (std::size_t (tcase.off) >= s_str.size () ?
+                               s_str.end () : s_str.begin () + tcase.off);
     const StringIter it_last  (std::size_t (off_last) >= s_str.size () ?
                                s_str.end () : s_str.begin () + off_last);
 
-    if (cs.arg) {
+    if (tcase.arg) {
         off_first2 = off_first2 > s_arg.size () ? s_arg.size () : off_first2;
         off_last2  = off_last2  > s_arg.size () ? s_arg.size () : off_last2;
 
@@ -1282,25 +1249,26 @@
         const charT* const warg_end = warg + off_last2;
 
         const Iterator first (warg_beg, warg_beg,        warg_end);
-        const Iterator last  (warg_end, warg + cs.off2,  warg_end);
+        const Iterator last  (warg_end, warg + tcase.off2,  warg_end);
 
         s_str.replace (it_first, it_last, first, last);
     }
     else {
-        const StringIter first (std::size_t (cs.off2) >= s_str.size () ?
-                                s_str.end () : s_str.begin () + cs.size2);
+        const StringIter first (std::size_t (tcase.off2) >= s_str.size () ?
+                                s_str.end () : s_str.begin () + tcase.size2);
         const StringIter last (off_last2 > s_str.size () ?
                                s_str.end () : s_str.begin () + off_last2);
 
         s_str.replace (it_first, it_last, first, last);
     }
 
-    const std::size_t match = rw_match (cs.res, s_str.c_str(), cs.res_len);
+    const std::size_t match =
+        rw_match (tcase.res, s_str.c_str(), tcase.res_len);
 
-    rw_assert (match == cs.res_len, 0, cs.line,
-               "line %d. %s expected %{#*s}, got %{/*.*Gs}, "
+    rw_assert (match == tcase.res_len, 0, tcase.line,
+               "line %d. %{$FUNCALL} expected %{#*s}, got %{/*.*Gs}, "
                "difference at offset %zu for %s",
-               __LINE__, funcall, int (cs.res_len), cs.res,
+               __LINE__, int (tcase.res_len), tcase.res,
                int (sizeof (charT)), int (s_str.size ()), s_str.c_str (),
                match, itname);
 }
@@ -1311,62 +1279,61 @@
 void test_replace_range (const charT* wstr,
                          const charT* warg,
                          Traits*,
-                         const TestCase &cs,
-                         const char     *funcall)
+                         const TestCase &tcase)
 {
-    if (cs.bthrow)  // this method doesn't throw
+    if (tcase.bthrow)  // this method doesn't throw
         return;
 
     test_replace_range (wstr, warg, (Traits*)0,
-                       InputIter<charT>(0, 0, 0), cs, funcall);
+                       InputIter<charT>(0, 0, 0), tcase);
 
     // there is no need to call test_replace_range
     // for other iterators in this case
-    if (0 == cs.arg)
+    if (0 == tcase.arg)
         return;
 
     test_replace_range (wstr, warg, (Traits*)0,
-                       ConstFwdIter<charT>(0, 0, 0), cs, funcall);
+                       ConstFwdIter<charT>(0, 0, 0), tcase);
 
     test_replace_range (wstr, warg, (Traits*)0,
-                       ConstBidirIter<charT>(0, 0, 0), cs, funcall);
+                       ConstBidirIter<charT>(0, 0, 0), tcase);
 
     test_replace_range (wstr, warg, (Traits*)0,
-                       ConstRandomAccessIter<charT>(0, 0, 0), cs, funcall);
+                       ConstRandomAccessIter<charT>(0, 0, 0), tcase);
 }
 
 /**************************************************************************/
 
 template <class charT, class Traits>
 void test_replace (charT, Traits*,
-                   const TestCase &cs,
-                   const char     *funcall)
+                   ReplaceOverload which,
+                   const TestCase &tcase)
 {
     typedef std::allocator<charT>                        Allocator;
     typedef std::basic_string <charT, Traits, Allocator> TestString;
     typedef typename TestString::iterator                StringIter;
 
-    const bool use_iters = (Replace (ptr) <= cs.which);
+    const bool use_iters = Replace (iter_iter_ptr) <= which;
 
     static charT wstr [LLEN];
     static charT warg [LLEN];
 
-    rw_widen (wstr, cs.str, cs.str_len);
-    rw_widen (warg, cs.arg, cs.arg_len);
+    rw_widen (wstr, tcase.str, tcase.str_len);
+    rw_widen (warg, tcase.arg, tcase.arg_len);
 
     // special processing for replace_range to exercise all iterators
-    if (Replace (range) == cs.which) {
-        test_replace_range (wstr, warg, (Traits*)0, cs, funcall);
+    if (Replace (iter_iter_range) == which) {
+        test_replace_range (wstr, warg, (Traits*)0, tcase);
         return;
     }
 
-    /* const */ TestString s_str (wstr, cs.str_len);
-    const       TestString s_arg (warg, cs.arg_len);
+    /* const */ TestString s_str (wstr, tcase.str_len);
+    const       TestString s_arg (warg, tcase.arg_len);
 
     std::size_t res_off = 0;
-    int first = use_iters ? cs.off : cs.str_len + 1;
-    int last  = use_iters ? cs.off + cs.size : cs.str_len + 1;
-    std::size_t size = cs.size2 >= 0 ? cs.size2 : s_str.max_size () + 1;
+    int first = use_iters ? tcase.off : tcase.str_len + 1;
+    int last  = use_iters ? tcase.off + tcase.size : tcase.str_len + 1;
+    std::size_t size = tcase.size2 >= 0 ? tcase.size2 : s_str.max_size () + 1;
 
     StringIter it_first (std::size_t (first) >= s_str.size () ?
                          s_str.end () : s_str.begin () + first);
@@ -1374,9 +1341,9 @@
                          s_str.end () : s_str.begin () + last);
 
     // string function argument
-    const charT* const arg_ptr = cs.arg ? warg : s_str.c_str ();
-    const TestString&  arg_str = cs.arg ? s_arg : s_str;
-    const charT        arg_val = make_char (char (cs.val), (charT*)0);
+    const charT* const arg_ptr = tcase.arg ? warg : s_str.c_str ();
+    const TestString&  arg_str = tcase.arg ? s_arg : s_str;
+    const charT        arg_val = make_char (char (tcase.val), (charT*)0);
 
     // address of returned reference
     const TestString* res_ptr = 0;
@@ -1385,11 +1352,11 @@
 
     // is some exception expected ?
     const char* expected = 0;
-    if (1 == cs.bthrow && !use_iters)
+    if (1 == tcase.bthrow && !use_iters)
         expected = exp_exceptions [1];
-    if (2 == cs.bthrow && Replace (off_size_str_off_size) == cs.which)
+    if (2 == tcase.bthrow && Replace (size_size_str_size_size) == which)
         expected = exp_exceptions [1];
-    if (3 == cs.bthrow && !use_iters)
+    if (3 == tcase.bthrow && !use_iters)
         expected = exp_exceptions [2];
 
     const char* caught = 0;
@@ -1398,54 +1365,54 @@
 
 #else   // if defined (_RWSTD_NO_EXCEPTIONS)
 
-    if (cs.bthrow)
+    if (tcase.bthrow)
         return;
 
 #endif   // _RWSTD_NO_EXCEPTIONS
 
-    switch (cs.which)
-    {
-    case Replace (off_size_ptr): {
-        res_ptr = &s_str.replace (cs.off, cs.size, arg_ptr);
+    switch (which) {
+    case Replace (size_size_ptr): {
+        res_ptr = &s_str.replace (tcase.off, tcase.size, arg_ptr);
         break;
     }
 
-    case Replace (off_size_str): {
-        res_ptr = &s_str.replace (cs.off, cs.size, arg_str);
+    case Replace (size_size_str): {
+        res_ptr = &s_str.replace (tcase.off, tcase.size, arg_str);
         break;
     }
 
-    case Replace (off_size_ptr_size): {
-        res_ptr = &s_str.replace (cs.off, cs.size, arg_ptr, size);
+    case Replace (size_size_ptr_size): {
+        res_ptr = &s_str.replace (tcase.off, tcase.size, arg_ptr, size);
         break;
     }
 
-    case Replace (off_size_str_off_size): {
-        res_ptr = &s_str.replace (cs.off, cs.size, arg_str, cs.off2, size);
+    case Replace (size_size_str_size_size): {
+        res_ptr = &s_str.replace (tcase.off, tcase.size, arg_str,
+                                  tcase.off2, size);
         break;
     }
 
-    case Replace (off_size_size_val): {
-        res_ptr = &s_str.replace (cs.off, cs.size, size, arg_val);
+    case Replace (size_size_size_val): {
+        res_ptr = &s_str.replace (tcase.off, tcase.size, size, arg_val);
         break;
     }
 
-    case Replace (ptr): {
+    case Replace (iter_iter_ptr): {
         res_ptr = &s_str.replace (it_first, it_last, arg_ptr);
         break;
     }
 
-    case Replace (str): {
+    case Replace (iter_iter_str): {
         res_ptr = &s_str.replace (it_first, it_last, arg_str);
         break;
     }
 
-    case Replace (ptr_size): {
+    case Replace (iter_iter_ptr_size): {
         res_ptr = &s_str.replace (it_first, it_last, arg_ptr, size);
         break;
     }
 
-    case Replace (size_val): {
+    case Replace (iter_iter_size_val): {
         res_ptr = &s_str.replace (it_first, it_last, size, arg_val);
         break;
     }
@@ -1458,24 +1425,27 @@
     res_off = res_ptr - &s_str;
 
     // verify the returned value
-    rw_assert (0 == res_off, 0, cs.line,
-               "line %d. %s returned invalid reference, offset is %zu%",
-               __LINE__, funcall, res_off);
+    rw_assert (0 == res_off, 0, tcase.line,
+               "line %d. %{$FUNCALL} returned invalid reference, offset is %zu",
+               __LINE__, res_off);
 
     // verfiy that strings length are equal
-    rw_assert (cs.res_len == s_str.size (), 0, cs.line,
-               "line %d. %s expected %{#*s} with length %zu, got %{/*.*Gs} "
-               "with length %zu", __LINE__, funcall, int (cs.res_len),
-               cs.res, cs.res_len, int (sizeof (charT)), int (s_str.size ()),
+    rw_assert (tcase.res_len == s_str.size (), 0, tcase.line,
+               "line %d. %{$FUNCALL} expected %{#*s} with length %zu, "
+               "got %{/*.*Gs} with length %zu",
+               __LINE__, int (tcase.res_len),
+               tcase.res, tcase.res_len, int (sizeof (charT)),
+               int (s_str.size ()),
                s_str.c_str (), s_str.size ());
 
     // verfiy that replace results match expected result
-    const std::size_t match = rw_match (cs.res, s_str.c_str(), cs.res_len);
+    const std::size_t match =
+        rw_match (tcase.res, s_str.c_str(), tcase.res_len);
 
-    rw_assert (match == cs.res_len, 0, cs.line,
-               "line %d. %s expected %{#*s}, got %{/*.*Gs}, "
+    rw_assert (match == tcase.res_len, 0, tcase.line,
+               "line %d. %{$FUNCALL} expected %{#*s}, got %{/*.*Gs}, "
                "difference at offset %zu",
-               __LINE__, funcall, int (cs.res_len), cs.res,
+               __LINE__, int (tcase.res_len), tcase.res,
                int (sizeof (charT)), int (s_str.size ()), s_str.c_str (),
                match);
 
@@ -1496,32 +1466,29 @@
     _RWSTD_UNUSED (should_throw);
 #endif   // _RWSTD_NO_EXCEPTIONS
 
-    rw_assert (caught == expected, 0, cs.line,
-               "line %d. %s %{?}expected %s, caught %s"
+    rw_assert (caught == expected, 0, tcase.line,
+               "line %d. %{$FUNCALL} %{?}expected %s, caught %s"
                "%{:}unexpectedly caught %s%{;}", __LINE__,
-               funcall, 0 != expected, expected, caught, caught);
+               0 != expected, expected, caught, caught);
 }
 
 /**************************************************************************/
 
 static void
-test_replace (const MemFun *pfid, const TestCase& cs, bool exc_safety_test)
+test_replace (const MemFun   &memfun,
+              const TestCase &tcase)
 {
-    // format the description of the function call including
-    // the values of arguments for use in diagnostics
-    char* const funcall =
-        StringMembers::format (pfid->cid_, pfid->tid_,
-                               StringMembers::DefaultAllocator,
-                               cs);
+    // exercise exception safety?
+    const bool exception_safety = -1 == tcase.bthrow;
 
 #undef TEST
 #define TEST(charT, Traits)                                             \
-    exc_safety_test ?                                                   \
-        test_exceptions (charT (), (Traits*)0, cs, funcall)             \
-      : test_replace (charT (), (Traits*)0, cs, funcall)
+    exception_safety ?                                                  \
+        test_exceptions (charT (), (Traits*)0, memfun.which_, tcase)    \
+      : test_replace (charT (), (Traits*)0, memfun.which_, tcase)
 
-    if (StringMembers::DefaultTraits == pfid->tid_) {
-        if (StringMembers::Char == pfid->cid_)
+    if (StringMembers::DefaultTraits == memfun.traits_id_) {
+        if (StringMembers::Char == memfun.char_id_)
             TEST (char, std::char_traits<char>);
 
 #ifndef _RWSTD_NO_WCHAR_T
@@ -1531,103 +1498,17 @@
 
     }
     else {
-       if (StringMembers::Char == pfid->cid_)
+       if (StringMembers::Char == memfun.char_id_)
            TEST (char, UserTraits<char>);
 
 #ifndef _RWSTD_NO_WCHAR_T
-       else if (StringMembers::WChar == pfid->cid_)
+       else if (StringMembers::WChar == memfun.char_id_)
            TEST (wchar_t, UserTraits<wchar_t>);
 #endif   // _RWSTD_NO_WCHAR_T
 
        else
            TEST (UserChar, UserTraits<UserChar>);
     }
-
-    std::free (funcall);
-}
-
-/**************************************************************************/
-
-static void
-test_replace (const MemFun *pfid, const Test& test)
-{
-    rw_info (0, 0, 0, "std::basic_string<%s, %s<%1$s>, %s<%1$s>>::%s",
-             pfid->cname_, pfid->tname_, pfid->aname_, test.funsig);
-
-    if (StringMembers::opt_no_exception_safety)
-        rw_note (0, 0, 0,
-                 "std::basic_string<%s, %s<%1$s>, %s<%1$s>>::"
-                 "%s exception safety test disabled",
-                 pfid->cname_, pfid->tname_, pfid->aname_, test.funsig);
-
-#ifdef _RWSTD_NO_REPLACEABLE_NEW_DELETE
-
-    else
-        rw_warn (0, 0, __LINE__,
-                 "%s exception safety test: no replacable new and delete",
-                 test.funsig);
-
-#endif  //_RWSTD_NO_REPLACEABLE_NEW_DELETE
-
-    for (std::size_t i = 0; i != test.case_count; ++i) {
-
-        if (!rw_enabled (test.cases [i].line)) {
-            rw_note (0, 0, __LINE__,
-                     "test on line %d disabled", test.cases [i].line);
-            continue;
-        }
-
-        // do not exercise exceptions if they were disabled
-        if (   0 != StringMembers::opt_no_exceptions
-            && 0 != test.cases [i].bthrow)
-            continue;
-
-        // do not exercise exception safety if they were disabled
-        if (    0 != StringMembers::opt_no_exception_safety
-            && -1 == test.cases [i].bthrow)
-            continue;
-
-        test_replace (pfid, test.cases [i], -1 == test.cases [i].bthrow);
-    }
-}
-
-
-/**************************************************************************/
-
-static void
-run_test (const MemFun *pfid)
-{
-    if (   StringMembers::UserTraits == pfid->tid_
-        && StringMembers::opt_no_user_traits) {
-        rw_note (1 < StringMembers::opt_no_user_traits++, 0, 0,
-                 "user defined traits test disabled");
-    }
-    else if (   StringMembers::DefaultTraits == pfid->tid_
-             && StringMembers::opt_no_char_traits) {
-        rw_note (1 < StringMembers::opt_no_char_traits++, 0, 0,
-                 "char_traits test disabled");
-    }
-    else {
-
-        if (StringMembers::opt_no_exceptions)
-            rw_note (1 < StringMembers::opt_no_exceptions++, 0, 0,
-                     "string::replace exceptions tests disabled");
-
-        static const std::size_t ntests = sizeof tests / sizeof *tests;
-
-        for (std::size_t i = 0; i < ntests; i++) {
-
-            int tmp = tests [i].cases [0].which - StringMembers::replace_first;
-
-            if (Disabled (tmp))
-                rw_note (0, 0, 0,
-                         "std::basic_string<%s, %s<%1$s>, %s<%1$s>>::"
-                         "%s test disabled", pfid->cname_, pfid->tname_,
-                         pfid->aname_, tests [i].funsig);
-            else
-                test_replace (pfid, tests [i]);
-        }
-    }
 }
 
 /**************************************************************************/
@@ -1641,53 +1522,30 @@
             LSTR [i] = 'x';
     }
 
-    if (rw_enabled ("char")) {
+    static const StringMembers::Test
+        tests [] = {
 
-        MemFun fid (StringMembers::Char, "char",
-                    StringMembers::DefaultTraits, 0);
-
-        fid.tname_ = "char_traits";
-
-        run_test (&fid);
-
-        fid.tid_   = StringMembers::UserTraits;
-        fid.tname_ = "UserTraits";
-
-        run_test (&fid);
-    }
-    else
-        rw_note (0, 0, 0, "string::%s char tests disabled", method_name);
-
-    if (rw_enabled ("wchar_t")) {
-
-        MemFun fid (StringMembers::WChar, "wchar_t",
-                    StringMembers::DefaultTraits, 0);
-
-        fid.tname_ = "char_traits";
-
-        run_test (&fid);
-
-        fid.tid_   = StringMembers::UserTraits;
-        fid.tname_ = "UserTraits";
-
-        run_test (&fid);
-    }
-    else
-        rw_note (0, 0, 0, "string::%s wchar tests disabled", method_name);
+#undef TEST
+#define TEST(tag) {                                             \
+        StringMembers::replace_ ## tag, tag ## _test_cases,     \
+        sizeof tag ## _test_cases / sizeof *tag ## _test_cases  \
+    }
+
+            TEST (size_size_ptr),
+            TEST (size_size_str),
+            TEST (size_size_ptr_size),
+            TEST (size_size_str_size_size),
+            TEST (size_size_size_val),
+            TEST (iter_iter_ptr),
+            TEST (iter_iter_str),
+            TEST (iter_iter_ptr_size),
+            TEST (iter_iter_size_val),
+            TEST (iter_iter_range)
+        };
 
-    if (StringMembers::opt_no_user_char) {
-        rw_note (0, 0, 0, "user defined chars test disabled");
-    }
-    else {
-        MemFun fid (StringMembers::UChar, "UserChar",
-                    StringMembers::UserTraits, 0);
-        fid.tname_ = "UserTraits";
-        run_test (&fid);
-    }
+    const std::size_t test_count = sizeof tests / sizeof *tests;
 
-    // silence a bogus EDG eccp remark #550-D:
-    // variable "exp_exceptions" was set but never used
-    _RWSTD_UNUSED (exp_exceptions);
+    StringMembers::run_test (test_replace, tests, test_count);
 
     return 0;
 }
@@ -1705,11 +1563,11 @@
                     "|-no-exceptions# "
                     "|-no-exception-safety# "
 
-                    "|-no-replace-off-size-ptr# "
-                    "|-no-replace-off-size-str# "
-                    "|-no-replace-off_size-ptr-size# "
-                    "|-no-replace-off-size-str-off-size# "
-                    "|-no-replace-off-size-size-val# "
+                    "|-no-replace-size-size-ptr# "
+                    "|-no-replace-size-size-str# "
+                    "|-no-replace-size-size-ptr-size# "
+                    "|-no-replace-size-size-str-size-size# "
+                    "|-no-replace-size-size-size-val# "
                     "|-no-replace-ptr# "
                     "|-no-replace-str# "
                     "|-no-replace-ptr-size# "
@@ -1722,16 +1580,16 @@
                     &StringMembers::opt_no_exceptions,
                     &StringMembers::opt_no_exception_safety,
 
-                    &Disabled (Replace (off_size_ptr)),
-                    &Disabled (Replace (off_size_str)),
-                    &Disabled (Replace (off_size_ptr_size)),
-                    &Disabled (Replace (off_size_str_off_size)),
-                    &Disabled (Replace (off_size_size_val)),
-                    &Disabled (Replace (ptr)),
-                    &Disabled (Replace (str)),
-                    &Disabled (Replace (ptr_size)),
-                    &Disabled (Replace (size_val)),
-                    &Disabled (Replace (range)),
+                    &Disabled (Replace (size_size_ptr)),
+                    &Disabled (Replace (size_size_str)),
+                    &Disabled (Replace (size_size_ptr_size)),
+                    &Disabled (Replace (size_size_str_size_size)),
+                    &Disabled (Replace (size_size_size_val)),
+                    &Disabled (Replace (iter_iter_ptr)),
+                    &Disabled (Replace (iter_iter_str)),
+                    &Disabled (Replace (iter_iter_ptr_size)),
+                    &Disabled (Replace (iter_iter_size_val)),
+                    &Disabled (Replace (iter_iter_range)),
 
                     // sentinel
                     (void*)0);