You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@stdcxx.apache.org by an...@apache.org on 2006/04/07 16:56:06 UTC

svn commit: r392308 - /incubator/stdcxx/trunk/tests/strings/21.string.insert.cpp

Author: antonp
Date: Fri Apr  7 07:55:51 2006
New Revision: 392308

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

	* 21.string.insert.cpp (rw_opt_no_exception_safety): New option to
	disable the exception safety tests.
	(off_test_cases, off_str_test_cases, ...): New test cases were 
	added include cases for exception safety tests.
	(test_insert_exceptions): New function to exrcise exception safety.
	(test_insert): Modified to include exception safety tests, added
	exc_safety_test parameter to indicate the test case type.
	(main): added support for new option  no-exception-safety.


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

Modified: incubator/stdcxx/trunk/tests/strings/21.string.insert.cpp
URL: http://svn.apache.org/viewcvs/incubator/stdcxx/trunk/tests/strings/21.string.insert.cpp?rev=392308&r1=392307&r2=392308&view=diff
==============================================================================
--- incubator/stdcxx/trunk/tests/strings/21.string.insert.cpp (original)
+++ incubator/stdcxx/trunk/tests/strings/21.string.insert.cpp Fri Apr  7 07:55:51 2006
@@ -25,6 +25,7 @@
  * 
  **************************************************************************/
 
+#include <memory>       // for placement operator new()
 #include <string>       // for string
 #include <cstdlib>      // for free(), size_t
 #include <stdexcept>    // for out_of_range, length_error
@@ -36,6 +37,12 @@
 #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
+
 /**************************************************************************/
 
 struct MemFun
@@ -123,6 +130,7 @@
 
 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_insert_off_ptr;           // for --no-insert-off-ptr
 static int rw_opt_no_insert_off_str;           // for --no-insert-off-str
@@ -151,7 +159,8 @@
     //    |            |  |           |        +---- exception info 
     //    |            |  |           |        |         0 - no exception        
     //    |            |  |           |        |         1 - out_of_range        
-    //    |            |  |           |        |         2 - length_error        
+    //    |            |  |           |        |         2 - length_error  
+    //    |            |  |           |        |        -1 - exc. safety
     //    |            |  |           |        |                       
     //    |            |  |           |        +------------+             
     //    V            V  V           V                     V
@@ -181,6 +190,7 @@
     TEST ("a\0b\0\0c", 2, "e\0e",     "a\0eb\0\0c",         0),
     TEST ("a\0bc\0\0", 6, "e\0e",     "a\0bc\0\0e",         0),
 
+    TEST ("",          0, 0,          "",                   0),
     TEST ("abc",       0, 0,          "abcabc",             0),
     TEST ("abc",       2, 0,          "ababcc",             0),
     TEST ("a\0bc\0\0", 0, 0,          "aa\0bc\0\0",         0),
@@ -195,6 +205,8 @@
     TEST ("a",         2, "",         "",                   1),
     TEST (LSTR,LLEN + 10, "",         "",                   1),
 
+    TEST ("",          0, LSTR,       LSTR,                -1),
+
 #endif   // _RWSTD_NO_EXCEPTIONS
 
     TEST ("last",      4, "test",     "lasttest",           0)
@@ -218,7 +230,8 @@
     //    |            |  |           |        +---- exception info 
     //    |            |  |           |        |         0 - no exception        
     //    |            |  |           |        |         1 - out_of_range        
-    //    |            |  |           |        |         2 - length_error        
+    //    |            |  |           |        |         2 - length_error  
+    //    |            |  |           |        |        -1 - exc. safety
     //    |            |  |           |        |                       
     //    |            |  |           |        +------------+             
     //    V            V  V           V                     V
@@ -262,6 +275,8 @@
     TEST ("a",         2, "",         "",                   1),
     TEST (LSTR,LLEN + 10, "",         "",                   1),
 
+    TEST ("",          0, LSTR,       LSTR,                -1),
+
 #endif   // _RWSTD_NO_EXCEPTIONS
 
     TEST ("last",      4, "test",     "lasttest",           0)
@@ -288,7 +303,8 @@
     //    |            |  |            |  |  |  +--- exception info  
     //    |            |  |            |  |  |  |       0 - no exception        
     //    |            |  |            |  |  |  |       1 - out_of_range        
-    //    |            |  |            |  |  |  |       2 - length_error        
+    //    |            |  |            |  |  |  |       2 - length_error   
+    //    |            |  |            |  |  |  |      -1 - exc. safety 
     //    |            |  |            |  |  |  |                         
     //    |            |  |            |  |  |  +----------------+             
     //    V            V  V            V  V  V                   V             
@@ -347,6 +363,8 @@
     TEST (LSTR,LLEN + 10, "",          0, 0,  "",                1),
     TEST ("",          0, LSTR,LLEN + 10, 0,  "",                2),
 
+    TEST (LSTR,        0, 0,           0, 0, 0,                 -1),
+
 #endif   // _RWSTD_NO_EXCEPTIONS
 
     TEST ("last",      4, "test",      0, 4,  "lasttest",        0)
@@ -371,7 +389,8 @@
     //    |            |  |            |  |     +--- exception info 
     //    |            |  |            |  |     |      0 - no exception        
     //    |            |  |            |  |     |      1 - out_of_range        
-    //    |            |  |            |  |     |      2 - length_error        
+    //    |            |  |            |  |     |      2 - length_error  
+    //    |            |  |            |  |     |     -1 - exc. safety 
     //    |            |  |            |  |     |                           
     //    |            |  |            |  |     +------------+             
     //    V            V  V            V  V                  V             
@@ -416,6 +435,8 @@
     TEST ("a",         2, "",          0,  "",               1),
     TEST (LSTR,LLEN + 10, "",          0,  "",               1),
 
+    TEST ("",          0, LSTR, LLEN - 1,  LSTR,            -1),
+
 #endif   // _RWSTD_NO_EXCEPTIONS
 
     TEST ("last",      4, "test",      4,  "lasttest",       0)
@@ -441,7 +462,8 @@
     //    |            |  |   |   |       +--------- exception info 
     //    |            |  |   |   |       |             0 - no exception        
     //    |            |  |   |   |       |             1 - out_of_range        
-    //    |            |  |   |   |       |             2 - length_error     
+    //    |            |  |   |   |       |             2 - length_error  
+    //    |            |  |   |   |       |            -1 - exc. safety
     //    |            |  |   |   |       |                         
     //    |            |  |   |   |       +-----------+             
     //    V            V  V   V   V                   V             
@@ -477,6 +499,12 @@
     TEST ("",          0, LLEN - 1, 'x', LSTR,        0),
     TEST (LSTR,        0, 0,        'x', LSTR,        0),
 
+#ifndef _RWSTD_NO_EXCEPTIONS
+
+    TEST ("",          0, LLEN - 1, 'x', LSTR,       -1),
+
+#endif   // _RWSTD_NO_EXCEPTIONS
+
     TEST ("last",      4, 4, 't',  "lasttttt",        0)
 };
 
@@ -499,6 +527,7 @@
     //    |            |    |   |               |       0 - no exception        
     //    |            |    |   |               |       1 - out_of_range        
     //    |            |    |   |               |       2 - length_error     
+    //    |            |    |   |               |      -1 - exc. safety 
     //    |            |    |   |               |                 
     //    |            |    |   |               |
     //    V            V    V   V               V  
@@ -521,6 +550,12 @@
     TEST ("\0ab\0\0c", 0, '\0', "\0\0ab\0\0c",  0),
     TEST ("a\0bc\0\0", 6,  'a', "a\0bc\0\0a",   0),
 
+#ifndef _RWSTD_NO_EXCEPTIONS
+
+    TEST (LSTR,        0,  'c', 0,             -1),
+
+#endif   // _RWSTD_NO_EXCEPTIONS
+
     TEST ("last",      4,  't', "lastt",        0)
 };
 
@@ -569,6 +604,149 @@
 
 /**************************************************************************/
 
+template <class charT, class Traits>
+void test_insert_exceptions (charT, Traits*,  
+                             const ITags     which,
+                             const TestCase &cs,
+                             const char     *insert_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 insertion
+    // 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 (insert_off_ptr == which) 
+                s_str.insert (cs.pos1, cs.src ? wsrc : s_str.c_str ());
+
+            else if (insert_off_str == which)
+                s_str.insert (cs.pos1, cs.src ? s_src : s_str);
+
+            else if (insert_off_ptr_size == which)
+                s_str.insert (cs.pos1, cs.src ? 
+                              wsrc : s_str.c_str (), cs.count);
+
+            else if (insert_off_str_off_size == which) 
+                s_str.insert (cs.pos1, cs.src ? 
+                              s_src : s_str, cs.pos2, cs.count);
+
+            else if (insert_off_size_val == which)
+                s_str.insert (cs.pos1, cs.count, 
+                              make_char ((char) cs.ch, (charT*)0));
+
+            else if (insert_size_val == which) {
+                StringIter it (s_str.begin () + cs.pos1);
+                s_str.insert (it, cs.count, make_char ((char) cs.ch, (charT*)0));
+            }
+
+            else if (insert_val == which) {
+                StringIter it (s_str.begin () + cs.pos1);
+                s_str.insert (it, make_char ((char) cs.ch, (charT*)0));
+            }
+
+            else if (insert_range == which) {
+                StringIter it (s_str.begin () + cs.pos1);
+                s_str.insert (it, 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__, insert_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__, insert_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__, insert_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 insert 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__, insert_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 <class charT, class Traits, class Iterator>
 void test_insert_range (charT* wstr,
                         charT* wsrc, 
@@ -881,15 +1059,18 @@
 
 /**************************************************************************/
 
-void test_insert (const MemFun *pfid, const ITags which, const TestCase& cs)
+void test_insert (const MemFun *pfid, const ITags which, 
+                  const TestCase& cs, bool exc_safety_test)
 {
     char* buf = 0;
     std::size_t buf_sz = 0;
     get_insert_format (&buf, &buf_sz, pfid, which, cs); 
 
 #undef TEST
-#define TEST(charT, Traits)	                                    \
-    test_insert (charT(), (Traits*)0, which, cs, buf)
+#define TEST(charT, Traits)	                                           \
+    !exc_safety_test ?                                                 \
+        test_insert (charT(), (Traits*)0, which, cs, buf)              \
+      : test_insert_exceptions (charT(), (Traits*)0, which, cs, buf)
 
     if (MemFun:: DefaultTraits == pfid->tid_) {
         if (MemFun::Char == pfid->cid_)
@@ -925,6 +1106,21 @@
     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)) {
@@ -937,7 +1133,12 @@
         if (0 != rw_opt_no_exceptions && 0 != ftag.t_cases[i].bthrow)
             continue;
 
-        test_insert (pfid, ftag.i_tag, ftag.t_cases[i]);
+        // do not exercise exception safety if they were disabled
+        if (0 != rw_opt_no_exception_safety && -1 == ftag.t_cases[i].bthrow)
+            continue;
+
+        test_insert (pfid, ftag.i_tag, ftag.t_cases[i], 
+                     -1 == ftag.t_cases[i].bthrow);
     }
 }
 
@@ -1046,6 +1247,8 @@
                     "|-no-user_traits# "
                     "|-no-user_chars# "
                     "|-no-exceptions# "
+                    "|-no-exception-safety# "
+
                     "|-no-insert-off-ptr# "
                     "|-no-insert-off-str# "
                     "|-no-insert-off-ptr-size# "
@@ -1054,10 +1257,13 @@
                     "|-no-insert-size-val# "
                     "|-no-insert-val# "
                     "|-no-insert-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_insert_off_ptr,
                     &rw_opt_no_insert_off_str,
                     &rw_opt_no_insert_off_ptr_size,