Attached is a proposed patch for fix the bugs STDCXX-268 and STDCXX-331.

  Actually this patch fixes the bug STDCXX-331, but since the std::list
constructor uses insert() method so the bug STDCXX-268 is fixed automatically.

  ChangeLog:
  STDCXX-268
  STDCXX-331
  * list (_RWSTD_LIST_SAFE_INSERT_RANGE): New macro for exception
  safe inserting the range into the list.
  (_C_insert): Used _RWSTD_LIST_SAFE_INSERT_RANGE macro.
  (_C_insert): Added try/catch with removing the inserted elements
  if exception was thrown.

Farid.
Index: list
===================================================================
--- list        (revision 504581)
+++ list        (working copy)
@@ -344,6 +344,22 @@
 
 #endif // _RWSTD_NO_LIST_NODE_BUFFER
 
+#  define _RWSTD_LIST_SAFE_INSERT_RANGE(__it, __first, __last)  \
+    _RWSTD_ASSERT_RANGE (begin (), __it);                       \
+    _RWSTD_ASSERT_RANGE (__first, __last);                      \
+    size_type __n = 0;                                          \
+    _TRY {                                                      \
+        for ( ; !(__first == __last); ++__first, ++__n)         \
+            insert (__it, *__first);                            \
+    } _CATCH (...) {                                            \
+        for ( ; __n; --__n) {                                   \
+            iterator __prev = __it;                             \
+            erase (--__prev);                                   \
+        }                                                       \
+        _RETHROW;                                               \
+    } typedef void dummy_t
+
+
     // here and only here is _C_node initialized
     void _C_init (bool __empty_list = false) {
         _C_node = _C_get_node (__empty_list);
@@ -577,23 +593,15 @@
     void _C_insert (const iterator &__it,
                     _InputIterator __first, _InputIterator __last, 
                     bidirectional_iterator_tag) {
-        _RWSTD_ASSERT_RANGE (begin (), __it);
-        _RWSTD_ASSERT_RANGE (__first, __last);
-
-        for ( ; !(__first == __last); ++__first)
-            insert (__it, *__first); 
+        _RWSTD_LIST_SAFE_INSERT_RANGE (__it, __first, __last);
     }
 
     // handles input iterators
     template <class _InputIterator>
-    void _C_insert (iterator __it,
+    void _C_insert (const iterator &__it,
                     _InputIterator __first, _InputIterator __last, 
                     input_iterator_tag) {
-        _RWSTD_ASSERT_RANGE (begin (), __it);
-        _RWSTD_ASSERT_RANGE (__first, __last);
-
-        for ( ; !(__first == __last); ++__first, ++__it)
-            __it = insert (__it, *__first); 
+        _RWSTD_LIST_SAFE_INSERT_RANGE (__it, __first, __last);
     }
  
     // handles nonintegral types
@@ -643,20 +651,12 @@
     }
 
     void insert (iterator __it, const_pointer __first, const_pointer __last) {
-        _RWSTD_ASSERT_RANGE (begin (), __it);
-        _RWSTD_ASSERT_RANGE (__first, __last);
-
-        for (; !(__first == __last); ++__first)
-            insert (__it, *__first);
+        _RWSTD_LIST_SAFE_INSERT_RANGE (__it, __first, __last);
     }
 
     void insert (iterator __it,
                  const_iterator __first, const_iterator __last) {
-        _RWSTD_ASSERT_RANGE (begin (), __it);
-        _RWSTD_ASSERT_RANGE (__first, __last);
-
-        for (; !(__first == __last); ++__first)
-            insert (__it, *__first);
+        _RWSTD_LIST_SAFE_INSERT_RANGE (__it, __first, __last);
     }
 
 #endif   // _RWSTD_NO_INLINE_MEMBER_TEMPLATES
@@ -706,8 +706,18 @@
     void _C_insert (iterator __it, size_type __n, const_reference __x) {
         _RWSTD_ASSERT_RANGE (begin (), __it);
 
-        while (__n--)
-            insert (__it, __x);
+        size_type __i = 0;
+
+        _TRY {
+            for ( ; __i < __n; ++__i)
+                insert (__it, __x);
+        } _CATCH (...) {
+            for ( ; __i; --__i) {
+                iterator __prev = __it;
+                erase (--__prev);
+            }
+            _RETHROW;
+        }
     }
 
 public:

Reply via email to