@@ -1440,24 +1440,48 @@ public:
14401440 template <class _ForwardIterator , __enable_if_t <__has_forward_iterator_category<_ForwardIterator>::value, int > = 0 >
14411441 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
14421442 append (_ForwardIterator __first, _ForwardIterator __last) {
1443- size_type __sz = size ();
1444- size_type __cap = capacity ();
1445- size_type __n = static_cast <size_type>(std::distance (__first, __last));
1443+ const size_type __size = size ();
1444+ const size_type __cap = capacity ();
1445+ const size_type __n = static_cast <size_type>(std::distance (__first, __last));
14461446 if (__n == 0 )
14471447 return *this ;
14481448
1449- if (__string_is_trivial_iterator_v<_ForwardIterator> && !__addr_in_range (*__first)) {
1450- if (__cap - __sz < __n)
1451- __grow_by_without_replace (__cap, __sz + __n - __cap, __sz, __sz, 0 );
1452- __annotate_increase (__n);
1453- auto __end = __copy_non_overlapping_range (__first, __last, std::__to_address (__get_pointer () + __sz));
1454- traits_type::assign (*__end, value_type ());
1455- __set_size (__sz + __n);
1456- return *this ;
1449+ if (__n > __cap - __size) {
1450+ __long __buffer = __allocate_long_buffer (__alloc_, __get_amortized_growth_capacity (__size + __n));
1451+ __buffer.__size_ = __size + __n;
1452+ auto __guard = std::__make_exception_guard ([&] {
1453+ __alloc_traits::deallocate (__alloc_, __buffer.__data_ , __buffer.__cap_ * __endian_factor);
1454+ });
1455+ auto __end = __copy_non_overlapping_range (__first, __last, std::__to_address (__buffer.__data_ ) + __size);
1456+ traits_type::assign (*__end, _CharT ());
1457+ traits_type::copy (std::__to_address (__buffer.__data_ ), data (), __size);
1458+ __guard.__complete ();
1459+ __reset_internal_buffer (__buffer);
14571460 } else {
1458- const basic_string __temp (__first, __last, __alloc_);
1459- return append (__temp.data (), __temp.size ());
1461+ _CharT* const __ptr = std::__to_address (__get_pointer ());
1462+ # ifndef _LIBCPP_CXX03_LANG
1463+ if constexpr (__libcpp_is_contiguous_iterator<_ForwardIterator>::value &&
1464+ is_same<value_type, __remove_cvref_t <decltype (*__first)>>::value) {
1465+ traits_type::move (__ptr + __size, std::__to_address (__first), __last - __first);
1466+ } else if constexpr (__has_bidirectional_iterator_category<_ForwardIterator>::value) {
1467+ auto __dest = __ptr + __size + __n;
1468+ while (__first != __last) {
1469+ --__last;
1470+ --__dest;
1471+ traits_type::assign (*__dest, *__last);
1472+ }
1473+ } else
1474+ # endif
1475+ {
1476+ _CharT __first_val = *__first;
1477+ ++__first;
1478+ __copy_non_overlapping_range (__first, __last, __ptr + __size + 1 );
1479+ traits_type::assign (__ptr[__size], __first_val);
1480+ }
1481+ traits_type::assign (__ptr[__size + __n], _CharT ());
1482+ __set_size (__size + __n);
14601483 }
1484+ return *this ;
14611485 }
14621486
14631487# if _LIBCPP_STD_VER >= 23
0 commit comments