@@ -1870,6 +1870,23 @@ private:
1870
1870
template <class _Iterator , class _Sentinel >
1871
1871
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __assign_with_sentinel (_Iterator __first, _Sentinel __last);
1872
1872
1873
+ // Copy [__first, __last) into [__dest, __dest + (__last - __first)). Assumes that the ranges don't overlap.
1874
+ template <class _ForwardIter , class _Sent >
1875
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 static value_type*
1876
+ __copy_non_overlapping_range (_ForwardIter __first, _Sent __last, value_type* __dest) {
1877
+ #ifndef _LIBCPP_CXX03_LANG
1878
+ if constexpr (__libcpp_is_contiguous_iterator<_ForwardIter>::value &&
1879
+ is_same<value_type, __iter_value_type<_ForwardIter>>::value && is_same<_ForwardIter, _Sent>::value) {
1880
+ traits_type::copy (__dest, std::__to_address (__first), __last - __first);
1881
+ return __dest + (__last - __first);
1882
+ }
1883
+ #endif
1884
+
1885
+ for (; __first != __last; ++__first)
1886
+ traits_type::assign (*__dest++, *__first);
1887
+ return __dest;
1888
+ }
1889
+
1873
1890
template <class _ForwardIterator , class _Sentinel >
1874
1891
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 iterator
1875
1892
__insert_from_safe_copy (size_type __n, size_type __ip, _ForwardIterator __first, _Sentinel __last) {
@@ -1889,8 +1906,7 @@ private:
1889
1906
__sz += __n;
1890
1907
__set_size (__sz);
1891
1908
traits_type::assign (__p[__sz], value_type ());
1892
- for (__p += __ip; __first != __last; ++__p, ++__first)
1893
- traits_type::assign (*__p, *__first);
1909
+ __copy_non_overlapping_range (__first, __last, __p + __ip);
1894
1910
1895
1911
return begin () + __ip;
1896
1912
}
@@ -2405,9 +2421,8 @@ basic_string<_CharT, _Traits, _Allocator>::__init_with_size(_InputIterator __fir
2405
2421
#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
2406
2422
try {
2407
2423
#endif // _LIBCPP_HAS_NO_EXCEPTIONS
2408
- for (; __first != __last; ++__first, (void )++__p)
2409
- traits_type::assign (*__p, *__first);
2410
- traits_type::assign (*__p, value_type ());
2424
+ auto __end = __copy_non_overlapping_range (__first, __last, std::__to_address (__p));
2425
+ traits_type::assign (*__end, value_type ());
2411
2426
#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
2412
2427
} catch (...) {
2413
2428
if (__is_long ())
@@ -2873,10 +2888,8 @@ basic_string<_CharT, _Traits, _Allocator>::append(_ForwardIterator __first, _For
2873
2888
if (__cap - __sz < __n)
2874
2889
__grow_by_without_replace (__cap, __sz + __n - __cap, __sz, __sz, 0 );
2875
2890
__annotate_increase (__n);
2876
- pointer __p = __get_pointer () + __sz;
2877
- for (; __first != __last; ++__p, (void )++__first)
2878
- traits_type::assign (*__p, *__first);
2879
- traits_type::assign (*__p, value_type ());
2891
+ auto __end = __copy_non_overlapping_range (__first, __last, std::__to_address (__get_pointer () + __sz));
2892
+ traits_type::assign (*__end, value_type ());
2880
2893
__set_size (__sz + __n);
2881
2894
} else {
2882
2895
const basic_string __temp (__first, __last, __alloc ());
0 commit comments