stdcxx-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ant...@apache.org
Subject svn commit: r393473 - /incubator/stdcxx/trunk/tests/strings/21.string.append.cpp
Date Wed, 12 Apr 2006 14:42:31 GMT
Author: antonp
Date: Wed Apr 12 07:42:30 2006
New Revision: 393473

URL: http://svn.apache.org/viewcvs?rev=393473&view=rev
Log:
2006-04-12  Anton Pevtsov  <antonp@moscow.vdiweb.com>

	STDCXX-4
	* 21.string.append.cpp: New test exercising lib.string.append.

Modified:
    incubator/stdcxx/trunk/tests/strings/21.string.append.cpp

Modified: incubator/stdcxx/trunk/tests/strings/21.string.append.cpp
URL: http://svn.apache.org/viewcvs/incubator/stdcxx/trunk/tests/strings/21.string.append.cpp?rev=393473&r1=393472&r2=393473&view=diff
==============================================================================
--- incubator/stdcxx/trunk/tests/strings/21.string.append.cpp (original)
+++ incubator/stdcxx/trunk/tests/strings/21.string.append.cpp Wed Apr 12 07:42:30 2006
@@ -1,274 +1,1030 @@
 /***************************************************************************
  *
- * 21.string.append.cpp - test exercising [lib.string.append]
+ * 21.string.append.cpp - string test exercising lib.string.append
  *
  * $Id$
  *
  ***************************************************************************
  *
- * Copyright (c) 1994-2005 Quovadx,  Inc., acting through its  Rogue Wave
- * Software division. Licensed under the Apache License, Version 2.0 (the
- * "License");  you may  not use this file except  in compliance with the
- * License.    You    may   obtain   a   copy   of    the   License    at
- * http://www.apache.org/licenses/LICENSE-2.0.    Unless   required    by
- * applicable law  or agreed to  in writing,  software  distributed under
- * the License is distributed on an "AS IS" BASIS,  WITHOUT WARRANTIES OR
- * CONDITIONS OF  ANY KIND, either  express or implied.  See  the License
- * for the specific language governing permissions  and limitations under
- * the License.
+ * Copyright 2006 The Apache Software Foundation or its licensors,
+ * as applicable.
+ *
+ * Copyright 2006 Rogue Wave Software.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  * 
  **************************************************************************/
 
-#include <string>
+#include <memory>       // for placement operator new()
+#include <string>       // for string
+#include <cstdlib>      // for free(), size_t
+#include <stdexcept>    // for out_of_range, length_error
+
+#include <cmdopt.h>     // for rw_enabled()
+#include <driver.h>     // for rw_test()
+
+#include <rw_printf.h>  // for rw_asnprintf()
+#include <rw_char.h>    // for rw_widen()
+#include <alg_test.h>   // for InputIter<>
+
+#ifndef _RWSTD_NO_REPLACEABLE_NEW_DELETE
+   // disabled for compilers such as IBM VAC++ or MSVC
+   // that can't reliably replace the operators
+#  include <rw_new.h>
+#endif   // _RWSTD_NO_REPLACEABLE_NEW_DELETE
 
-#include <cmdopt.h>
-#include <driver.h>
+/**************************************************************************/
+
+struct MemFun
+{
+    enum charT  { Char, WChar, UChar };
+    enum Traits { DefaultTraits, UserTraits };
+
+    MemFun (charT cid, const char *cname,
+          Traits tid, const char *tname)
+        : cid_ (cid), tid_ (tid), 
+          cname_ (cname), tname_ (tname), aname_ ("allocator"),
+          fname_ ("append") { /* 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
+};
 
 /**************************************************************************/
 
-template<class _CharT>
-class Lit { };
-
-_RWSTD_SPECIALIZED_CLASS
-class Lit<char>
-{
-public:
-    static const char null[];
-    static const char abcdefg[];
-    static const char dummy[];
-    static const char testString[];
-    static const char differentString[];
-    static const char veryLongTestString[];
-    static const char a[];
-    static const char b[];
-    static const char longTestString[];
-    static const char anotherTestString[];
-    static const char testStringAnotherTestString[];
-    static const char reallyLong[];
-    static const char t[];
-    static const char s[];
-    static const char testStrings[];
-  
+// for convenience and brevity
+#define LSTR      long_string
+#define LLEN      long_string_len
+
+static const std::size_t long_string_len = 4096;
+static char long_string [long_string_len];
+
+static const char* const exp_exceptions[] = 
+    { "unknown exception", "out_of_range", "length_error" };
+
+/**************************************************************************/
+
+typedef enum AppendTags {
+
+    // append (const charT* s)
+    append_ptr          =  1,   
+    // append (const basic_string& str)
+    append_str          =  2,
+    // append (const charT* s, size_type n)
+    append_ptr_size     =  3,
+    // append (const basic_string& str, size_type pos, size_type n)
+    append_str_off_size =  4,
+    // append (size_type n, charT c)
+    append_size_val     =  5,
+    // append (InputIterator first, InputIterator last)
+    append_range        =  6
+
+} ATags;
+
+/**************************************************************************/
+
+struct TestCase
+{
+    int  line;
+
+    int  pos;
+    int  count;
+    int  ch;
+
+    const char* str;
+    std::size_t str_len;
+
+    const char* src;
+    std::size_t src_len;
+
+    const char* res;
+    std::size_t res_len;
+
+    int bthrow;
+
 };
 
-const char Lit<char>:: null[] = "\0";
-const char Lit<char>:: abcdefg[] = "abcdefg";
-const char Lit<char>:: dummy[] = "dummy";
-const char Lit<char>:: testString[] = "test string";
-const char Lit<char>:: differentString[]= "different string";
-const char Lit<char>:: veryLongTestString[] = "very long test string";
-const char Lit<char>:: a[] = "a";
-const char Lit<char>:: b[] = "b";
-const char Lit<char>:: longTestString[] = "long test string";
-const char Lit<char>:: anotherTestString[] = "another test string";
-const char Lit<char>:: testStringAnotherTestString[] = "test stringanother test string";
-const char Lit<char>:: reallyLong[] = "Really, really long test string that seems to never stop";
-const char Lit<char>:: t[] = "t";
-const char Lit<char>:: s[] = "s";
-const char Lit<char>:: testStrings[] = "test strings";
+/**************************************************************************/
 
+static int rw_opt_no_char_traits;              // for --no-char_traits
+static int rw_opt_no_user_traits;              // for --no-user_traits
 
-#ifndef _RWSTD_NO_WCHAR_T
-_RWSTD_SPECIALIZED_CLASS
-class Lit<wchar_t>
+static int rw_opt_no_user_chars;               // for --no-user_chars
+static int rw_opt_no_exceptions;               // for --no-exceptions
+static int rw_opt_no_exception_safety;         // for --no-exception-safety
+
+static int rw_opt_no_append_ptr;               // for --no-append-ptr
+static int rw_opt_no_append_str;               // for --no-append-str
+static int rw_opt_no_append_ptr_size;          // for --no-append-ptr-size
+static int rw_opt_no_append_str_off_size;      // for --no-append-str-off-size
+static int rw_opt_no_append_size_val;          // for --no-append-size-val
+static int rw_opt_no_append_range;             // for --no-append-range
+
+/**************************************************************************/
+
+// used to exercise 
+// append (const charT* s)
+static const TestCase ptr_test_cases [] = {
+
+#undef TEST
+#define TEST(str, src, res, bthrow)                            \
+    { __LINE__, -1, -1, -1, str, sizeof str - 1, src,          \
+      sizeof src - 1, res, sizeof res - 1, bthrow }
+
+    //    +----------------------------------------- controlled sequence
+    //    |             +--------------------------- sequence to be appended
+    //    |             |             +------------- expected result sequence
+    //    |             |             |        +---- exception info 
+    //    |             |             |        |         0 - no exception        
+    //    |             |             |        |         1 - out_of_range        
+    //    |             |             |        |         2 - length_error  
+    //    |             |             |        |        -1 - exc. safety
+    //    |             |             |        |                       
+    //    |             |             |        +--------------+             
+    //    V             V             V                       V
+    TEST ("ab",         "c",          "abc",                  0),
+
+    TEST ("",           "",           "",                     0),
+    TEST ("",           "\0",         "",                     0),
+    TEST ("",           "abc",        "abc",                  0),
+
+    TEST ("\0",         "",           "\0",                   0),
+    TEST ("\0",         "a",          "\0a",                  0),
+    TEST ("\0",         "\0\0",       "\0",                   0),
+
+    TEST ("ab",         "cd",         "abcd",                 0),
+    TEST ("bcd",        "a",          "bcda",                 0),
+    TEST ("cde",        "ab",         "cdeab",                0),
+    TEST ("abc",        "",           "abc",                  0),
+    TEST ("ab",         "c\0e",       "abc",                  0),
+
+    TEST ("\0\0ab",     "cdefghij",   "\0\0abcdefghij",       0),
+    TEST ("a\0\0b",     "cdefghij",   "a\0\0bcdefghij",       0),
+    TEST ("ab\0\0",     "cdefghij",   "ab\0\0cdefghij",       0),
+    TEST ("a\0b\0\0c",  "e\0",        "a\0b\0\0ce",           0),
+    TEST ("\0ab\0\0c",  "e\0",        "\0ab\0\0ce",           0),
+    TEST ("abcdefghij", "abcdefghij", "abcdefghijabcdefghij", 0),
+
+    TEST ("",           LSTR,         LSTR,                   0),
+    TEST (LSTR,         "",           LSTR,                   0),
+
+    TEST ("",           0,            "",                     0),
+    TEST ("abc",        0,            "abcabc",               0),
+    TEST ("a\0\0bc",    0,            "a\0\0bca",             0),
+    TEST ("\0\0abc",    0,            "\0\0abc",              0),
+    TEST ("abc\0\0",    0,            "abc\0\0abc",           0),
+
+#ifndef _RWSTD_NO_EXCEPTIONS
+
+    TEST ("",           LSTR,         LSTR,                  -1),
+
+#endif   // _RWSTD_NO_EXCEPTIONS
+
+    TEST ("last",       "test",       "lasttest",             0)
+};
+
+/**************************************************************************/
+
+// used to exercise 
+// append (const basic_string& str)
+static const TestCase str_test_cases [] = {
+
+#undef TEST
+#define TEST(str, src, res, bthrow)                            \
+    { __LINE__, -1, -1, -1, str, sizeof str - 1, src,          \
+      sizeof src - 1, res, sizeof res - 1, bthrow }
+
+    //    +----------------------------------------- controlled sequence
+    //    |             +--------------------------- sequence to be appended
+    //    |             |             +------------- expected result sequence
+    //    |             |             |        +---- exception info 
+    //    |             |             |        |         0 - no exception        
+    //    |             |             |        |         1 - out_of_range        
+    //    |             |             |        |         2 - length_error  
+    //    |             |             |        |        -1 - exc. safety
+    //    |             |             |        |                       
+    //    |             |             |        +--------------+             
+    //    V             V             V                       V
+    TEST ("ab",         "c",          "abc",                  0),
+
+    TEST ("",           "",           "",                     0),
+    TEST ("",           "\0",         "\0",                   0),
+    TEST ("",           "abc",        "abc",                  0),
+
+    TEST ("\0",         "",           "\0",                   0),
+    TEST ("\0",         "a",          "\0a",                  0),
+    TEST ("\0",         "\0\0",       "\0\0\0",               0),
+
+    TEST ("ab",         "cd",         "abcd",                 0),
+    TEST ("bcd",        "a",          "bcda",                 0),
+    TEST ("cde",        "ab",         "cdeab",                0),
+    TEST ("abc",        "",           "abc",                  0),
+    TEST ("ab",         "c\0e",       "abc\0e",               0),
+
+    TEST ("\0\0ab",     "cdefghij",   "\0\0abcdefghij",       0),
+    TEST ("a\0\0b",     "cdefghij",   "a\0\0bcdefghij",       0),
+    TEST ("ab\0\0",     "cdefghij",   "ab\0\0cdefghij",       0),
+    TEST ("a\0b\0\0c",  "e\0",        "a\0b\0\0ce\0",         0),
+    TEST ("\0ab\0\0c",  "e\0",        "\0ab\0\0ce\0",         0),
+    TEST ("ab\0\0c\0",  "\0e",        "ab\0\0c\0\0e",         0),
+    TEST ("abcdefghij", "abcdefghij", "abcdefghijabcdefghij", 0),
+
+    TEST ("",           LSTR,         LSTR,                   0),
+    TEST (LSTR,         "",           LSTR,                   0),
+
+    TEST ("",           0,            "",                     0),
+    TEST ("abc",        0,            "abcabc",               0),
+    TEST ("a\0\0bc",    0,            "a\0\0bca\0\0bc",       0),
+    TEST ("\0\0abc",    0,            "\0\0abc\0\0abc",       0),
+    TEST ("abc\0\0",    0,            "abc\0\0abc\0\0",       0),
+
+#ifndef _RWSTD_NO_EXCEPTIONS
+
+    TEST ("",           LSTR,         LSTR,                  -1),
+
+#endif   // _RWSTD_NO_EXCEPTIONS
+
+    TEST ("last",       "test",       "lasttest",             0)
+};
+
+/**************************************************************************/
+
+// used to exercise 
+// append (const charT* s, size_type n)
+static const TestCase ptr_size_test_cases [] = {
+
+#undef TEST
+#define TEST(str, src, count, res, bthrow)                            \
+    { __LINE__, -1, count, -1, str, sizeof str - 1, src,              \
+      sizeof src - 1, res, sizeof res - 1, bthrow }
+
+    //    +-------------------------------------- controlled sequence
+    //    |            +------------------------- sequence to be appended
+    //    |            |            +------------ append() n argument 
+    //    |            |            |  +--------- expected result sequence 
+    //    |            |            |  |     +--- exception info 
+    //    |            |            |  |     |      0 - no exception        
+    //    |            |            |  |     |      1 - out_of_range        
+    //    |            |            |  |     |      2 - length_error  
+    //    |            |            |  |     |     -1 - exc. safety 
+    //    |            |            |  |     |                           
+    //    |            |            |  |     +------------+             
+    //    V            V            V  V                  V             
+    TEST ("ab",        "c",         1, "abc",             0),
+
+    TEST ("",          "",          0,  "",               0),
+    TEST ("",          "abc",       1,  "a",              0),
+    TEST ("",          "\0",        1,  "\0",             0),
+
+    TEST ("\0",        "",          0,  "\0",             0),
+    TEST ("\0",        "a",         0,  "\0",             0),
+    TEST ("\0",        "a",         1,  "\0a",            0),
+    TEST ("\0",        "\0\0",      1,  "\0\0",           0),
+    TEST ("\0",        "\0\0",      2,  "\0\0\0",         0),
+
+    TEST ("cde",       "ab",        2,  "cdeab",          0),
+    TEST ("cde",       "ab",        1,  "cdea",           0),
+
+    TEST ("\0e\0",     "a\0b\0\0c", 0,  "\0e\0",          0),
+    TEST ("\0e\0",     "\0ab\0\0c", 3,  "\0e\0\0ab",      0),
+
+    TEST ("a\0b\0\0c", "\0e\0",     3,  "a\0b\0\0c\0e\0", 0),
+    TEST ("a\0b\0\0c", "\0\0e\0",   2,  "a\0b\0\0c\0\0",  0),
+    TEST ("\0ab\0\0c", "\0e\0",     1,  "\0ab\0\0c\0",    0),
+    TEST ("a\0bc\0\0", "\0e",       2,  "a\0bc\0\0\0e",   0),
+
+    TEST ("",          0,           0,  "",               0),
+    TEST ("abc",       0,           0,  "abc",            0),
+    TEST ("abc",       0,           1,  "abca",           0),
+    TEST ("abc",       0,           2,  "abcab",          0),
+    TEST ("a\0bc",     0,           2,  "a\0bca\0",       0),
+    TEST ("\0abc\0\0", 0,           1,  "\0abc\0\0\0",    0),
+    TEST ("a\0bc\0\0", 0,           3,  "a\0bc\0\0a\0b",  0),
+
+    TEST ("",          LSTR, LLEN - 1,  LSTR,             0),
+    TEST (LSTR,        "",          0,  LSTR,             0),
+
+#ifndef _RWSTD_NO_EXCEPTIONS
+
+    TEST ("",          LSTR, LLEN - 1,  LSTR,            -1),
+
+#endif   // _RWSTD_NO_EXCEPTIONS
+
+    TEST ("last",      "test",      4, "lasttest",        0)
+};
+
+/**************************************************************************/
+
+// used to exercise 
+// append (const basic_string& str, size_type pos, size_type n)
+// append (InputIterator first, InputIterator last)
+static const TestCase range_test_cases [] = {
+
+#undef TEST
+#define TEST(str, src, pos, count, res, bthrow)                            \
+    { __LINE__, pos, count, -1, str, sizeof str - 1, src,                  \
+      sizeof src - 1, res, sizeof res - 1, bthrow }
+
+    //    +-------------------------------------- controlled sequence
+    //    |            +------------------------- sequence to be appended
+    //    |            |            +------------ append() pos argument
+    //    |            |            |  +--------- append() n argument 
+    //    |            |            |  |  +------ expected result sequence
+    //    |            |            |  |  |  +--- exception info  
+    //    |            |            |  |  |  |       0 - no exception        
+    //    |            |            |  |  |  |       1 - out_of_range        
+    //    |            |            |  |  |  |       2 - length_error   
+    //    |            |            |  |  |  |      -1 - exc. safety 
+    //    |            |            |  |  |  |                         
+    //    |            |            |  |  |  +----------------+             
+    //    V            V            V  V  V                   V             
+    TEST ("ab",        "c",         0, 1, "abc",              0),
+
+    TEST ("",          "",          0, 0,  "",                0),
+    TEST ("",          "abc",       1, 1,  "b",               0),
+    TEST ("",          "\0",        0, 1,  "\0",              0),
+
+    TEST ("\0",        "",          0, 0,  "\0",              0),
+
+    TEST ("abc",       "",          0, 0,  "abc",             0),
+
+    TEST ("\0",        "a",         0, 1,  "\0a",             0),
+    TEST ("\0",        "\0\0",      1, 1,  "\0\0",            0),
+    TEST ("\0",        "\0\0",      0, 2,  "\0\0\0",          0),
+    TEST ("\0",        "\0\0",      1, 5,  "\0\0",            0),
+
+    TEST ("cde",       "ab",        0, 2,  "cdeab",           0),
+    TEST ("cde",       "ab",        0, 1,  "cdea",            0),
+    TEST ("cde",       "ab",        1, 5,  "cdeb",            0),
+
+    TEST ("ab",        "c\0e",      0, 3,  "abc\0e",          0),
+    TEST ("ab",        "c\0e",      1, 2,  "ab\0e",           0),
+    TEST ("ab",        "c\0e",      0, 2,  "abc\0",           0),
+
+    TEST ("\0e\0",     "\0ab\0\0c", 0, 9,  "\0e\0\0ab\0\0c",  0),
+    TEST ("\0e\0",     "\0ab\0\0c", 0, 3,  "\0e\0\0ab",       0),
+    TEST ("a\0b\0\0c", "\0e\0",     0, 3,  "a\0b\0\0c\0e\0",  0),
+    TEST ("a\0b\0\0c", "\0\0e\0",   0, 2,  "a\0b\0\0c\0\0",   0),
+    TEST ("\0ab\0\0c", "\0e\0",     2, 1,  "\0ab\0\0c\0",     0),
+    TEST ("a\0bc\0\0", "\0e",       0, 2,  "a\0bc\0\0\0e",    0),
+
+    TEST ("",          0,           0, 0,  "",                0),
+    TEST ("abc",       0,           1, 0,  "abc",             0),
+    TEST ("abc",       0,           1, 1,  "abcb",            0),
+    TEST ("abc",       0,           0, 2,  "abcab",           0),
+    TEST ("a\0bc\0\0", 0,           4, 2,  "a\0bc\0\0\0\0",   0),
+    TEST ("a\0bc\0\0", 0,           1, 3,  "a\0bc\0\0\0bc",   0),
+    TEST ("a\0bc\0\0", 0,           3, 9,  "a\0bc\0\0c\0\0",  0),
+    TEST ("abcdef",    0,           1, 2,  "abcdefbc",        0),
+
+    TEST ("",          LSTR,        0, LLEN, LSTR,            0),
+    TEST (LSTR,        "",          0, 0,    LSTR,            0),
+
+#ifndef _RWSTD_NO_EXCEPTIONS
+
+    TEST ("",          "\0",        2, 0,  "",                1),
+    TEST ("",          "a",         2, 0,  "",                1),
+    TEST ("",          LSTR,LLEN + 10, 0,  "",                1),
+
+    TEST (LSTR,        0,           0, 0, 0,                 -1),
+
+#endif   // _RWSTD_NO_EXCEPTIONS
+
+    TEST ("last",      "test",      0, 4, "lasttest",         0)
+};
+
+/**************************************************************************/
+
+// used to exercise 
+// append (charT c, size_type n)
+static const TestCase size_val_test_cases [] = {
+
+#undef TEST
+#define TEST(str, count, ch, res, bthrow)                            \
+    { __LINE__, -1, count, ch, str, sizeof str - 1, 0, 0,            \
+      res, sizeof res - 1, bthrow }
+
+    //    +-------------------------------------- controlled sequence
+    //    |            +------------------------- append() count argument
+    //    |            |   +--------------------- character to be appended
+    //    |            |   |   +----------------- expected result sequence 
+    //    |            |   |   |       +--------- exception info 
+    //    |            |   |   |       |             0 - no exception        
+    //    |            |   |   |       |             1 - out_of_range        
+    //    |            |   |   |       |             2 - length_error  
+    //    |            |   |   |       |            -1 - exc. safety
+    //    |            |   |   |       |                         
+    //    |            |   |   |       +-----------+             
+    //    V            V   V   V                   V                
+    TEST ("ab",        1, 'c', "abc",              0),
+
+    TEST ("",          0, ' ',  "",                0),
+    TEST ("",          1, 'b',  "b",               0),
+    TEST ("",          3, 'b',  "bbb",             0),
+
+    TEST ("\0",        0, ' ',  "\0",              0),
+    TEST ("",          2, '\0', "\0\0",            0),
+
+    TEST ("\0",        1, 'a',  "\0a",             0),
+    TEST ("\0",        1, '\0', "\0\0",            0),
+    TEST ("\0",        2, '\0', "\0\0\0",          0),
+    TEST ("\0",        0, '\0', "\0",              0),
+
+    TEST ("cde",       1, 'a',  "cdea",            0),
+    TEST ("cde",       2, 'a',  "cdeaa",           0),
+    TEST ("cde",       3, 'a',  "cdeaaa",          0),
+
+    TEST ("ab",        2, '\0', "ab\0\0",          0),
+    TEST ("ab",        1, '\0', "ab\0",            0),
+    TEST ("ab",        2, '\0', "ab\0\0",          0),
+
+    TEST ("a\0b\0\0c", 2, '\0', "a\0b\0\0c\0\0",   0),
+    TEST ("a\0b\0\0c", 1, '\0', "a\0b\0\0c\0",     0),
+    TEST ("\0ab\0\0c", 3, '\0', "\0ab\0\0c\0\0\0", 0),
+    TEST ("a\0bc\0\0", 2, 'a',  "a\0bc\0\0aa",     0),
+
+    TEST ("",          LLEN - 1, 'x', LSTR,        0),
+    TEST (LSTR,        0,        'x', LSTR,        0),
+
+#ifndef _RWSTD_NO_EXCEPTIONS
+
+    TEST ("",          LLEN - 1, 'x', LSTR,       -1),
+
+#endif   // _RWSTD_NO_EXCEPTIONS
+
+    TEST ("last",      4, 't', "lasttttt",         0)
+};
+
+/**************************************************************************/
+
+static const struct FunctionTag
 {
-public:
-    static const wchar_t null[];
-    static const wchar_t abcdefg[];
-    static const wchar_t dummy[];
-    static const wchar_t testString[];
-    static const wchar_t differentString[];
-    static const wchar_t veryLongTestString[];
-    static const wchar_t a[];
-    static const wchar_t b[];
-    static const wchar_t longTestString[];
-    static const wchar_t anotherTestString[];
-    static const wchar_t testStringAnotherTestString[];
-    static const wchar_t reallyLong[];
-    static const wchar_t t[];
-    static const wchar_t s[];
-    static const wchar_t testStrings[];
+    ATags           a_tag;
+    const int      *p_opt;
+    const TestCase *t_cases;
+    std::size_t     n_cases;
+    const char     *str_hdr;
+
+} function_tags [] = {
+
+#undef TEST
+#define TEST(tag, opt, cases, hdr)                              \
+    { tag, &opt, cases, sizeof cases / sizeof *cases, hdr }     
+
+    TEST (append_ptr, rw_opt_no_append_ptr, ptr_test_cases,                  
+          "append (const charT* s)"),
+
+    TEST (append_str, rw_opt_no_append_str, str_test_cases,            
+          "append (const basic_string& str)"),
+
+    TEST (append_ptr_size, rw_opt_no_append_ptr_size, ptr_size_test_cases, 
+          "append (const charT* s, size_type n)"),
+
+    TEST (append_str_off_size, rw_opt_no_append_str_off_size, 
+          range_test_cases, "append (const basic_string& str,"
+          " size_type pos, size_type n)"),
+
+    TEST (append_size_val, rw_opt_no_append_size_val, 
+          size_val_test_cases, "append (size_type n, charT c)"),
+
+    TEST (append_range, rw_opt_no_append_range, range_test_cases, 
+          "append (InputIterator first, InputIterator last)")
 };
 
-const wchar_t Lit<wchar_t>:: null[] = L"\0";
-const wchar_t Lit<wchar_t>:: abcdefg[] = L"abcdefg";
-const wchar_t Lit<wchar_t>:: dummy[] = L"dummy";
-const wchar_t Lit<wchar_t>:: testString[] = L"test string";
-const wchar_t Lit<wchar_t>:: differentString[] = L"different string";
-const wchar_t Lit<wchar_t>:: veryLongTestString[] = L"very long test string";
-const wchar_t Lit<wchar_t>:: a[] = L"a";
-const wchar_t Lit<wchar_t>:: b[] = L"b";
-const wchar_t Lit<wchar_t>:: longTestString[] = L"long test string";
-const wchar_t Lit<wchar_t>:: anotherTestString[] = L"another test string";
-const wchar_t Lit<wchar_t>:: testStringAnotherTestString[] = L"test stringanother test string";
-const wchar_t Lit<wchar_t>:: reallyLong[] = L"Really, really long test string that seems to never stop";
-const wchar_t Lit<wchar_t>:: t[] = L"t";
-const wchar_t Lit<wchar_t>:: s[] = L"s";
-const wchar_t Lit<wchar_t>:: testStrings[] = L"test strings";
-#endif
+/**************************************************************************/
+
+template <class charT, class Traits>
+void test_append_exceptions (charT, Traits*,  
+                             const ATags     which,
+                             const TestCase &cs,
+                             const char     *append_fmt)
+{
+    typedef std::basic_string <charT, Traits, 
+                               std::allocator<charT> > TestString;
+    typedef typename TestString::iterator StringIter;
+    typedef typename TestString::const_iterator ConstStringIter;
+
+    static charT wstr [LLEN];
+    static charT wsrc [LLEN];
+
+    rw_widen (wstr, cs.str, cs.str_len);
+    rw_widen (wsrc, cs.src, cs.src_len);
+
+    TestString s_str (wstr, cs.str_len);
+    TestString s_src (wsrc, cs.src_len);
+
+    std::size_t throw_after = 0;
+
+    const std::size_t     size     = s_str.size ();
+    const std::size_t     capacity = s_str.capacity ();
+    const ConstStringIter begin    = s_str.begin ();
+
+#ifndef _RWSTD_NO_REPLACEABLE_NEW_DELETE
+
+    rwt_free_store* const pst = rwt_get_free_store (0);
+
+#endif   // _RWSTD_NO_REPLACEABLE_NEW_DELETE
+
+    // iterate for`n=throw_after' starting at the next call to operator
+    // new, forcing each call to throw an exception, until the appendion
+    // finally succeeds (i.e, no exception is thrown)
+    for ( ; ; ) {
+
+#ifndef _RWSTD_NO_EXCEPTIONS
+#  ifndef _RWSTD_NO_REPLACEABLE_NEW_DELETE
+
+        *pst->throw_at_calls_ [0] = pst->new_calls_ [0] + throw_after + 1;
+
+#  endif   // _RWSTD_NO_REPLACEABLE_NEW_DELETE
+#endif   // _RWSTD_NO_EXCEPTIONS
+
+        _TRY {
+            if (append_ptr == which) 
+                s_str.append (cs.src ? wsrc : s_str.c_str ());
+
+            else if (append_str == which)
+                s_str.append (cs.src ? s_src : s_str);
+
+            else if (append_ptr_size == which)
+                s_str.append (cs.src ? wsrc : s_str.c_str (), cs.count);
+
+            else if (append_str_off_size == which) 
+                s_str.append (cs.src ? s_src : s_str, cs.pos, cs.count);
+
+            else if (append_size_val == which)
+                s_str.append (cs.count, make_char ((char) cs.ch, (charT*)0));
+
+            else if (append_range == which)
+                s_str.append (s_src.begin (), s_src.end ());
+
+            break;
+        }
+        _CATCH (...) {
+
+#ifndef _RWSTD_NO_EXCEPTIONS
+
+            // 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 "
+                       "from %zu to %zu after an exception",
+                       __LINE__, append_fmt, size, s_str.size ());
+
+            rw_assert (s_str.capacity () == capacity, 0, cs.line,
+                       "line %d: %s: capacity unexpectedly "
+                       "changed from %zu to %zu after an exception",
+                       __LINE__, append_fmt, capacity, s_str.capacity ());
+
+            
+            rw_assert (s_str.begin () == begin, 0, cs.line,
+                       "line %d: %s: begin() unexpectedly "
+                       "changed from after an exception by %d",
+                       __LINE__, append_fmt, s_str.begin () - begin);
+
+
+            // increment to allow this call to operator new to succeed
+            // and force the next one to fail, and try to append again
+            ++throw_after;
+
+#endif   // _RWSTD_NO_EXCEPTIONS
+
+        }   // catch
+    }   // for
+
+#ifndef _RWSTD_NO_EXCEPTIONS
+#  ifndef _RWSTD_NO_REPLACEABLE_NEW_DELETE
+
+    // verify that if exceptions are enabled and when capacity changes
+    // 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__, append_fmt);
+
+#  endif   // _RWSTD_NO_REPLACEABLE_NEW_DELETE
+#else   // if defined (_RWSTD_NO_EXCEPTIONS)
+
+    _RWSTD_UNUSED (size);
+    _RWSTD_UNUSED (capacity);
+    _RWSTD_UNUSED (throw_after);
+
+#endif   // _RWSTD_NO_EXCEPTIONS
+
+#ifndef _RWSTD_NO_REPLACEABLE_NEW_DELETE
+
+    *pst->throw_at_calls_ [0] = std::size_t (-1);
+
+#endif   // _RWSTD_NO_REPLACEABLE_NEW_DELETE
+}
 
 /**************************************************************************/
 
-template <typename T>
-void test_append (T, const char*)
-{
-    typedef std::char_traits<T>                     Traits;
-    typedef std::allocator<T>                       Allocator;
-    typedef std::basic_string<T, Traits, Allocator> String;
+template <class charT, class Traits, class Iterator>
+void test_append_range (charT* wstr,
+                        charT* wsrc, 
+                        Traits*,
+                        const Iterator &it,
+                        const TestCase &cs,
+                        const char     *append_fmt)
+{
+    typedef std::basic_string <charT, Traits, 
+                               std::allocator<charT> > String;
+    typedef typename String::iterator StringIter;
 
-    rw_info (0, 0, 0, "Assignment operator with string parameter");
+    const char* const itname = 
+        cs.src ? type_name (it, (charT*)0) : "basic_string::iterator";
 
-    {
-        String t1(Lit<T>::abcdefg), t2;
-        t2 = t1;
-        // Basic string assignment over nullString
-        rw_assert ((t2 == t1), 0, __LINE__, "B1");
+    String s_str (wstr, cs.str_len);
+    String s_src (wsrc, cs.src_len);
+
+    std::size_t off_last = cs.pos + cs.count;
+
+    if (cs.src) {
+        off_last = off_last > s_src.size () ? s_src.size () : off_last;
+
+        const Iterator first = make_iter (wsrc + cs.pos, 
+            wsrc + cs.pos, wsrc + off_last, Iterator (0, 0, 0));
+        const Iterator last  = make_iter (wsrc + off_last, 
+            wsrc + cs.pos, wsrc + off_last, Iterator (0, 0, 0));
+
+        s_str.append (first, last);
     }
+    else {
+        StringIter first (s_str.begin () + cs.pos);
+        StringIter last  (off_last > s_str.size () ? 
+            s_str.end () 
+          : s_str.begin () + off_last);
 
-    {
-        String t1(Lit<T>::abcdefg), t2(Lit<T>::dummy);
-        t2 = t1;
-        // Basic string assignment over dummy string
-        rw_assert ((t2 == t1), 0, __LINE__, "B2");
+        s_str.append (first, last);
     }
 
-    {
-        String t1, t2;
-        t2 = t1;
-        // Assignment of nullString over nullString
-        rw_assert ((t2 == t1), 0, __LINE__, "B3");
-    
-        // Correctly references nullString
-        rw_assert (t2.data () == String ().data (), 0, __LINE__, "B4");
+    const std::size_t match = rw_match (cs.res, s_str.c_str(), cs.res_len);
+
+    rw_assert (match == cs.res_len, 0, cs.line,
+               "line %d. %s expected %{#*s}, got %{/*.*Gs}, "
+               "difference at pos %zu for %s", 
+               __LINE__, append_fmt, int (cs.res_len), cs.res, 
+               int (sizeof (charT)), int (s_str.size ()), s_str.c_str (), 
+               match, itname);
+}
+
+/**************************************************************************/
+
+template <class charT, class Traits>
+void test_append_range (charT* wstr, 
+                        charT* wsrc, 
+                        Traits*,
+                        const TestCase &cs,
+                        const char     *append_fmt)
+{
+    if (cs.bthrow)  // this method doesn't throw
+        return;
+
+    test_append_range (wstr, wsrc, (Traits*)0, 
+                       InputIter<charT>(0, 0, 0), cs, append_fmt);
+
+    // there is no need to call test_append_range 
+    // for other iterators in this case
+    if (0 == cs.src)
+        return;
+
+    test_append_range (wstr, wsrc, (Traits*)0, 
+                       ConstFwdIter<charT>(0, 0, 0), cs, append_fmt);
+
+    test_append_range (wstr, wsrc, (Traits*)0, 
+                       ConstBidirIter<charT>(0, 0, 0), cs, append_fmt);
+
+    test_append_range (wstr, wsrc, (Traits*)0, 
+                       ConstRandomAccessIter<charT>(0, 0, 0), cs, append_fmt);
+}
+
+/**************************************************************************/
+
+template <class charT, class Traits>
+void test_append (charT, Traits*,  
+                  const ATags     which,
+                  const TestCase &cs,
+                  const char     *append_fmt)
+{
+    typedef std::basic_string <charT, Traits, 
+                               std::allocator<charT> > TestString;
+    typedef typename TestString::iterator StringIter;
+
+    static charT wstr [LLEN];
+    static charT wsrc [LLEN];
+
+    rw_widen (wstr, cs.str, cs.str_len);
+    rw_widen (wsrc, cs.src, cs.src_len);
+
+    // special processing for append_range to exercise all iterators
+    if (append_range == which) {
+        test_append_range (wstr, wsrc, (Traits*)0, cs, append_fmt);
+        return;
     }
 
+    TestString s_str (wstr, cs.str_len);
+    TestString s_src (wsrc, cs.src_len);
+
+    std::size_t res_off = 0;
+
+#ifndef _RWSTD_NO_EXCEPTIONS
+
+    // is some exception expected ?
+    const char* expected = 0;
+    if (1 == cs.bthrow && append_str_off_size == which)
+        expected = exp_exceptions [1];
+    if (2 == cs.bthrow)
+        expected = exp_exceptions [2];
+
+    const char* caught = 0;
+
+    try {
+
+#endif   // _RWSTD_NO_EXCEPTIONS
+
+    switch (which)
     {
-        String t1, t2(Lit<T>::dummy);
-        t2 = t1;
-        // Assignment of nullString over dummy string
-        rw_assert ((t2 == t1), 0, __LINE__, "B5");
-    
-        // Correctly references nullString
-        rw_assert (t2.data () == String ().data (), 0, __LINE__, "B6");
-    }
-  
-    rw_info (0, 0, 0, "Assignment operator with const char pointer");
-  
-    String nl;
-    {
-        String t1;
-        //t1 = "";
-        t1 = Lit<T>::null;
-    
-        // Assigning nullString literal over nullString
-        rw_assert ((nl == t1), 0, __LINE__, "B7");
-    
-        // Returns the correct data
-        const T* temp = t1.data();
-        rw_assert ((0 == temp[0]), 0, __LINE__, "B8");
+    case append_ptr: {
+        TestString& s_res = s_str.append (cs.src ? wsrc : s_str.c_str ());
+        res_off = &s_res - &s_str;
+        break;
+    }
 
-        // Returns the correct c_str
-        rw_assert ((*t1.c_str() == Lit<T>::null[0]), 0, __LINE__, "B9");
+    case append_str: {
+        TestString& s_res = s_str.append (cs.src ? s_src : s_str);
+        res_off = &s_res - &s_str;
+        break;
     }
 
-    {
-        String t1(Lit<T>::testString);
-        t1 = Lit<T>::null;
-    
-        // Assigning nullString literal over test string
-        rw_assert ((nl == t1), 0, __LINE__, "B10");
-    
-        // Returns the correct data
-        const T* temp = t1.data();
-        rw_assert ((0 == temp[0]), 0, __LINE__, "B11");
-    
-        // Returns the correct c_str
-        rw_assert ((*t1.c_str() == Lit<T>::null[0]), 0, __LINE__, "B12");
+    case append_ptr_size: {
+        TestString& s_res = 
+            s_str.append (cs.src ? wsrc : s_str.c_str (), cs.count);
+        res_off = &s_res - &s_str;
+        break;
     }
 
-    {
-        String t1(Lit<T>::testString);
-    
-        t1 = Lit<T>::differentString;
-        // Assigning longer literal over shorter literal
-        rw_assert ((std::char_traits<T>::compare(
-                        t1.data(), Lit<T>::differentString, 17) == 0), 
-                   0, __LINE__, "B13");
-    
-        // Returns the correct c_str
-        rw_assert ((std::char_traits<T>::compare(
-                        t1.c_str(), Lit<T>::differentString, 17) == 0), 
-                   0, __LINE__, "B14");
-    
-        // Returns the correct length
-        rw_assert ((t1.length() == 16), 0, __LINE__, "B15");
+    case append_str_off_size: {
+        TestString& s_res = 
+            s_str.append (cs.src ? s_src : s_str, cs.pos, cs.count);
+        res_off = &s_res - &s_str;
+        break;
     }
 
-    {
-        String t1(Lit<T>::veryLongTestString);
-        t1 = Lit<T>::differentString;
-    
-        // Assigning shorter literal over longer literal
-        rw_assert ((std::char_traits<T>::compare(
-                        t1.data(), Lit<T>::differentString, 17) == 0), 
-                   0, __LINE__, "B16");
-    
-        // Returns the correct c_str
-        rw_assert ((std::char_traits<T>::compare(
-                        t1.c_str(), Lit<T>::differentString, 17) == 0), 
-                   0, __LINE__, "B17");
-    
-        // Returns the correct length
-        rw_assert ((t1.length() == 16), 0, __LINE__, "B18");
+    case append_size_val: {
+        TestString& s_res = 
+            s_str.append (cs.count, make_char ((char) cs.ch, (charT*)0));
+        res_off = &s_res - &s_str;
+        break;
     }
-  
-    rw_info (0, 0, 0, "Assignment operator with char reference");
 
-    {
-        String t1;
-        t1 = Lit<T>::a[0];
-    
-        // Assigning character over nullString
-        rw_assert ((t1 == Lit<T>::a), 0, __LINE__, "B19");
-    
-        // Returns correct length
-        rw_assert ((t1.length() == 1), 0, __LINE__, "B20");
+    default:
+        RW_ASSERT ("test logic error: unknown append overload");
+        return;
     }
 
-    {
-        String t1(1, Lit<T>::b[0]);
-        t1 = Lit<T>::a[0];
-        //t1 = 'a';
-    
-        // Assigning character over single char string
-        rw_assert ((t1 == Lit<T>::a), 0, __LINE__, "B21");
-    
-        // Returns correct length
-        rw_assert ((t1.length() == 1), 0, __LINE__, "B22");
+    // verify the returned value
+    rw_assert (0 == res_off, 0, cs.line,
+               "line %d. %s returned invalid reference, offset is %zu", 
+               __LINE__, append_fmt, 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__, append_fmt, int (cs.res_len), 
+               cs.res, cs.res_len, int (sizeof (charT)), int (s_str.size ()),
+               s_str.c_str (), s_str.size ());
+
+    // verfiy that append results match expected result
+    const std::size_t match = rw_match (cs.res, s_str.c_str(), cs.res_len);
+
+    rw_assert (match == cs.res_len, 0, cs.line,
+               "line %d. %s expected %{#*s}, got %{/*.*Gs}, "
+               "difference at pos %zu", 
+               __LINE__, append_fmt, int (cs.res_len), cs.res, 
+               int (sizeof (charT)), int (s_str.size ()), s_str.c_str (), 
+               match);
+
+#ifndef _RWSTD_NO_EXCEPTIONS
+
+    }
+    catch (std::out_of_range) {
+        caught = exp_exceptions[1];
     }
+    catch (std::length_error) {
+        caught = exp_exceptions[2];
+    }
+    catch (...) {
+        caught = exp_exceptions[0];
+    }
+
+#else   // if defined (_RWSTD_NO_EXCEPTIONS)
+    _RWSTD_UNUSED (should_throw);
+#endif   // _RWSTD_NO_EXCEPTIONS
+
+    rw_assert (caught == expected, 0, cs.line,
+               "line %d. %s %{?}expected %s, caught %s"
+               "%{:}unexpectedly caught %s%{;}",
+               __LINE__, append_fmt, 0 != expected, expected, caught, caught);
+}
+
+/**************************************************************************/
+
+void get_append_format (char** pbuf, std::size_t* pbufsize, 
+                        const MemFun *pfid, 
+                        const ATags which, 
+                        const TestCase& cs)
+{
+    if (   MemFun::DefaultTraits == pfid->tid_
+        && (MemFun::Char == pfid->cid_ || MemFun::WChar == pfid->cid_))
+        rw_asnprintf (pbuf, pbufsize,
+                      "std::%{?}w%{;}string (%{#*s}).append",
+                      MemFun::WChar == pfid->cid_,
+                      int (cs.str_len), cs.str);
+    else
+        rw_asnprintf (pbuf, pbufsize,
+                      "std::basic_string<%s, %s<%1$s>, %s<%1$s>>(%{#*s})"
+                      ".append", pfid->cname_, pfid->tname_, pfid->aname_, 
+                      int (cs.str_len), cs.str);
+
+    const bool self = 0 == cs.src;
 
+    switch (which)
     {
-        //String t1("Long test string");
-        String t1(Lit<T>::longTestString);
-        t1 = Lit<T>::a[0];
-    
-        // Assigning character over long char string
-        rw_assert ((t1 == Lit<T>::a), 0, __LINE__, "B23");
+    case append_ptr:
+        rw_asnprintf (pbuf, pbufsize, 
+                      "%{+} (%{?}%{#*s}%{;}%{?}this->c_str ()%{;})",
+                      !self, int (cs.src_len), cs.src, self);
+        break;
+
+    case append_str:
+        rw_asnprintf (pbuf, pbufsize, 
+                      "%{+} (%{?}string (%{#*s})%{;}%{?}*this%{;})",
+                      !self, int (cs.src_len), cs.src, self);
+        break;
+
+    case append_ptr_size:
+        rw_asnprintf (pbuf, pbufsize, "%{+} ("
+                      "%{?}%{#*s}%{;}%{?}this->c_str ()%{;}, %zu)", 
+                      !self, int (cs.src_len), cs.src, self, cs.count);
+        break;
+
+    case append_str_off_size:
+        rw_asnprintf (pbuf, pbufsize, "%{+} ("
+                      "%{?}string (%{#*s})%{;}%{?}*this%{;}, %zu, %zu)",
+                      !self, int (cs.src_len), cs.src, 
+                      self, cs.pos, cs.count);
+        break;
+
+    case append_size_val:
+        rw_asnprintf (pbuf, pbufsize, 
+                      "%{+} (%zu, %#c)", cs.count, cs.ch);
+        break;
+
+    case append_range:
+        rw_asnprintf (pbuf, pbufsize, "%{+} ("
+                      "%{?}%{#*s}%{;}%{?}*this%{;}.begin + %zu, "
+                      "%{?}%{#*s}%{;}%{?}*this%{;}.begin + %zu)", 
+                      !self, int (cs.src_len), cs.src,
+                      self, cs.pos, !self, int (cs.src_len), cs.src, 
+                      self, cs.pos + cs.count);
+        break;
+    }
+}
+
+/**************************************************************************/
+
+void test_append (const MemFun *pfid, const ATags which, 
+                  const TestCase& cs, bool exc_safety_test)
+{
+    char* buf = 0;
+    std::size_t buf_sz = 0;
+    get_append_format (&buf, &buf_sz, pfid, which, cs); 
+
+#undef TEST
+#define TEST(charT, Traits)	                                           \
+    !exc_safety_test ?                                                 \
+        test_append (charT(), (Traits*)0, which, cs, buf)              \
+      : test_append_exceptions (charT(), (Traits*)0, which, cs, buf)
+
+    if (MemFun:: DefaultTraits == pfid->tid_) {
+        if (MemFun::Char == pfid->cid_)
+            TEST (char, std::char_traits<char>);
+
+#ifndef _RWSTD_NO_WCHAR_T
+    else
+        TEST (wchar_t, std::char_traits<wchar_t>);
+#endif   // _RWSTD_NO_WCHAR_T
 
-        // Returns correct length
-        rw_assert ((t1.length() == 1), 0, __LINE__, "B24");
     }
+    else {
+       if (MemFun::Char == pfid->cid_)
+           TEST (char, UserTraits<char>);
 
-    {
-        //String t1("Really, really long test string that seems to never stop");
-        String t1(Lit<T>::reallyLong);
-        t1 = Lit<T>::a[0];
-    
-        // Assigning character over really long char string
-        rw_assert ((t1 == Lit<T>::a), 0, __LINE__, "B25");
-    
-        // Returns correct length
-        rw_assert ((t1.length() == 1), 0, __LINE__, "B26");
+#ifndef _RWSTD_NO_WCHAR_T
+       else if (MemFun::WChar == pfid->cid_)
+           TEST (wchar_t, UserTraits<wchar_t>);
+#endif   // _RWSTD_NO_WCHAR_T
+
+       else
+           TEST (UserChar, UserTraits<UserChar>);
+    }
+
+    free (buf);
+}
+
+/**************************************************************************/
+
+static void
+test_append (const MemFun *pfid, const FunctionTag& ftag)
+{
+    rw_info (0, 0, 0, "std::basic_string<%s, %s<%1$s>, %s<%1$s>>::%s",
+             pfid->cname_, pfid->tname_, pfid->aname_, ftag.str_hdr);
+
+    if (rw_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_, ftag.str_hdr);
+
+#ifdef _RWSTD_NO_REPLACEABLE_NEW_DELETE
+
+    else
+        rw_warn (0, 0, __LINE__,
+                 "%s exception safety test: no replacable new and delete",
+                 ftag.str_hdr);
+
+#endif  //_RWSTD_NO_REPLACEABLE_NEW_DELETE
+
+    for (std::size_t i = 0; i != ftag.n_cases; ++i) {
+
+        if (!rw_enabled (ftag.t_cases[i].line)) {
+            rw_note (0, 0, __LINE__, 
+                     "test on line %d disabled", ftag.t_cases[i].line);
+            continue;
+        }
+
+        // do not exercise exceptions if they were disabled
+        if (0 != rw_opt_no_exceptions && 0 != ftag.t_cases[i].bthrow)
+            continue;
+
+        // do not exercise exception safety if they were disabled
+        if (0 != rw_opt_no_exception_safety && -1 == ftag.t_cases[i].bthrow)
+            continue;
+
+        test_append (pfid, ftag.a_tag, ftag.t_cases[i], 
+                     -1 == ftag.t_cases[i].bthrow);
+    }
+}
+
+
+/**************************************************************************/
+
+static void
+run_test (const MemFun *pfid)
+{
+    if (MemFun::UserTraits == pfid->tid_ && rw_opt_no_user_traits) {
+        rw_note (1 < rw_opt_no_user_traits++, 0, 0,
+                 "user defined traits test disabled");
+    }
+    else if (MemFun::DefaultTraits == pfid->tid_  && rw_opt_no_char_traits) {
+        rw_note (1 < rw_opt_no_char_traits++, 0, 0,
+                 "char_traits test disabled");
+    }
+    else {
+
+        if (rw_opt_no_exceptions)
+            rw_note (1 < rw_opt_no_exceptions++, 0, 0,
+                     "string::append exceptions tests disabled"); 
+
+        static const std::size_t ftags = 
+            sizeof function_tags / sizeof *function_tags;
+
+        for (std::size_t i = 0; i < ftags; i++) {
+
+            if (*function_tags[i].p_opt) 
+                rw_note (0, 0, 0, 
+                         "std::basic_string<%s, %s<%1$s>, %s<%1$s>>::"
+                         "%s test disabled", pfid->cname_, pfid->tname_, 
+                         pfid->aname_, function_tags[i].str_hdr);
+            else
+                test_append (pfid, function_tags[i]);
+        }
     }
 }
 
@@ -276,22 +1032,58 @@
 
 int run_test (int, char*[])
 {
-    if (rw_enabled ("char"))
-        test_append (char (), "char");
+    if ('\0' == LSTR [0]) {
+        // initialize LSTR
+        for (std::size_t i = 0; i != sizeof LSTR - 1; ++i)
+            LSTR [i] = 'x';
+    }
+
+    if (rw_enabled ("char")) {
+
+        MemFun fid (MemFun::Char, "char", MemFun::DefaultTraits, 0);
+
+        fid.tname_ = "char_traits";
+
+        run_test (&fid);
+
+        fid.tid_   = MemFun::UserTraits;
+        fid.tname_ = "UserTraits";
+
+        run_test (&fid);
+    }
     else
-        rw_note (0, __FILE__, __LINE__, "char test disabled");
+        rw_note (0, 0, 0, "string::append char tests disabled");
 
-#ifndef _RWSTD_NO_WCHAR_T
+    if (rw_enabled ("wchar_t")) {
+
+        MemFun fid (MemFun::WChar, "wchar_t", MemFun::DefaultTraits, 0);
+
+        fid.tname_ = "char_traits";
+
+        run_test (&fid);
+
+        fid.tid_   = MemFun::UserTraits;
+        fid.tname_ = "UserTraits";
 
-    if (rw_enabled ("wchar_t"))
-        test_append (wchar_t (), "wchar_t");
+        run_test (&fid);
+    }
     else
-        rw_note (0, __FILE__, __LINE__, "wchar_t test disabled");
+        rw_note (0, 0, 0, "string::append wchar tests disabled");
 
-#endif   // _RWSTD_NO_WCHAR_T
+    if (rw_opt_no_user_chars) {
+        rw_note (0, 0, 0, "user defined chars test disabled");
+    }
+    else {
+        MemFun fid (MemFun::UChar, "UserChar", MemFun::UserTraits, 0);
+        fid.tname_ = "UserTraits";
+        run_test (&fid);
+    }
 
-    return 0;
+    // silence a bogus EDG eccp remark #550-D:
+    // variable "exp_exceptions" was set but never used
+    _RWSTD_UNUSED (exp_exceptions);
 
+    return 0;
 }
 
 /**************************************************************************/
@@ -301,5 +1093,30 @@
     return rw_test (argc, argv, __FILE__,
                     "lib.string.append",
                     0 /* no comment */, run_test,
-                    0 /* co command line options */);
+                    "|-no-char_traits# "
+                    "|-no-user_traits# "
+                    "|-no-user_chars# "
+                    "|-no-exceptions# "
+                    "|-no-exception-safety# "
+
+                    "|-no-append-ptr# "
+                    "|-no-append-str# "
+                    "|-no-append-ptr-size# "
+                    "|-no-append-str-off-size# "
+                    "|-no-append-size-val# "
+                    "|-no-append-range#",
+
+                    &rw_opt_no_char_traits,
+                    &rw_opt_no_user_traits,
+                    &rw_opt_no_user_chars,
+                    &rw_opt_no_exceptions,
+                    &rw_opt_no_exception_safety,
+
+                    &rw_opt_no_append_ptr,
+                    &rw_opt_no_append_str,
+                    &rw_opt_no_append_ptr_size,
+                    &rw_opt_no_append_str_off_size,
+                    &rw_opt_no_append_size_val,
+                    &rw_opt_no_append_range);
 }
+



Mime
View raw message