[libcxx] r257716 - Merging r257682:

Hans Wennborg via cfe-commits cfe-commits at lists.llvm.org
Wed Jan 13 15:53:40 PST 2016


Author: hans
Date: Wed Jan 13 17:53:40 2016
New Revision: 257716

URL: http://llvm.org/viewvc/llvm-project?rev=257716&view=rev
Log:
Merging r257682:
------------------------------------------------------------------------
r257682 | marshall | 2016-01-13 13:54:34 -0800 (Wed, 13 Jan 2016) | 1 line

Fix PR#25973 : 'basic_string::assign(InputIt, InputIt) doesn't provide the strong exception safety guarantee'. This turned out to be a pervasive problem in <string>, which required a fair amount of rework. Add in an optimization for when iterators provide noexcept increment/comparison/assignment/dereference (which covers many of the iterators in libc++). Reviewed as http://reviews.llvm.org/D15862
------------------------------------------------------------------------

Added:
    libcxx/branches/release_38/test/libcxx/iterators/
      - copied from r257682, libcxx/trunk/test/libcxx/iterators/
    libcxx/branches/release_38/test/libcxx/strings/
      - copied from r257682, libcxx/trunk/test/libcxx/strings/
Modified:
    libcxx/branches/release_38/   (props changed)
    libcxx/branches/release_38/include/algorithm
    libcxx/branches/release_38/include/iterator
    libcxx/branches/release_38/include/string
    libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_append/initializer_list.pass.cpp
    libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_append/iterator.pass.cpp
    libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_append/pointer.pass.cpp
    libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_append/pointer_size.pass.cpp
    libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_append/push_back.pass.cpp
    libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_append/size_char.pass.cpp
    libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_append/string.pass.cpp
    libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_append/string_size_size.pass.cpp
    libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_assign/initializer_list.pass.cpp
    libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_assign/iterator.pass.cpp
    libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_assign/pointer.pass.cpp
    libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_assign/pointer_size.pass.cpp
    libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_assign/rv_string.pass.cpp
    libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_assign/size_char.pass.cpp
    libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_assign/string.pass.cpp
    libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_assign/string_size_size.pass.cpp
    libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_insert/iter_char.pass.cpp
    libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_insert/iter_initializer_list.pass.cpp
    libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_insert/iter_iter_iter.pass.cpp
    libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_insert/iter_size_char.pass.cpp
    libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_insert/size_pointer.pass.cpp
    libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_insert/size_pointer_size.pass.cpp
    libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_insert/size_size_char.pass.cpp
    libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_insert/size_string.pass.cpp
    libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_insert/size_string_size_size.pass.cpp
    libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_initializer_list.pass.cpp
    libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_iter_iter.pass.cpp
    libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_pointer.pass.cpp
    libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_pointer_size.pass.cpp
    libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_size_char.pass.cpp
    libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_string.pass.cpp
    libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_replace/size_size_pointer.pass.cpp
    libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_replace/size_size_pointer_size.pass.cpp
    libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_replace/size_size_size_char.pass.cpp
    libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_replace/size_size_string.pass.cpp
    libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_replace/size_size_string_size_size.pass.cpp
    libcxx/branches/release_38/test/support/test_iterators.h

Propchange: libcxx/branches/release_38/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Wed Jan 13 17:53:40 2016
@@ -1 +1,2 @@
 /libcxx/branches/apple:136569-137939
+/libcxx/trunk:257682

Modified: libcxx/branches/release_38/include/algorithm
URL: http://llvm.org/viewvc/llvm-project/libcxx/branches/release_38/include/algorithm?rev=257716&r1=257715&r2=257716&view=diff
==============================================================================
--- libcxx/branches/release_38/include/algorithm (original)
+++ libcxx/branches/release_38/include/algorithm Wed Jan 13 17:53:40 2016
@@ -1687,25 +1687,6 @@ search_n(_ForwardIterator __first, _Forw
 }
 
 // copy
-
-template <class _Iter>
-struct __libcpp_is_trivial_iterator
-{
-    static const bool value = is_pointer<_Iter>::value;
-};
-
-template <class _Iter>
-struct __libcpp_is_trivial_iterator<move_iterator<_Iter> >
-{
-    static const bool value = is_pointer<_Iter>::value;
-};
-
-template <class _Iter>
-struct __libcpp_is_trivial_iterator<__wrap_iter<_Iter> >
-{
-    static const bool value = is_pointer<_Iter>::value;
-};
-
 template <class _Iter>
 inline _LIBCPP_INLINE_VISIBILITY
 _Iter

Modified: libcxx/branches/release_38/include/iterator
URL: http://llvm.org/viewvc/llvm-project/libcxx/branches/release_38/include/iterator?rev=257716&r1=257715&r2=257716&view=diff
==============================================================================
--- libcxx/branches/release_38/include/iterator (original)
+++ libcxx/branches/release_38/include/iterator Wed Jan 13 17:53:40 2016
@@ -437,6 +437,12 @@ struct __is_bidirectional_iterator : pub
 template <class _Tp>
 struct __is_random_access_iterator : public __has_iterator_category_convertible_to<_Tp, random_access_iterator_tag> {};
 
+template <class _Tp>
+struct __is_exactly_input_iterator
+    : public integral_constant<bool, 
+    	 __has_iterator_category_convertible_to<_Tp, input_iterator_tag>::value && 
+    	!__has_iterator_category_convertible_to<_Tp, forward_iterator_tag>::value> {};
+
 template<class _Category, class _Tp, class _Distance = ptrdiff_t,
          class _Pointer = _Tp*, class _Reference = _Tp&>
 struct _LIBCPP_TYPE_VIS_ONLY iterator
@@ -1404,6 +1410,23 @@ operator+(typename __wrap_iter<_Iter>::d
     return __x;
 }
 
+template <class _Iter>
+struct __libcpp_is_trivial_iterator
+	: public _LIBCPP_BOOL_CONSTANT(is_pointer<_Iter>::value) {};
+	
+template <class _Iter>
+struct __libcpp_is_trivial_iterator<move_iterator<_Iter> >
+	: public _LIBCPP_BOOL_CONSTANT(__libcpp_is_trivial_iterator<_Iter>::value) {};
+
+template <class _Iter>
+struct __libcpp_is_trivial_iterator<reverse_iterator<_Iter> >
+	: public _LIBCPP_BOOL_CONSTANT(__libcpp_is_trivial_iterator<_Iter>::value) {};
+
+template <class _Iter>
+struct __libcpp_is_trivial_iterator<__wrap_iter<_Iter> >
+	: public _LIBCPP_BOOL_CONSTANT(__libcpp_is_trivial_iterator<_Iter>::value) {};
+
+
 template <class _Tp, size_t _Np>
 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 _Tp*

Modified: libcxx/branches/release_38/include/string
URL: http://llvm.org/viewvc/llvm-project/libcxx/branches/release_38/include/string?rev=257716&r1=257715&r2=257716&view=diff
==============================================================================
--- libcxx/branches/release_38/include/string (original)
+++ libcxx/branches/release_38/include/string Wed Jan 13 17:53:40 2016
@@ -1201,6 +1201,30 @@ _LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TY
 #pragma warning( pop )
 #endif // _LIBCPP_MSVC
 
+#ifdef _LIBCPP_NO_EXCEPTIONS
+template <class _Iter>
+struct __libcpp_string_gets_noexcept_iterator_impl : public true_type {};
+#elif defined(_LIBCPP_HAS_NO_NOEXCEPT)
+template <class _Iter>
+struct __libcpp_string_gets_noexcept_iterator_impl : public false_type {};
+#else
+template <class _Iter, bool = __is_forward_iterator<_Iter>::value>
+struct __libcpp_string_gets_noexcept_iterator_impl : public _LIBCPP_BOOL_CONSTANT((
+    noexcept(++(declval<_Iter&>())) && 
+    is_nothrow_assignable<_Iter&, _Iter>::value && 
+    noexcept(declval<_Iter>() == declval<_Iter>()) && 
+    noexcept(*declval<_Iter>())
+)) {};
+
+template <class _Iter> 
+struct __libcpp_string_gets_noexcept_iterator_impl<_Iter, false> : public false_type {};
+#endif
+
+
+template <class _Iter>
+struct __libcpp_string_gets_noexcept_iterator
+    : public _LIBCPP_BOOL_CONSTANT(__libcpp_is_trivial_iterator<_Iter>::value || __libcpp_string_gets_noexcept_iterator_impl<_Iter>::value) {};
+
 #ifdef _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT
 
 template <class _CharT, size_t = sizeof(_CharT)>
@@ -1495,15 +1519,16 @@ public:
     template<class _InputIterator>
         typename enable_if
         <
-             __is_input_iterator  <_InputIterator>::value &&
-            !__is_forward_iterator<_InputIterator>::value,
+            __is_exactly_input_iterator<_InputIterator>::value
+                || !__libcpp_string_gets_noexcept_iterator<_InputIterator>::value,
             basic_string&
         >::type
         append(_InputIterator __first, _InputIterator __last);
     template<class _ForwardIterator>
         typename enable_if
         <
-            __is_forward_iterator<_ForwardIterator>::value,
+            __is_forward_iterator<_ForwardIterator>::value
+                && __libcpp_string_gets_noexcept_iterator<_ForwardIterator>::value,
             basic_string&
         >::type
         append(_ForwardIterator __first, _ForwardIterator __last);
@@ -1535,15 +1560,16 @@ public:
     template<class _InputIterator>
         typename enable_if
         <
-             __is_input_iterator  <_InputIterator>::value &&
-            !__is_forward_iterator<_InputIterator>::value,
+           __is_exactly_input_iterator<_InputIterator>::value
+                || !__libcpp_string_gets_noexcept_iterator<_InputIterator>::value,
             basic_string&
         >::type
         assign(_InputIterator __first, _InputIterator __last);
     template<class _ForwardIterator>
         typename enable_if
         <
-            __is_forward_iterator<_ForwardIterator>::value,
+            __is_forward_iterator<_ForwardIterator>::value
+                 && __libcpp_string_gets_noexcept_iterator<_ForwardIterator>::value,
             basic_string&
         >::type
         assign(_ForwardIterator __first, _ForwardIterator __last);
@@ -1564,15 +1590,16 @@ public:
     template<class _InputIterator>
         typename enable_if
         <
-             __is_input_iterator  <_InputIterator>::value &&
-            !__is_forward_iterator<_InputIterator>::value,
+           __is_exactly_input_iterator<_InputIterator>::value
+                || !__libcpp_string_gets_noexcept_iterator<_InputIterator>::value,
             iterator
         >::type
         insert(const_iterator __pos, _InputIterator __first, _InputIterator __last);
     template<class _ForwardIterator>
         typename enable_if
         <
-            __is_forward_iterator<_ForwardIterator>::value,
+            __is_forward_iterator<_ForwardIterator>::value
+                 && __libcpp_string_gets_noexcept_iterator<_ForwardIterator>::value,
             iterator
         >::type
         insert(const_iterator __pos, _ForwardIterator __first, _ForwardIterator __last);
@@ -1817,8 +1844,7 @@ private:
     template <class _InputIterator>
     typename enable_if
     <
-         __is_input_iterator  <_InputIterator>::value &&
-        !__is_forward_iterator<_InputIterator>::value,
+        __is_exactly_input_iterator<_InputIterator>::value,
         void
     >::type
     __init(_InputIterator __first, _InputIterator __last);
@@ -2195,8 +2221,7 @@ template <class _CharT, class _Traits, c
 template <class _InputIterator>
 typename enable_if
 <
-     __is_input_iterator  <_InputIterator>::value &&
-    !__is_forward_iterator<_InputIterator>::value,
+    __is_exactly_input_iterator<_InputIterator>::value,
     void
 >::type
 basic_string<_CharT, _Traits, _Allocator>::__init(_InputIterator __first, _InputIterator __last)
@@ -2494,15 +2519,14 @@ template <class _CharT, class _Traits, c
 template<class _InputIterator>
 typename enable_if
 <
-     __is_input_iterator  <_InputIterator>::value &&
-    !__is_forward_iterator<_InputIterator>::value,
+     __is_exactly_input_iterator <_InputIterator>::value
+          || !__libcpp_string_gets_noexcept_iterator<_InputIterator>::value,
     basic_string<_CharT, _Traits, _Allocator>&
 >::type
 basic_string<_CharT, _Traits, _Allocator>::assign(_InputIterator __first, _InputIterator __last)
 {
-    clear();
-    for (; __first != __last; ++__first)
-        push_back(*__first);
+    basic_string __temp(__first, __last, __alloc());
+    assign(__temp.data(), __temp.size());
     return *this;
 }
 
@@ -2510,7 +2534,8 @@ template <class _CharT, class _Traits, c
 template<class _ForwardIterator>
 typename enable_if
 <
-    __is_forward_iterator<_ForwardIterator>::value,
+    __is_forward_iterator<_ForwardIterator>::value
+         && __libcpp_string_gets_noexcept_iterator<_ForwardIterator>::value,
     basic_string<_CharT, _Traits, _Allocator>&
 >::type
 basic_string<_CharT, _Traits, _Allocator>::assign(_ForwardIterator __first, _ForwardIterator __last)
@@ -2643,14 +2668,14 @@ template <class _CharT, class _Traits, c
 template<class _InputIterator>
 typename enable_if
 <
-     __is_input_iterator  <_InputIterator>::value &&
-    !__is_forward_iterator<_InputIterator>::value,
+    __is_exactly_input_iterator<_InputIterator>::value
+             || !__libcpp_string_gets_noexcept_iterator<_InputIterator>::value,
     basic_string<_CharT, _Traits, _Allocator>&
 >::type
 basic_string<_CharT, _Traits, _Allocator>::append(_InputIterator __first, _InputIterator __last)
 {
-    for (; __first != __last; ++__first)
-        push_back(*__first);
+	basic_string __temp (__first, __last, __alloc());
+	append(__temp.data(), __temp.size());
     return *this;
 }
 
@@ -2658,7 +2683,8 @@ template <class _CharT, class _Traits, c
 template<class _ForwardIterator>
 typename enable_if
 <
-    __is_forward_iterator<_ForwardIterator>::value,
+    __is_forward_iterator<_ForwardIterator>::value
+          && __libcpp_string_gets_noexcept_iterator<_ForwardIterator>::value,
     basic_string<_CharT, _Traits, _Allocator>&
 >::type
 basic_string<_CharT, _Traits, _Allocator>::append(_ForwardIterator __first, _ForwardIterator __last)
@@ -2774,9 +2800,9 @@ template <class _CharT, class _Traits, c
 template<class _InputIterator>
 typename enable_if
 <
-     __is_input_iterator  <_InputIterator>::value &&
-    !__is_forward_iterator<_InputIterator>::value,
-    typename basic_string<_CharT, _Traits, _Allocator>::iterator
+   __is_exactly_input_iterator<_InputIterator>::value
+        || !__libcpp_string_gets_noexcept_iterator<_InputIterator>::value,
+   typename basic_string<_CharT, _Traits, _Allocator>::iterator
 >::type
 basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, _InputIterator __first, _InputIterator __last)
 {
@@ -2785,24 +2811,16 @@ basic_string<_CharT, _Traits, _Allocator
         "string::insert(iterator, range) called with an iterator not"
         " referring to this string");
 #endif
-    size_type __old_sz = size();
-    difference_type __ip = __pos - begin();
-    for (; __first != __last; ++__first)
-        push_back(*__first);
-    pointer __p = __get_pointer();
-    _VSTD::rotate(__p + __ip, __p + __old_sz, __p + size());
-#if _LIBCPP_DEBUG_LEVEL >= 2
-    return iterator(this, __p + __ip);
-#else
-    return iterator(__p + __ip);
-#endif
+    basic_string __temp(__first, __last, __alloc());
+    return insert(__pos, __temp.data(), __temp.data() + __temp.size());
 }
 
 template <class _CharT, class _Traits, class _Allocator>
 template<class _ForwardIterator>
 typename enable_if
 <
-    __is_forward_iterator<_ForwardIterator>::value,
+    __is_forward_iterator<_ForwardIterator>::value
+        && __libcpp_string_gets_noexcept_iterator<_ForwardIterator>::value,
     typename basic_string<_CharT, _Traits, _Allocator>::iterator
 >::type
 basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, _ForwardIterator __first, _ForwardIterator __last)
@@ -3005,22 +3023,8 @@ typename enable_if
 basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_iterator __i2,
                                                    _InputIterator __j1, _InputIterator __j2)
 {
-    for (; true; ++__i1, ++__j1)
-    {
-        if (__i1 == __i2)
-        {
-            if (__j1 != __j2)
-                insert(__i1, __j1, __j2);
-            break;
-        }
-        if (__j1 == __j2)
-        {
-            erase(__i1, __i2);
-            break;
-        }
-        traits_type::assign(const_cast<value_type&>(*__i1), *__j1);
-    }
-    return *this;
+    basic_string __temp(__j1, __j2, __alloc());
+    return this->replace(__i1, __i2, __temp);
 }
 
 template <class _CharT, class _Traits, class _Allocator>

Modified: libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_append/initializer_list.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_append/initializer_list.pass.cpp?rev=257716&r1=257715&r2=257716&view=diff
==============================================================================
--- libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_append/initializer_list.pass.cpp (original)
+++ libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_append/initializer_list.pass.cpp Wed Jan 13 17:53:40 2016
@@ -24,7 +24,7 @@ int main()
         s.append({'a', 'b', 'c'});
         assert(s == "123abc");
     }
-#if __cplusplus >= 201103L
+#if TEST_STD_VER >= 11
     {
         typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
         S s("123");

Modified: libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_append/iterator.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_append/iterator.pass.cpp?rev=257716&r1=257715&r2=257716&view=diff
==============================================================================
--- libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_append/iterator.pass.cpp (original)
+++ libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_append/iterator.pass.cpp Wed Jan 13 17:53:40 2016
@@ -15,7 +15,7 @@
 #include <string>
 #include <cassert>
 
-#include "../../input_iterator.h"
+#include "test_iterators.h"
 #include "min_allocator.h"
 
 template <class S, class It>
@@ -27,6 +27,20 @@ test(S s, It first, It last, S expected)
     assert(s == expected);
 }
 
+template <class S, class It>
+void
+test_exceptions(S s, It first, It last)
+{
+	S aCopy = s;
+    try {
+    	s.append(first, last);
+    	assert(false);
+    	}
+    catch (...) {}
+    assert(s.__invariants());
+    assert(s == aCopy);
+}
+
 int main()
 {
     {
@@ -87,7 +101,7 @@ int main()
     test(S("12345678901234567890"), input_iterator<const char*>(s), input_iterator<const char*>(s+52),
          S("12345678901234567890""ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"));
     }
-#if __cplusplus >= 201103L
+#if TEST_STD_VER >= 11
     {
     typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
     const char* s = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
@@ -147,4 +161,17 @@ int main()
          S("12345678901234567890""ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"));
     }
 #endif
+	{ // test iterator operations that throw
+    typedef std::string S;
+    typedef ThrowingIterator<char> TIter;
+    typedef input_iterator<TIter> IIter;
+    const char* s = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+    test_exceptions(S(), IIter(TIter(s, s+10, 4, TIter::TAIncrement)), IIter());
+    test_exceptions(S(), IIter(TIter(s, s+10, 5, TIter::TADereference)), IIter());
+    test_exceptions(S(), IIter(TIter(s, s+10, 6, TIter::TAComparison)), IIter());
+
+    test_exceptions(S(), TIter(s, s+10, 4, TIter::TAIncrement), TIter());
+    test_exceptions(S(), TIter(s, s+10, 5, TIter::TADereference), TIter());
+    test_exceptions(S(), TIter(s, s+10, 6, TIter::TAComparison), TIter());
+	}
 }

Modified: libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_append/pointer.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_append/pointer.pass.cpp?rev=257716&r1=257715&r2=257716&view=diff
==============================================================================
--- libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_append/pointer.pass.cpp (original)
+++ libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_append/pointer.pass.cpp Wed Jan 13 17:53:40 2016
@@ -43,7 +43,7 @@ int main()
     test(S("12345678901234567890"), "12345678901234567890",
          S("1234567890123456789012345678901234567890"));
     }
-#if __cplusplus >= 201103L
+#if TEST_STD_VER >= 11
     {
     typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
     test(S(), "", S());

Modified: libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_append/pointer_size.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_append/pointer_size.pass.cpp?rev=257716&r1=257715&r2=257716&view=diff
==============================================================================
--- libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_append/pointer_size.pass.cpp (original)
+++ libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_append/pointer_size.pass.cpp Wed Jan 13 17:53:40 2016
@@ -48,7 +48,7 @@ int main()
     test(S("12345678901234567890"), "12345678901234567890", 20,
          S("1234567890123456789012345678901234567890"));
     }
-#if __cplusplus >= 201103L
+#if TEST_STD_VER >= 11
     {
     typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
     test(S(), "", 0, S());

Modified: libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_append/push_back.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_append/push_back.pass.cpp?rev=257716&r1=257715&r2=257716&view=diff
==============================================================================
--- libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_append/push_back.pass.cpp (original)
+++ libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_append/push_back.pass.cpp Wed Jan 13 17:53:40 2016
@@ -33,7 +33,7 @@ int main()
     test(S("12345"), 'a', S("12345a"));
     test(S("12345678901234567890"), 'a', S("12345678901234567890a"));
     }
-#if __cplusplus >= 201103L
+#if TEST_STD_VER >= 11
     {
     typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
     test(S(), 'a', S(1, 'a'));

Modified: libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_append/size_char.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_append/size_char.pass.cpp?rev=257716&r1=257715&r2=257716&view=diff
==============================================================================
--- libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_append/size_char.pass.cpp (original)
+++ libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_append/size_char.pass.cpp Wed Jan 13 17:53:40 2016
@@ -43,7 +43,7 @@ int main()
     test(S("12345678901234567890"), 1, 'a', S("12345678901234567890a"));
     test(S("12345678901234567890"), 10, 'a', S("12345678901234567890aaaaaaaaaa"));
     }
-#if __cplusplus >= 201103L
+#if TEST_STD_VER >= 11
     {
     typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
     test(S(), 0, 'a', S());

Modified: libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_append/string.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_append/string.pass.cpp?rev=257716&r1=257715&r2=257716&view=diff
==============================================================================
--- libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_append/string.pass.cpp (original)
+++ libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_append/string.pass.cpp Wed Jan 13 17:53:40 2016
@@ -51,7 +51,7 @@ int main()
     test(S("12345678901234567890"), S("12345678901234567890"),
          S("1234567890123456789012345678901234567890"));
     }
-#if __cplusplus >= 201103L
+#if TEST_STD_VER >= 11
     {
     typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
     test(S(), S(), S());

Modified: libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_append/string_size_size.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_append/string_size_size.pass.cpp?rev=257716&r1=257715&r2=257716&view=diff
==============================================================================
--- libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_append/string_size_size.pass.cpp (original)
+++ libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_append/string_size_size.pass.cpp Wed Jan 13 17:53:40 2016
@@ -80,7 +80,7 @@ int main()
     test(S("12345678901234567890"), S("12345678901234567890"), 5, 10,
          S("123456789012345678906789012345"));
     }
-#if __cplusplus >= 201103L
+#if TEST_STD_VER >= 11
     {
     typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
     test(S(), S(), 0, 0, S());

Modified: libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_assign/initializer_list.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_assign/initializer_list.pass.cpp?rev=257716&r1=257715&r2=257716&view=diff
==============================================================================
--- libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_assign/initializer_list.pass.cpp (original)
+++ libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_assign/initializer_list.pass.cpp Wed Jan 13 17:53:40 2016
@@ -24,7 +24,7 @@ int main()
         s.assign({'a', 'b', 'c'});
         assert(s == "abc");
     }
-#if __cplusplus >= 201103L
+#if TEST_STD_VER >= 11
     {
         typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
         S s("123");

Modified: libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_assign/iterator.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_assign/iterator.pass.cpp?rev=257716&r1=257715&r2=257716&view=diff
==============================================================================
--- libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_assign/iterator.pass.cpp (original)
+++ libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_assign/iterator.pass.cpp Wed Jan 13 17:53:40 2016
@@ -15,7 +15,7 @@
 #include <string>
 #include <cassert>
 
-#include "../../input_iterator.h"
+#include "test_iterators.h"
 #include "min_allocator.h"
 
 template <class S, class It>
@@ -27,6 +27,20 @@ test(S s, It first, It last, S expected)
     assert(s == expected);
 }
 
+template <class S, class It>
+void
+test_exceptions(S s, It first, It last)
+{
+	S aCopy = s;
+    try {
+   	    s.assign(first, last);
+    	assert(false);
+    	}
+    catch (...) {}
+    assert(s.__invariants());
+    assert(s == aCopy);
+}
+
 int main()
 {
     {
@@ -147,4 +161,17 @@ int main()
          S("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"));
     }
 #endif
+	{ // test iterator operations that throw
+    typedef std::string S;
+    typedef ThrowingIterator<char> TIter;
+    typedef input_iterator<TIter> IIter;
+    const char* s = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+    test_exceptions(S(), IIter(TIter(s, s+10, 4, TIter::TAIncrement)), IIter());
+    test_exceptions(S(), IIter(TIter(s, s+10, 5, TIter::TADereference)), IIter());
+    test_exceptions(S(), IIter(TIter(s, s+10, 6, TIter::TAComparison)), IIter());
+
+    test_exceptions(S(), TIter(s, s+10, 4, TIter::TAIncrement), TIter());
+    test_exceptions(S(), TIter(s, s+10, 5, TIter::TADereference), TIter());
+    test_exceptions(S(), TIter(s, s+10, 6, TIter::TAComparison), TIter());
+	}
 }

Modified: libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_assign/pointer.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_assign/pointer.pass.cpp?rev=257716&r1=257715&r2=257716&view=diff
==============================================================================
--- libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_assign/pointer.pass.cpp (original)
+++ libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_assign/pointer.pass.cpp Wed Jan 13 17:53:40 2016
@@ -43,7 +43,7 @@ int main()
     test(S("12345678901234567890"), "12345678901234567890",
          S("12345678901234567890"));
     }
-#if __cplusplus >= 201103L
+#if TEST_STD_VER >= 11
     {
     typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
     test(S(), "", S());

Modified: libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_assign/pointer_size.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_assign/pointer_size.pass.cpp?rev=257716&r1=257715&r2=257716&view=diff
==============================================================================
--- libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_assign/pointer_size.pass.cpp (original)
+++ libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_assign/pointer_size.pass.cpp Wed Jan 13 17:53:40 2016
@@ -48,7 +48,7 @@ int main()
     test(S("12345678901234567890"), "12345678901234567890", 20,
          S("12345678901234567890"));
     }
-#if __cplusplus >= 201103L
+#if TEST_STD_VER >= 11
     {
     typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
     test(S(), "", 0, S());

Modified: libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_assign/rv_string.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_assign/rv_string.pass.cpp?rev=257716&r1=257715&r2=257716&view=diff
==============================================================================
--- libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_assign/rv_string.pass.cpp (original)
+++ libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_assign/rv_string.pass.cpp Wed Jan 13 17:53:40 2016
@@ -52,7 +52,7 @@ int main()
     test(S("12345678901234567890"), S("12345678901234567890"),
          S("12345678901234567890"));
     }
-#if __cplusplus >= 201103L
+#if TEST_STD_VER >= 11
     {
     typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
     test(S(), S(), S());

Modified: libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_assign/size_char.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_assign/size_char.pass.cpp?rev=257716&r1=257715&r2=257716&view=diff
==============================================================================
--- libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_assign/size_char.pass.cpp (original)
+++ libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_assign/size_char.pass.cpp Wed Jan 13 17:53:40 2016
@@ -43,7 +43,7 @@ int main()
     test(S("12345678901234567890"), 1, 'a', S(1, 'a'));
     test(S("12345678901234567890"), 10, 'a', S(10, 'a'));
     }
-#if __cplusplus >= 201103L
+#if TEST_STD_VER >= 11
     {
     typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
     test(S(), 0, 'a', S());

Modified: libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_assign/string.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_assign/string.pass.cpp?rev=257716&r1=257715&r2=257716&view=diff
==============================================================================
--- libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_assign/string.pass.cpp (original)
+++ libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_assign/string.pass.cpp Wed Jan 13 17:53:40 2016
@@ -51,7 +51,7 @@ int main()
     test(S("12345678901234567890"), S("12345678901234567890"),
          S("12345678901234567890"));
     }
-#if __cplusplus >= 201103L
+#if TEST_STD_VER >= 11
     {
     typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
     test(S(), S(), S());

Modified: libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_assign/string_size_size.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_assign/string_size_size.pass.cpp?rev=257716&r1=257715&r2=257716&view=diff
==============================================================================
--- libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_assign/string_size_size.pass.cpp (original)
+++ libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_assign/string_size_size.pass.cpp Wed Jan 13 17:53:40 2016
@@ -80,7 +80,7 @@ int main()
     test(S("12345678901234567890"), S("12345678901234567890"), 5, 10,
          S("6789012345"));
     }
-#if __cplusplus >= 201103L
+#if TEST_STD_VER >= 11
     {
     typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
     test(S(), S(), 0, 0, S());

Modified: libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_insert/iter_char.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_insert/iter_char.pass.cpp?rev=257716&r1=257715&r2=257716&view=diff
==============================================================================
--- libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_insert/iter_char.pass.cpp (original)
+++ libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_insert/iter_char.pass.cpp Wed Jan 13 17:53:40 2016
@@ -56,7 +56,7 @@ int main()
     test(s, s.begin()+5, 'B', S("a567AB1432dcb"));
     test(s, s.begin()+6, 'C', S("a567ABC1432dcb"));
     }
-#if __cplusplus >= 201103L
+#if TEST_STD_VER >= 11
     {
     typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
     S s;

Modified: libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_insert/iter_initializer_list.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_insert/iter_initializer_list.pass.cpp?rev=257716&r1=257715&r2=257716&view=diff
==============================================================================
--- libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_insert/iter_initializer_list.pass.cpp (original)
+++ libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_insert/iter_initializer_list.pass.cpp Wed Jan 13 17:53:40 2016
@@ -29,7 +29,7 @@ int main()
         assert(i - s.begin() == 3);
         assert(s == "123abc456");
     }
-#if __cplusplus >= 201103L
+#if TEST_STD_VER >= 11
     {
         typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
         S s("123456");

Modified: libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_insert/iter_iter_iter.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_insert/iter_iter_iter.pass.cpp?rev=257716&r1=257715&r2=257716&view=diff
==============================================================================
--- libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_insert/iter_iter_iter.pass.cpp (original)
+++ libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_insert/iter_iter_iter.pass.cpp Wed Jan 13 17:53:40 2016
@@ -19,7 +19,7 @@
 #include <string>
 #include <cassert>
 
-#include "../../input_iterator.h"
+#include "test_iterators.h"
 #include "min_allocator.h"
 
 template <class S, class It>
@@ -33,6 +33,21 @@ test(S s, typename S::difference_type po
     assert(s == expected);
 }
 
+template <class S, class It>
+void
+test_exceptions(S s, typename S::difference_type pos, It first, It last)
+{
+    typename S::const_iterator p = s.cbegin() + pos;
+	S aCopy = s;
+    try {
+        s.insert(p, first, last);
+        assert(false);
+        }
+    catch (...) {}
+    assert(s.__invariants());
+    assert(s == aCopy);
+}
+
 int main()
 {
     {
@@ -80,7 +95,7 @@ int main()
     test(S("12345678901234567890"), 20, input_iterator<const char*>(s), input_iterator<const char*>(s+52),
          S("12345678901234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"));
     }
-#if __cplusplus >= 201103L
+#if TEST_STD_VER >= 11
     {
     typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
     const char* s = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
@@ -127,6 +142,19 @@ int main()
          S("12345678901234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"));
     }
 #endif
+	{ // test iterator operations that throw
+    typedef std::string S;
+    typedef ThrowingIterator<char> TIter;
+    typedef input_iterator<TIter> IIter;
+    const char* s = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+    test_exceptions(S(), 0, IIter(TIter(s, s+10, 4, TIter::TAIncrement)), IIter());
+    test_exceptions(S(), 0, IIter(TIter(s, s+10, 5, TIter::TADereference)), IIter());
+    test_exceptions(S(), 0, IIter(TIter(s, s+10, 6, TIter::TAComparison)), IIter());
+
+    test_exceptions(S(), 0, TIter(s, s+10, 4, TIter::TAIncrement), TIter());
+    test_exceptions(S(), 0, TIter(s, s+10, 5, TIter::TADereference), TIter());
+    test_exceptions(S(), 0, TIter(s, s+10, 6, TIter::TAComparison), TIter());
+	}
 #if _LIBCPP_DEBUG >= 1
     {
         std::string v;

Modified: libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_insert/iter_size_char.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_insert/iter_size_char.pass.cpp?rev=257716&r1=257715&r2=257716&view=diff
==============================================================================
--- libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_insert/iter_size_char.pass.cpp (original)
+++ libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_insert/iter_size_char.pass.cpp Wed Jan 13 17:53:40 2016
@@ -101,7 +101,7 @@ int main()
     test(S("abcdefghijklmnopqrst"), 20, 10, '1', S("abcdefghijklmnopqrst1111111111"));
     test(S("abcdefghijklmnopqrst"), 20, 20, '1', S("abcdefghijklmnopqrst11111111111111111111"));
     }
-#if __cplusplus >= 201103L
+#if TEST_STD_VER >= 11
     {
     typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
     test(S(""), 0, 0, '1', S(""));

Modified: libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_insert/size_pointer.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_insert/size_pointer.pass.cpp?rev=257716&r1=257715&r2=257716&view=diff
==============================================================================
--- libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_insert/size_pointer.pass.cpp (original)
+++ libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_insert/size_pointer.pass.cpp Wed Jan 13 17:53:40 2016
@@ -124,7 +124,7 @@ int main()
     test(S("abcdefghijklmnopqrst"), 21, "1234567890", S("can't happen"));
     test(S("abcdefghijklmnopqrst"), 21, "12345678901234567890", S("can't happen"));
     }
-#if __cplusplus >= 201103L
+#if TEST_STD_VER >= 11
     {
     typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
     test(S(""), 0, "", S(""));

Modified: libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_insert/size_pointer_size.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_insert/size_pointer_size.pass.cpp?rev=257716&r1=257715&r2=257716&view=diff
==============================================================================
--- libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_insert/size_pointer_size.pass.cpp (original)
+++ libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_insert/size_pointer_size.pass.cpp Wed Jan 13 17:53:40 2016
@@ -365,7 +365,7 @@ int main()
     test(S("abcdefghijklmnopqrst"), 21, "12345678901234567890", 19, S("can't happen"));
     test(S("abcdefghijklmnopqrst"), 21, "12345678901234567890", 20, S("can't happen"));
     }
-#if __cplusplus >= 201103L
+#if TEST_STD_VER >= 11
     {
     typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
     test(S(""), 0, "", 0, S(""));

Modified: libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_insert/size_size_char.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_insert/size_size_char.pass.cpp?rev=257716&r1=257715&r2=257716&view=diff
==============================================================================
--- libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_insert/size_size_char.pass.cpp (original)
+++ libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_insert/size_size_char.pass.cpp Wed Jan 13 17:53:40 2016
@@ -125,7 +125,7 @@ int main()
     test(S("abcdefghijklmnopqrst"), 21, 10, '1', S("can't happen"));
     test(S("abcdefghijklmnopqrst"), 21, 20, '1', S("can't happen"));
     }
-#if __cplusplus >= 201103L
+#if TEST_STD_VER >= 11
     {
     typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
     test(S(""), 0, 0, '1', S(""));

Modified: libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_insert/size_string.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_insert/size_string.pass.cpp?rev=257716&r1=257715&r2=257716&view=diff
==============================================================================
--- libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_insert/size_string.pass.cpp (original)
+++ libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_insert/size_string.pass.cpp Wed Jan 13 17:53:40 2016
@@ -124,7 +124,7 @@ int main()
     test(S("abcdefghijklmnopqrst"), 21, S("1234567890"), S("can't happen"));
     test(S("abcdefghijklmnopqrst"), 21, S("12345678901234567890"), S("can't happen"));
     }
-#if __cplusplus >= 201103L
+#if TEST_STD_VER >= 11
     {
     typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
     test(S(""), 0, S(""), S(""));

Modified: libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_insert/size_string_size_size.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_insert/size_string_size_size.pass.cpp?rev=257716&r1=257715&r2=257716&view=diff
==============================================================================
--- libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_insert/size_string_size_size.pass.cpp (original)
+++ libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_insert/size_string_size_size.pass.cpp Wed Jan 13 17:53:40 2016
@@ -1746,7 +1746,7 @@ int main()
     test29<S>();
     test30<S>();
     }
-#if __cplusplus >= 201103L
+#if TEST_STD_VER >= 11
     {
     typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
     test0<S>();

Modified: libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_initializer_list.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_initializer_list.pass.cpp?rev=257716&r1=257715&r2=257716&view=diff
==============================================================================
--- libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_initializer_list.pass.cpp (original)
+++ libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_initializer_list.pass.cpp Wed Jan 13 17:53:40 2016
@@ -24,7 +24,7 @@ int main()
         s.replace(s.cbegin() + 3, s.cbegin() + 6, {'a', 'b', 'c'});
         assert(s == "123abc456");
     }
-#if __cplusplus >= 201103L
+#if TEST_STD_VER >= 11
     {
         typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
         S s("123def456");

Modified: libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_iter_iter.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_iter_iter.pass.cpp?rev=257716&r1=257715&r2=257716&view=diff
==============================================================================
--- libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_iter_iter.pass.cpp (original)
+++ libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_iter_iter.pass.cpp Wed Jan 13 17:53:40 2016
@@ -18,6 +18,7 @@
 #include <cassert>
 
 #include "min_allocator.h"
+#include "test_iterators.h"
 
 template <class S, class It>
 void
@@ -34,6 +35,22 @@ test(S s, typename S::size_type pos1, ty
     assert(s.size() == old_size - xlen + rlen);
 }
 
+template <class S, class It>
+void
+test_exceptions(S s, typename S::size_type pos1, typename S::size_type n1, It f, It l)
+{
+    typename S::const_iterator first = s.begin() + pos1;
+    typename S::const_iterator last = s.begin() + pos1 + n1;
+	S aCopy = s;
+	try {
+	    s.replace(first, last, f, l);
+	    assert(false);
+	    }
+	catch (...) {}
+    assert(s.__invariants());
+    assert(s == aCopy);
+}
+
 const char* str = "12345678901234567890";
 
 template <class S>
@@ -959,7 +976,7 @@ int main()
     test7<S>();
     test8<S>();
     }
-#if __cplusplus >= 201103L
+#if TEST_STD_VER >= 11
     {
     typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
     test0<S>();
@@ -973,4 +990,17 @@ int main()
     test8<S>();
     }
 #endif
+	{ // test iterator operations that throw
+    typedef std::string S;
+    typedef ThrowingIterator<char> TIter;
+    typedef input_iterator<TIter> IIter;
+    const char* s = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+    test_exceptions(S("abcdefghijklmnopqrst"), 10, 5, IIter(TIter(s, s+10, 4, TIter::TAIncrement)), IIter());
+    test_exceptions(S("abcdefghijklmnopqrst"), 10, 5, IIter(TIter(s, s+10, 5, TIter::TADereference)), IIter());
+    test_exceptions(S("abcdefghijklmnopqrst"), 10, 5, IIter(TIter(s, s+10, 6, TIter::TAComparison)), IIter());
+
+    test_exceptions(S("abcdefghijklmnopqrst"), 10, 5, TIter(s, s+10, 4, TIter::TAIncrement), TIter());
+    test_exceptions(S("abcdefghijklmnopqrst"), 10, 5, TIter(s, s+10, 5, TIter::TADereference), TIter());
+    test_exceptions(S("abcdefghijklmnopqrst"), 10, 5, TIter(s, s+10, 6, TIter::TAComparison), TIter());
+	}
 }

Modified: libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_pointer.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_pointer.pass.cpp?rev=257716&r1=257715&r2=257716&view=diff
==============================================================================
--- libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_pointer.pass.cpp (original)
+++ libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_pointer.pass.cpp Wed Jan 13 17:53:40 2016
@@ -274,7 +274,7 @@ int main()
     test1<S>();
     test2<S>();
     }
-#if __cplusplus >= 201103L
+#if TEST_STD_VER >= 11
     {
     typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
     test0<S>();

Modified: libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_pointer_size.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_pointer_size.pass.cpp?rev=257716&r1=257715&r2=257716&view=diff
==============================================================================
--- libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_pointer_size.pass.cpp (original)
+++ libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_pointer_size.pass.cpp Wed Jan 13 17:53:40 2016
@@ -959,7 +959,7 @@ int main()
     test7<S>();
     test8<S>();
     }
-#if __cplusplus >= 201103L
+#if TEST_STD_VER >= 11
     {
     typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
     test0<S>();

Modified: libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_size_char.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_size_char.pass.cpp?rev=257716&r1=257715&r2=257716&view=diff
==============================================================================
--- libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_size_char.pass.cpp (original)
+++ libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_size_char.pass.cpp Wed Jan 13 17:53:40 2016
@@ -275,7 +275,7 @@ int main()
     test1<S>();
     test2<S>();
     }
-#if __cplusplus >= 201103L
+#if TEST_STD_VER >= 11
     {
     typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
     test0<S>();

Modified: libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_string.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_string.pass.cpp?rev=257716&r1=257715&r2=257716&view=diff
==============================================================================
--- libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_string.pass.cpp (original)
+++ libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_string.pass.cpp Wed Jan 13 17:53:40 2016
@@ -274,7 +274,7 @@ int main()
     test1<S>();
     test2<S>();
     }
-#if __cplusplus >= 201103L
+#if TEST_STD_VER >= 11
     {
     typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
     test0<S>();

Modified: libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_replace/size_size_pointer.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_replace/size_size_pointer.pass.cpp?rev=257716&r1=257715&r2=257716&view=diff
==============================================================================
--- libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_replace/size_size_pointer.pass.cpp (original)
+++ libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_replace/size_size_pointer.pass.cpp Wed Jan 13 17:53:40 2016
@@ -365,7 +365,7 @@ int main()
     test1<S>();
     test2<S>();
     }
-#if __cplusplus >= 201103L
+#if TEST_STD_VER >= 11
     {
     typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
     test0<S>();

Modified: libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_replace/size_size_pointer_size.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_replace/size_size_pointer_size.pass.cpp?rev=257716&r1=257715&r2=257716&view=diff
==============================================================================
--- libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_replace/size_size_pointer_size.pass.cpp (original)
+++ libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_replace/size_size_pointer_size.pass.cpp Wed Jan 13 17:53:40 2016
@@ -1308,7 +1308,7 @@ int main()
     test10<S>();
     test11<S>();
     }
-#if __cplusplus >= 201103L
+#if TEST_STD_VER >= 11
     {
     typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
     test0<S>();

Modified: libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_replace/size_size_size_char.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_replace/size_size_size_char.pass.cpp?rev=257716&r1=257715&r2=257716&view=diff
==============================================================================
--- libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_replace/size_size_size_char.pass.cpp (original)
+++ libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_replace/size_size_size_char.pass.cpp Wed Jan 13 17:53:40 2016
@@ -364,7 +364,7 @@ int main()
     test1<S>();
     test2<S>();
     }
-#if __cplusplus >= 201103L
+#if TEST_STD_VER >= 11
     {
     typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
     test0<S>();

Modified: libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_replace/size_size_string.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_replace/size_size_string.pass.cpp?rev=257716&r1=257715&r2=257716&view=diff
==============================================================================
--- libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_replace/size_size_string.pass.cpp (original)
+++ libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_replace/size_size_string.pass.cpp Wed Jan 13 17:53:40 2016
@@ -362,7 +362,7 @@ int main()
     test1<S>();
     test2<S>();
     }
-#if __cplusplus >= 201103L
+#if TEST_STD_VER >= 11
     {
     typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
     test0<S>();

Modified: libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_replace/size_size_string_size_size.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_replace/size_size_string_size_size.pass.cpp?rev=257716&r1=257715&r2=257716&view=diff
==============================================================================
--- libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_replace/size_size_string_size_size.pass.cpp (original)
+++ libcxx/branches/release_38/test/std/strings/basic.string/string.modifiers/string_replace/size_size_string_size_size.pass.cpp Wed Jan 13 17:53:40 2016
@@ -5903,7 +5903,7 @@ int main()
     test54<S>();
     test55<S>();
     }
-#if __cplusplus >= 201103L
+#if TEST_STD_VER >= 11
     {
     typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
     test0<S>();

Modified: libcxx/branches/release_38/test/support/test_iterators.h
URL: http://llvm.org/viewvc/llvm-project/libcxx/branches/release_38/test/support/test_iterators.h?rev=257716&r1=257715&r2=257716&view=diff
==============================================================================
--- libcxx/branches/release_38/test/support/test_iterators.h (original)
+++ libcxx/branches/release_38/test/support/test_iterators.h Wed Jan 13 17:53:40 2016
@@ -11,8 +11,11 @@
 #define ITERATORS_H
 
 #include <iterator>
+#include <stdexcept>
 #include <cassert>
 
+#include "test_macros.h"
+
 #ifndef _LIBCPP_HAS_NO_DELETED_FUNCTIONS
 #define DELETE_FUNCTION = delete
 #else
@@ -324,6 +327,202 @@ inline Iter base(random_access_iterator<
 template <class Iter>    // everything else
 inline Iter base(Iter i) { return i; }
 
+template <typename T>
+struct ThrowingIterator {
+    typedef std::bidirectional_iterator_tag iterator_category;
+    typedef ptrdiff_t                       difference_type;
+    typedef const T                         value_type;
+    typedef const T *                       pointer;
+    typedef const T &                       reference;
+
+	enum ThrowingAction { TAIncrement, TADecrement, TADereference, TAAssignment, TAComparison };
+
+//	Constructors
+	ThrowingIterator ()
+		: begin_(nullptr), end_(nullptr), current_(nullptr), action_(TADereference), index_(0) {}
+	ThrowingIterator (const T *first, const T *last, size_t index = 0, ThrowingAction action = TADereference)
+		: begin_(first), end_(last), current_(first), action_(action), index_(index) {}
+	ThrowingIterator (const ThrowingIterator &rhs)
+		: begin_(rhs.begin_), end_(rhs.end_), current_(rhs.current_), action_(rhs.action_), index_(rhs.index_) {}
+	ThrowingIterator & operator= (const ThrowingIterator &rhs)
+	{
+	if (action_ == TAAssignment)
+	{
+		if (index_ == 0)
+			throw std::runtime_error ("throw from iterator assignment");
+		else
+			--index_;
+	}
+	begin_   = rhs.begin_;
+	end_     = rhs.end_;
+	current_ = rhs.current_;
+	action_  = rhs.action_;
+	index_   = rhs.index_;
+	return *this;
+	}
+
+//	iterator operations
+	reference operator*() const
+	{
+	if (action_ == TADereference)
+	{
+		if (index_ == 0)
+			throw std::runtime_error ("throw from iterator dereference");
+		else
+			--index_;
+	}
+	return *current_;
+	}
+
+	ThrowingIterator & operator++()
+	{
+	if (action_ == TAIncrement)
+	{
+		if (index_ == 0)
+			throw std::runtime_error ("throw from iterator increment");
+		else
+			--index_;
+	}
+	++current_;
+	return *this;
+	}
+	
+	ThrowingIterator operator++(int)
+	{
+		ThrowingIterator temp = *this;
+		++(*this);
+		return temp;
+	}
+
+	ThrowingIterator & operator--()
+	{
+	if (action_ == TADecrement)
+	{
+		if (index_ == 0)
+			throw std::runtime_error ("throw from iterator decrement");
+		else
+			--index_;
+	}
+	--current_;
+	return *this;
+	}
+
+	ThrowingIterator operator--(int) {
+		ThrowingIterator temp = *this;
+		--(*this);
+		return temp;
+	}
+
+	bool operator== (const ThrowingIterator &rhs) const
+	{
+	if (action_ == TAComparison)
+	{
+		if (index_ == 0)
+			throw std::runtime_error ("throw from iterator comparison");
+		else
+			--index_;
+	}
+	bool atEndL =     current_ == end_;
+	bool atEndR = rhs.current_ == rhs.end_;
+	if (atEndL != atEndR) return false;  // one is at the end (or empty), the other is not.
+	if (atEndL) return true;			 // both are at the end (or empty)
+	return current_ == rhs.current_;
+	}
+
+private:
+	const T* begin_;
+	const T* end_;
+	const T* current_;
+	ThrowingAction action_;
+	mutable size_t index_;
+};
+
+template <typename T>
+bool operator== (const ThrowingIterator<T>& a, const ThrowingIterator<T>& b)
+{	return a.operator==(b); }
+
+template <typename T>
+bool operator!= (const ThrowingIterator<T>& a, const ThrowingIterator<T>& b)
+{	return !a.operator==(b); }
+	
+template <typename T>
+struct NonThrowingIterator {
+    typedef std::bidirectional_iterator_tag iterator_category;
+    typedef ptrdiff_t                       difference_type;
+    typedef const T                         value_type;
+    typedef const T *                       pointer;
+    typedef const T &                       reference;
+
+//	Constructors
+	NonThrowingIterator ()
+		: begin_(nullptr), end_(nullptr), current_(nullptr) {}
+	NonThrowingIterator (const T *first, const T* last)
+		: begin_(first), end_(last), current_(first) {}
+	NonThrowingIterator (const NonThrowingIterator &rhs)
+		: begin_(rhs.begin_), end_(rhs.end_), current_(rhs.current_) {}
+	NonThrowingIterator & operator= (const NonThrowingIterator &rhs) TEST_NOEXCEPT
+	{
+	begin_   = rhs.begin_;
+	end_     = rhs.end_;
+	current_ = rhs.current_;
+	return *this;
+	}
+
+//	iterator operations
+	reference operator*() const TEST_NOEXCEPT
+	{
+	return *current_;
+	}
+
+	NonThrowingIterator & operator++() TEST_NOEXCEPT
+	{
+	++current_;
+	return *this;
+	}
+	
+	NonThrowingIterator operator++(int) TEST_NOEXCEPT
+	{
+		NonThrowingIterator temp = *this;
+		++(*this);
+		return temp;
+	}
+
+	NonThrowingIterator & operator--() TEST_NOEXCEPT
+	{
+	--current_;
+	return *this;
+	}
+
+	NonThrowingIterator operator--(int) TEST_NOEXCEPT
+	{
+		NonThrowingIterator temp = *this;
+		--(*this);
+		return temp;
+	}
+
+	bool operator== (const NonThrowingIterator &rhs) const TEST_NOEXCEPT
+	{
+	bool atEndL =     current_ == end_;
+	bool atEndR = rhs.current_ == rhs.end_;
+	if (atEndL != atEndR) return false;  // one is at the end (or empty), the other is not.
+	if (atEndL) return true;			 // both are at the end (or empty)
+	return current_ == rhs.current_;
+	}
+
+private:
+	const T* begin_;
+	const T* end_;
+	const T* current_;
+};
+
+template <typename T>
+bool operator== (const NonThrowingIterator<T>& a, const NonThrowingIterator<T>& b) TEST_NOEXCEPT
+{	return a.operator==(b); }
+
+template <typename T>
+bool operator!= (const NonThrowingIterator<T>& a, const NonThrowingIterator<T>& b) TEST_NOEXCEPT
+{	return !a.operator==(b); }
+
 #undef DELETE_FUNCTION
 
 #endif  // ITERATORS_H




More information about the cfe-commits mailing list