@@ -1406,19 +1406,21 @@ public:
14061406 size_type __sz = size ();
14071407 size_type __cap = capacity ();
14081408 size_type __n = static_cast <size_type>(std::distance (__first, __last));
1409- if (__n) {
1410- if (__string_is_trivial_iterator<_ForwardIterator>::value && !__addr_in_range (*__first)) {
1411- if (__cap - __sz < __n)
1412- __grow_by_without_replace (__cap, __sz + __n - __cap, __sz, __sz, 0 );
1413- __annotate_increase (__n);
1414- auto __end = __copy_non_overlapping_range (__first, __last, std::__to_address (__get_pointer () + __sz));
1415- traits_type::assign (*__end, value_type ());
1416- __set_size (__sz + __n);
1417- } else {
1418- const basic_string __temp (__first, __last, __alloc_);
1419- append (__temp.data (), __temp.size ());
1420- }
1409+ if (__n == 0 )
1410+ return *this ;
1411+
1412+ if (__string_is_trivial_iterator<_ForwardIterator>::value && __addr_in_range (*__first)) {
1413+ const basic_string __temp (__first, __last, __alloc_);
1414+ append (__temp.data (), __temp.size ());
1415+ return *this ;
14211416 }
1417+
1418+ if (__cap - __sz < __n)
1419+ __grow_by_without_replace (__cap, __sz + __n - __cap, __sz, __sz, 0 );
1420+ __annotate_increase (__n);
1421+ auto __end = __copy_non_overlapping_range (__first, __last, std::__to_address (__get_pointer () + __sz));
1422+ traits_type::assign (*__end, value_type ());
1423+ __set_size (__sz + __n);
14221424 return *this ;
14231425 }
14241426
@@ -2783,24 +2785,22 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_NOINLINE basic_string<_CharT, _Traits, _Al
27832785basic_string<_CharT, _Traits, _Allocator>::__assign_no_alias (const value_type* __s, size_type __n) {
27842786 const auto __cap = __is_short ? static_cast <size_type>(__min_cap) : __get_long_cap ();
27852787 const auto __size = __is_short ? __get_short_size () : __get_long_size ();
2786- if (__n < __cap) {
2787- if (__n > __size)
2788- __annotate_increase (__n - __size);
2789- pointer __p;
2790- if (__is_short) {
2791- __p = __get_short_pointer ();
2792- __set_short_size (__n);
2793- } else {
2794- __p = __get_long_pointer ();
2795- __set_long_size (__n);
2796- }
2797- traits_type::copy (std::__to_address (__p), __s, __n);
2798- traits_type::assign (__p[__n], value_type ());
2799- if (__size > __n)
2800- __annotate_shrink (__size);
2801- } else {
2788+ if (__n >= __cap) {
28022789 __grow_by_and_replace (__cap - 1 , __n - __cap + 1 , __size, 0 , __size, __n, __s);
2790+ return *this ;
2791+ }
2792+
2793+ auto __guard = std::__make_scope_guard (__annotate_new_size (*this ));
2794+ pointer __p;
2795+ if (__is_short) {
2796+ __p = __get_short_pointer ();
2797+ __set_short_size (__n);
2798+ } else {
2799+ __p = __get_long_pointer ();
2800+ __set_long_size (__n);
28032801 }
2802+ traits_type::copy (std::__to_address (__p), __s, __n);
2803+ traits_type::assign (__p[__n], value_type ());
28042804 return *this ;
28052805}
28062806
@@ -3014,52 +3014,56 @@ basic_string<_CharT, _Traits, _Allocator>::append(const value_type* __s, size_ty
30143014 _LIBCPP_ASSERT_NON_NULL (__n == 0 || __s != nullptr , " string::append received nullptr" );
30153015 size_type __cap = capacity ();
30163016 size_type __sz = size ();
3017- if (__cap - __sz >= __n) {
3018- if (__n) {
3019- __annotate_increase (__n);
3020- value_type* __p = std::__to_address (__get_pointer ());
3021- traits_type::copy (__p + __sz, __s, __n);
3022- __sz += __n;
3023- __set_size (__sz);
3024- traits_type::assign (__p[__sz], value_type ());
3025- }
3026- } else
3017+ if (__cap - __sz < __n) {
30273018 __grow_by_and_replace (__cap, __sz + __n - __cap, __sz, __sz, 0 , __n, __s);
3019+ return *this ;
3020+ }
3021+
3022+ if (__n == 0 )
3023+ return *this ;
3024+
3025+ __annotate_increase (__n);
3026+ value_type* __p = std::__to_address (__get_pointer ());
3027+ traits_type::copy (__p + __sz, __s, __n);
3028+ __sz += __n;
3029+ __set_size (__sz);
3030+ traits_type::assign (__p[__sz], value_type ());
30283031 return *this ;
30293032}
30303033
30313034template <class _CharT , class _Traits , class _Allocator >
30323035_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>&
30333036basic_string<_CharT, _Traits, _Allocator>::append (size_type __n, value_type __c) {
3034- if (__n) {
3035- size_type __cap = capacity ();
3036- size_type __sz = size ();
3037- if (__cap - __sz < __n)
3038- __grow_by_without_replace (__cap, __sz + __n - __cap, __sz, __sz, 0 );
3039- __annotate_increase (__n);
3040- pointer __p = __get_pointer ();
3041- traits_type::assign (std::__to_address (__p) + __sz, __n, __c);
3042- __sz += __n;
3043- __set_size (__sz);
3044- traits_type::assign (__p[__sz], value_type ());
3045- }
3037+ if (__n == 0 )
3038+ return *this ;
3039+
3040+ size_type __cap = capacity ();
3041+ size_type __sz = size ();
3042+ if (__cap - __sz < __n)
3043+ __grow_by_without_replace (__cap, __sz + __n - __cap, __sz, __sz, 0 );
3044+ __annotate_increase (__n);
3045+ pointer __p = __get_pointer ();
3046+ traits_type::assign (std::__to_address (__p) + __sz, __n, __c);
3047+ __sz += __n;
3048+ __set_size (__sz);
3049+ traits_type::assign (__p[__sz], value_type ());
30463050 return *this ;
30473051}
30483052
30493053template <class _CharT , class _Traits , class _Allocator >
30503054_LIBCPP_CONSTEXPR_SINCE_CXX20 inline void
30513055basic_string<_CharT, _Traits, _Allocator>::__append_default_init (size_type __n) {
3052- if (__n) {
3053- size_type __cap = capacity () ;
3054- size_type __sz = size ();
3055- if (__cap - __sz < __n)
3056- __grow_by_without_replace (__cap, __sz + __n - __cap, __sz, __sz, 0 );
3057- __annotate_increase ( __n);
3058- pointer __p = __get_pointer ( );
3059- __sz += __n ;
3060- __set_size (__sz) ;
3061- traits_type::assign (__p[ __sz], value_type () );
3062- }
3056+ if (__n == 0 )
3057+ return ;
3058+ size_type __cap = capacity ();
3059+ size_type __sz = size ();
3060+ if (__cap - __sz < __n)
3061+ __grow_by_without_replace (__cap, __sz + __n - __cap, __sz, __sz, 0 );
3062+ __annotate_increase (__n );
3063+ pointer __p = __get_pointer () ;
3064+ __sz += __n ;
3065+ __set_size ( __sz);
3066+ traits_type::assign (__p[__sz], value_type ());
30633067}
30643068
30653069template <class _CharT , class _Traits , class _Allocator >
@@ -3117,23 +3121,27 @@ basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, const value_t
31173121 if (__pos > __sz)
31183122 this ->__throw_out_of_range ();
31193123 size_type __cap = capacity ();
3120- if (__cap - __sz >= __n) {
3121- if (__n) {
3122- __annotate_increase (__n);
3123- value_type* __p = std::__to_address (__get_pointer ());
3124- size_type __n_move = __sz - __pos;
3125- if (__n_move != 0 ) {
3126- if (std::__is_pointer_in_range (__p + __pos, __p + __sz, __s))
3127- __s += __n;
3128- traits_type::move (__p + __pos + __n, __p + __pos, __n_move);
3129- }
3130- traits_type::move (__p + __pos, __s, __n);
3131- __sz += __n;
3132- __set_size (__sz);
3133- traits_type::assign (__p[__sz], value_type ());
3134- }
3135- } else
3124+
3125+ if (__cap - __sz < __n) {
31363126 __grow_by_and_replace (__cap, __sz + __n - __cap, __sz, __pos, 0 , __n, __s);
3127+ return *this ;
3128+ }
3129+
3130+ if (__n == 0 )
3131+ return *this ;
3132+
3133+ __annotate_increase (__n);
3134+ value_type* __p = std::__to_address (__get_pointer ());
3135+ size_type __n_move = __sz - __pos;
3136+ if (__n_move != 0 ) {
3137+ if (std::__is_pointer_in_range (__p + __pos, __p + __sz, __s))
3138+ __s += __n;
3139+ traits_type::move (__p + __pos + __n, __p + __pos, __n_move);
3140+ }
3141+ traits_type::move (__p + __pos, __s, __n);
3142+ __sz += __n;
3143+ __set_size (__sz);
3144+ traits_type::assign (__p[__sz], value_type ());
31373145 return *this ;
31383146}
31393147
@@ -3143,24 +3151,26 @@ basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, size_type __n
31433151 size_type __sz = size ();
31443152 if (__pos > __sz)
31453153 this ->__throw_out_of_range ();
3146- if (__n) {
3147- size_type __cap = capacity ();
3148- value_type* __p;
3149- if (__cap - __sz >= __n) {
3150- __annotate_increase (__n);
3151- __p = std::__to_address (__get_pointer ());
3152- size_type __n_move = __sz - __pos;
3153- if (__n_move != 0 )
3154- traits_type::move (__p + __pos + __n, __p + __pos, __n_move);
3155- } else {
3156- __grow_by_without_replace (__cap, __sz + __n - __cap, __sz, __pos, 0 , __n);
3157- __p = std::__to_address (__get_long_pointer ());
3158- }
3159- traits_type::assign (__p + __pos, __n, __c);
3160- __sz += __n;
3161- __set_size (__sz);
3162- traits_type::assign (__p[__sz], value_type ());
3154+
3155+ if (__n == 0 )
3156+ return *this ;
3157+
3158+ size_type __cap = capacity ();
3159+ value_type* __p;
3160+ if (__cap - __sz >= __n) {
3161+ __annotate_increase (__n);
3162+ __p = std::__to_address (__get_pointer ());
3163+ size_type __n_move = __sz - __pos;
3164+ if (__n_move != 0 )
3165+ traits_type::move (__p + __pos + __n, __p + __pos, __n_move);
3166+ } else {
3167+ __grow_by_without_replace (__cap, __sz + __n - __cap, __sz, __pos, 0 , __n);
3168+ __p = std::__to_address (__get_long_pointer ());
31633169 }
3170+ traits_type::assign (__p + __pos, __n, __c);
3171+ __sz += __n;
3172+ __set_size (__sz);
3173+ traits_type::assign (__p[__sz], value_type ());
31643174 return *this ;
31653175}
31663176
@@ -3234,38 +3244,38 @@ basic_string<_CharT, _Traits, _Allocator>::replace(
32343244 this ->__throw_out_of_range ();
32353245 __n1 = std::min (__n1, __sz - __pos);
32363246 size_type __cap = capacity ();
3237- if (__cap - __sz + __n1 >= __n2) {
3238- value_type* __p = std::__to_address (__get_pointer ());
3239- if (__n1 != __n2) {
3240- if (__n2 > __n1)
3241- __annotate_increase (__n2 - __n1);
3242- size_type __n_move = __sz - __pos - __n1;
3243- if (__n_move != 0 ) {
3244- if (__n1 > __n2) {
3245- traits_type::move (__p + __pos, __s, __n2);
3246- traits_type::move (__p + __pos + __n2, __p + __pos + __n1, __n_move);
3247- return __null_terminate_at (__p, __sz + (__n2 - __n1));
3248- }
3249- if (std::__is_pointer_in_range (__p + __pos + 1 , __p + __sz, __s)) {
3250- if (__p + __pos + __n1 <= __s)
3251- __s += __n2 - __n1;
3252- else // __p + __pos < __s < __p + __pos + __n1
3253- {
3254- traits_type::move (__p + __pos, __s, __n1);
3255- __pos += __n1;
3256- __s += __n2;
3257- __n2 -= __n1;
3258- __n1 = 0 ;
3259- }
3260- }
3247+ if (__cap - __sz + __n1 < __n2) {
3248+ __grow_by_and_replace (__cap, __sz - __n1 + __n2 - __cap, __sz, __pos, __n1, __n2, __s);
3249+ return *this ;
3250+ }
3251+
3252+ value_type* __p = std::__to_address (__get_pointer ());
3253+ if (__n1 != __n2) {
3254+ if (__n2 > __n1)
3255+ __annotate_increase (__n2 - __n1);
3256+ size_type __n_move = __sz - __pos - __n1;
3257+ if (__n_move != 0 ) {
3258+ if (__n1 > __n2) {
3259+ traits_type::move (__p + __pos, __s, __n2);
32613260 traits_type::move (__p + __pos + __n2, __p + __pos + __n1, __n_move);
3261+ return __null_terminate_at (__p, __sz + (__n2 - __n1));
3262+ }
3263+ if (std::__is_pointer_in_range (__p + __pos + 1 , __p + __sz, __s)) {
3264+ if (__p + __pos + __n1 <= __s) {
3265+ __s += __n2 - __n1;
3266+ } else { // __p + __pos < __s < __p + __pos + __n1
3267+ traits_type::move (__p + __pos, __s, __n1);
3268+ __pos += __n1;
3269+ __s += __n2;
3270+ __n2 -= __n1;
3271+ __n1 = 0 ;
3272+ }
32623273 }
3274+ traits_type::move (__p + __pos + __n2, __p + __pos + __n1, __n_move);
32633275 }
3264- traits_type::move (__p + __pos, __s, __n2);
3265- return __null_terminate_at (__p, __sz + (__n2 - __n1));
3266- } else
3267- __grow_by_and_replace (__cap, __sz - __n1 + __n2 - __cap, __sz, __pos, __n1, __n2, __s);
3268- return *this ;
3276+ }
3277+ traits_type::move (__p + __pos, __s, __n2);
3278+ return __null_terminate_at (__p, __sz + (__n2 - __n1));
32693279}
32703280
32713281template <class _CharT , class _Traits , class _Allocator >
@@ -3318,15 +3328,16 @@ basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __
33183328template <class _CharT , class _Traits , class _Allocator >
33193329_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_NOINLINE void
33203330basic_string<_CharT, _Traits, _Allocator>::__erase_external_with_move (size_type __pos, size_type __n) {
3321- if (__n) {
3322- size_type __sz = size ();
3323- value_type* __p = std::__to_address (__get_pointer ());
3324- __n = std::min (__n, __sz - __pos);
3325- size_type __n_move = __sz - __pos - __n;
3326- if (__n_move != 0 )
3327- traits_type::move (__p + __pos, __p + __pos + __n, __n_move);
3328- __null_terminate_at (__p, __sz - __n);
3329- }
3331+ if (__n == 0 )
3332+ return ;
3333+
3334+ size_type __sz = size ();
3335+ value_type* __p = std::__to_address (__get_pointer ());
3336+ __n = std::min (__n, __sz - __pos);
3337+ size_type __n_move = __sz - __pos - __n;
3338+ if (__n_move != 0 )
3339+ traits_type::move (__p + __pos, __p + __pos + __n, __n_move);
3340+ __null_terminate_at (__p, __sz - __n);
33303341}
33313342
33323343template <class _CharT , class _Traits , class _Allocator >
0 commit comments