Index: include/algorithm =================================================================== --- include/algorithm +++ include/algorithm @@ -1687,26 +1687,7 @@ } // copy - template -struct __libcpp_is_trivial_iterator -{ - static const bool value = is_pointer<_Iter>::value; -}; - -template -struct __libcpp_is_trivial_iterator > -{ - static const bool value = is_pointer<_Iter>::value; -}; - -template -struct __libcpp_is_trivial_iterator<__wrap_iter<_Iter> > -{ - static const bool value = is_pointer<_Iter>::value; -}; - -template inline _LIBCPP_INLINE_VISIBILITY _Iter __unwrap_iter(_Iter __i) Index: include/iterator =================================================================== --- include/iterator +++ include/iterator @@ -437,6 +437,13 @@ template struct __is_random_access_iterator : public __has_iterator_category_convertible_to<_Tp, random_access_iterator_tag> {}; +template >::value> +struct __is_exactly_input_iterator + : public integral_constant::iterator_category, input_iterator_tag>::value> {}; + +template +struct __is_exactly_input_iterator<_Tp, false> : public false_type {}; + template struct _LIBCPP_TYPE_VIS_ONLY iterator @@ -1404,6 +1411,23 @@ return __x; } +template +struct __libcpp_is_trivial_iterator + : public _LIBCPP_BOOL_CONSTANT(is_pointer<_Iter>::value) {}; + +template +struct __libcpp_is_trivial_iterator > + : public _LIBCPP_BOOL_CONSTANT(__libcpp_is_trivial_iterator<_Iter>::value) {}; + +template +struct __libcpp_is_trivial_iterator > + : public _LIBCPP_BOOL_CONSTANT(__libcpp_is_trivial_iterator<_Iter>::value) {}; + +template +struct __libcpp_is_trivial_iterator<__wrap_iter<_Iter> > + : public _LIBCPP_BOOL_CONSTANT(__libcpp_is_trivial_iterator<_Iter>::value) {}; + + template inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 _Tp* Index: include/string =================================================================== --- include/string +++ include/string @@ -1201,6 +1201,25 @@ #pragma warning( pop ) #endif // _LIBCPP_MSVC +#ifdef _LIBCPP_HAS_NO_NOEXCEPT +template +struct __libcpp_string_gets_noexcept_iterator_impl : public _LIBCPP_BOOL_CONSTANT(false) {}; +#else +template +struct __libcpp_string_gets_noexcept_iterator_impl : public _LIBCPP_BOOL_CONSTANT(( + __is_forward_iterator<_Iter>::value && + noexcept(++(declval<_Iter&>())) && + is_nothrow_assignable<_Iter&, _Iter>::value && + noexcept(declval<_Iter>() == declval<_Iter>()) && + noexcept(*declval<_Iter>()) +)) {}; +#endif + + +template +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 @@ -1495,15 +1514,16 @@ template 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 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 +1555,16 @@ template 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 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 +1585,16 @@ template 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 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 +1839,7 @@ template 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 +2216,7 @@ template 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 +2514,14 @@ template 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 +2529,8 @@ template 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 +2663,31 @@ template 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); +#ifndef _LIBCPP_NO_EXCEPTIONS + size_type __sz = size(); + try + { +#endif + for (; __first != __last; ++__first) + push_back(*__first); + +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + pointer __p = __get_pointer() + __sz; + traits_type::assign(*__p, value_type()); + __set_size(__sz); + throw ; + } +#endif + return *this; } @@ -2658,7 +2695,8 @@ template 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 +2812,9 @@ template 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 +2823,16 @@ "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.begin(), __temp.end()); } template template 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 +3035,8 @@ 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(*__i1), *__j1); - } - return *this; + basic_string __temp(__j1, __j2, __alloc()); + return this->replace(__i1, __i2, __temp); } template