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: