@@ -1417,20 +1417,21 @@ public:
14171417 size_type __sz = size ();
14181418 size_type __cap = capacity ();
14191419 size_type __n = static_cast <size_type>(std::distance (__first, __last));
1420- if (__n) {
1421- if (__string_is_trivial_iterator_v<_ForwardIterator> && !__addr_in_range (*__first)) {
1422- if (__cap - __sz < __n)
1423- __grow_by_without_replace (__cap, __sz + __n - __cap, __sz, __sz, 0 );
1424- __annotate_increase (__n);
1425- auto __end = __copy_non_overlapping_range (__first, __last, std::__to_address (__get_pointer () + __sz));
1426- traits_type::assign (*__end, value_type ());
1427- __set_size (__sz + __n);
1428- } else {
1429- const basic_string __temp (__first, __last, __alloc_);
1430- append (__temp.data (), __temp.size ());
1431- }
1420+ if (__n == 0 )
1421+ return *this ;
1422+
1423+ if (__string_is_trivial_iterator_v<_ForwardIterator> && !__addr_in_range (*__first)) {
1424+ if (__cap - __sz < __n)
1425+ __grow_by_without_replace (__cap, __sz + __n - __cap, __sz, __sz, 0 );
1426+ __annotate_increase (__n);
1427+ auto __end = __copy_non_overlapping_range (__first, __last, std::__to_address (__get_pointer () + __sz));
1428+ traits_type::assign (*__end, value_type ());
1429+ __set_size (__sz + __n);
1430+ return *this ;
1431+ } else {
1432+ const basic_string __temp (__first, __last, __alloc_);
1433+ return append (__temp.data (), __temp.size ());
14321434 }
1433- return *this ;
14341435 }
14351436
14361437# if _LIBCPP_STD_VER >= 23
@@ -2790,24 +2791,23 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_NOINLINE basic_string<_CharT, _Traits, _Al
27902791basic_string<_CharT, _Traits, _Allocator>::__assign_no_alias (const value_type* __s, size_type __n) {
27912792 const auto __cap = __is_short ? static_cast <size_type>(__min_cap) : __get_long_cap ();
27922793 const auto __size = __is_short ? __get_short_size () : __get_long_size ();
2793- if (__n < __cap) {
2794- if (__n > __size)
2795- __annotate_increase (__n - __size);
2796- pointer __p;
2797- if (__is_short) {
2798- __p = __get_short_pointer ();
2799- __set_short_size (__n);
2800- } else {
2801- __p = __get_long_pointer ();
2802- __set_long_size (__n);
2803- }
2804- traits_type::copy (std::__to_address (__p), __s, __n);
2805- traits_type::assign (__p[__n], value_type ());
2806- if (__size > __n)
2807- __annotate_shrink (__size);
2808- } else {
2794+ if (__n >= __cap) {
28092795 __grow_by_and_replace (__cap - 1 , __n - __cap + 1 , __size, 0 , __size, __n, __s);
2796+ return *this ;
28102797 }
2798+
2799+ __annotate_delete ();
2800+ auto __guard = std::__make_scope_guard (__annotate_new_size (*this ));
2801+ pointer __p;
2802+ if (__is_short) {
2803+ __p = __get_short_pointer ();
2804+ __set_short_size (__n);
2805+ } else {
2806+ __p = __get_long_pointer ();
2807+ __set_long_size (__n);
2808+ }
2809+ traits_type::copy (std::__to_address (__p), __s, __n);
2810+ traits_type::assign (__p[__n], value_type ());
28112811 return *this ;
28122812}
28132813
@@ -3021,52 +3021,56 @@ basic_string<_CharT, _Traits, _Allocator>::append(const value_type* __s, size_ty
30213021 _LIBCPP_ASSERT_NON_NULL (__n == 0 || __s != nullptr , " string::append received nullptr" );
30223022 size_type __cap = capacity ();
30233023 size_type __sz = size ();
3024- if (__cap - __sz >= __n) {
3025- if (__n) {
3026- __annotate_increase (__n);
3027- value_type* __p = std::__to_address (__get_pointer ());
3028- traits_type::copy (__p + __sz, __s, __n);
3029- __sz += __n;
3030- __set_size (__sz);
3031- traits_type::assign (__p[__sz], value_type ());
3032- }
3033- } else
3024+ if (__cap - __sz < __n) {
30343025 __grow_by_and_replace (__cap, __sz + __n - __cap, __sz, __sz, 0 , __n, __s);
3026+ return *this ;
3027+ }
3028+
3029+ if (__n == 0 )
3030+ return *this ;
3031+
3032+ __annotate_increase (__n);
3033+ value_type* __p = std::__to_address (__get_pointer ());
3034+ traits_type::copy (__p + __sz, __s, __n);
3035+ __sz += __n;
3036+ __set_size (__sz);
3037+ traits_type::assign (__p[__sz], value_type ());
30353038 return *this ;
30363039}
30373040
30383041template <class _CharT , class _Traits , class _Allocator >
30393042_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>&
30403043basic_string<_CharT, _Traits, _Allocator>::append (size_type __n, value_type __c) {
3041- if (__n) {
3042- size_type __cap = capacity ();
3043- size_type __sz = size ();
3044- if (__cap - __sz < __n)
3045- __grow_by_without_replace (__cap, __sz + __n - __cap, __sz, __sz, 0 );
3046- __annotate_increase (__n);
3047- pointer __p = __get_pointer ();
3048- traits_type::assign (std::__to_address (__p) + __sz, __n, __c);
3049- __sz += __n;
3050- __set_size (__sz);
3051- traits_type::assign (__p[__sz], value_type ());
3052- }
3044+ if (__n == 0 )
3045+ return *this ;
3046+
3047+ size_type __cap = capacity ();
3048+ size_type __sz = size ();
3049+ if (__cap - __sz < __n)
3050+ __grow_by_without_replace (__cap, __sz + __n - __cap, __sz, __sz, 0 );
3051+ __annotate_increase (__n);
3052+ pointer __p = __get_pointer ();
3053+ traits_type::assign (std::__to_address (__p) + __sz, __n, __c);
3054+ __sz += __n;
3055+ __set_size (__sz);
3056+ traits_type::assign (__p[__sz], value_type ());
30533057 return *this ;
30543058}
30553059
30563060template <class _CharT , class _Traits , class _Allocator >
30573061_LIBCPP_CONSTEXPR_SINCE_CXX20 inline void
30583062basic_string<_CharT, _Traits, _Allocator>::__append_default_init (size_type __n) {
3059- if (__n) {
3060- size_type __cap = capacity () ;
3061- size_type __sz = size ();
3062- if (__cap - __sz < __n)
3063- __grow_by_without_replace (__cap, __sz + __n - __cap, __sz, __sz, 0 );
3064- __annotate_increase ( __n);
3065- pointer __p = __get_pointer ( );
3066- __sz += __n ;
3067- __set_size (__sz) ;
3068- traits_type::assign (__p[ __sz], value_type () );
3069- }
3063+ if (__n == 0 )
3064+ return ;
3065+ size_type __cap = capacity ();
3066+ size_type __sz = size ();
3067+ if (__cap - __sz < __n)
3068+ __grow_by_without_replace (__cap, __sz + __n - __cap, __sz, __sz, 0 );
3069+ __annotate_increase (__n );
3070+ pointer __p = __get_pointer () ;
3071+ __sz += __n ;
3072+ __set_size ( __sz);
3073+ traits_type::assign (__p[__sz], value_type ());
30703074}
30713075
30723076template <class _CharT , class _Traits , class _Allocator >
@@ -3124,23 +3128,27 @@ basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, const value_t
31243128 if (__pos > __sz)
31253129 this ->__throw_out_of_range ();
31263130 size_type __cap = capacity ();
3127- if (__cap - __sz >= __n) {
3128- if (__n) {
3129- __annotate_increase (__n);
3130- value_type* __p = std::__to_address (__get_pointer ());
3131- size_type __n_move = __sz - __pos;
3132- if (__n_move != 0 ) {
3133- if (std::__is_pointer_in_range (__p + __pos, __p + __sz, __s))
3134- __s += __n;
3135- traits_type::move (__p + __pos + __n, __p + __pos, __n_move);
3136- }
3137- traits_type::move (__p + __pos, __s, __n);
3138- __sz += __n;
3139- __set_size (__sz);
3140- traits_type::assign (__p[__sz], value_type ());
3141- }
3142- } else
3131+
3132+ if (__cap - __sz < __n) {
31433133 __grow_by_and_replace (__cap, __sz + __n - __cap, __sz, __pos, 0 , __n, __s);
3134+ return *this ;
3135+ }
3136+
3137+ if (__n == 0 )
3138+ return *this ;
3139+
3140+ __annotate_increase (__n);
3141+ value_type* __p = std::__to_address (__get_pointer ());
3142+ size_type __n_move = __sz - __pos;
3143+ if (__n_move != 0 ) {
3144+ if (std::__is_pointer_in_range (__p + __pos, __p + __sz, __s))
3145+ __s += __n;
3146+ traits_type::move (__p + __pos + __n, __p + __pos, __n_move);
3147+ }
3148+ traits_type::move (__p + __pos, __s, __n);
3149+ __sz += __n;
3150+ __set_size (__sz);
3151+ traits_type::assign (__p[__sz], value_type ());
31443152 return *this ;
31453153}
31463154
@@ -3150,24 +3158,26 @@ basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, size_type __n
31503158 size_type __sz = size ();
31513159 if (__pos > __sz)
31523160 this ->__throw_out_of_range ();
3153- if (__n) {
3154- size_type __cap = capacity ();
3155- value_type* __p;
3156- if (__cap - __sz >= __n) {
3157- __annotate_increase (__n);
3158- __p = std::__to_address (__get_pointer ());
3159- size_type __n_move = __sz - __pos;
3160- if (__n_move != 0 )
3161- traits_type::move (__p + __pos + __n, __p + __pos, __n_move);
3162- } else {
3163- __grow_by_without_replace (__cap, __sz + __n - __cap, __sz, __pos, 0 , __n);
3164- __p = std::__to_address (__get_long_pointer ());
3165- }
3166- traits_type::assign (__p + __pos, __n, __c);
3167- __sz += __n;
3168- __set_size (__sz);
3169- traits_type::assign (__p[__sz], value_type ());
3161+
3162+ if (__n == 0 )
3163+ return *this ;
3164+
3165+ size_type __cap = capacity ();
3166+ value_type* __p;
3167+ if (__cap - __sz >= __n) {
3168+ __annotate_increase (__n);
3169+ __p = std::__to_address (__get_pointer ());
3170+ size_type __n_move = __sz - __pos;
3171+ if (__n_move != 0 )
3172+ traits_type::move (__p + __pos + __n, __p + __pos, __n_move);
3173+ } else {
3174+ __grow_by_without_replace (__cap, __sz + __n - __cap, __sz, __pos, 0 , __n);
3175+ __p = std::__to_address (__get_long_pointer ());
31703176 }
3177+ traits_type::assign (__p + __pos, __n, __c);
3178+ __sz += __n;
3179+ __set_size (__sz);
3180+ traits_type::assign (__p[__sz], value_type ());
31713181 return *this ;
31723182}
31733183
@@ -3241,38 +3251,38 @@ basic_string<_CharT, _Traits, _Allocator>::replace(
32413251 this ->__throw_out_of_range ();
32423252 __n1 = std::min (__n1, __sz - __pos);
32433253 size_type __cap = capacity ();
3244- if (__cap - __sz + __n1 >= __n2) {
3245- value_type* __p = std::__to_address (__get_pointer ());
3246- if (__n1 != __n2) {
3247- if (__n2 > __n1)
3248- __annotate_increase (__n2 - __n1);
3249- size_type __n_move = __sz - __pos - __n1;
3250- if (__n_move != 0 ) {
3251- if (__n1 > __n2) {
3252- traits_type::move (__p + __pos, __s, __n2);
3253- traits_type::move (__p + __pos + __n2, __p + __pos + __n1, __n_move);
3254- return __null_terminate_at (__p, __sz + (__n2 - __n1));
3255- }
3256- if (std::__is_pointer_in_range (__p + __pos + 1 , __p + __sz, __s)) {
3257- if (__p + __pos + __n1 <= __s)
3258- __s += __n2 - __n1;
3259- else // __p + __pos < __s < __p + __pos + __n1
3260- {
3261- traits_type::move (__p + __pos, __s, __n1);
3262- __pos += __n1;
3263- __s += __n2;
3264- __n2 -= __n1;
3265- __n1 = 0 ;
3266- }
3267- }
3254+ if (__cap - __sz + __n1 < __n2) {
3255+ __grow_by_and_replace (__cap, __sz - __n1 + __n2 - __cap, __sz, __pos, __n1, __n2, __s);
3256+ return *this ;
3257+ }
3258+
3259+ value_type* __p = std::__to_address (__get_pointer ());
3260+ if (__n1 != __n2) {
3261+ if (__n2 > __n1)
3262+ __annotate_increase (__n2 - __n1);
3263+ size_type __n_move = __sz - __pos - __n1;
3264+ if (__n_move != 0 ) {
3265+ if (__n1 > __n2) {
3266+ traits_type::move (__p + __pos, __s, __n2);
32683267 traits_type::move (__p + __pos + __n2, __p + __pos + __n1, __n_move);
3268+ return __null_terminate_at (__p, __sz + (__n2 - __n1));
3269+ }
3270+ if (std::__is_pointer_in_range (__p + __pos + 1 , __p + __sz, __s)) {
3271+ if (__p + __pos + __n1 <= __s) {
3272+ __s += __n2 - __n1;
3273+ } else { // __p + __pos < __s < __p + __pos + __n1
3274+ traits_type::move (__p + __pos, __s, __n1);
3275+ __pos += __n1;
3276+ __s += __n2;
3277+ __n2 -= __n1;
3278+ __n1 = 0 ;
3279+ }
32693280 }
3281+ traits_type::move (__p + __pos + __n2, __p + __pos + __n1, __n_move);
32703282 }
3271- traits_type::move (__p + __pos, __s, __n2);
3272- return __null_terminate_at (__p, __sz + (__n2 - __n1));
3273- } else
3274- __grow_by_and_replace (__cap, __sz - __n1 + __n2 - __cap, __sz, __pos, __n1, __n2, __s);
3275- return *this ;
3283+ }
3284+ traits_type::move (__p + __pos, __s, __n2);
3285+ return __null_terminate_at (__p, __sz + (__n2 - __n1));
32763286}
32773287
32783288template <class _CharT , class _Traits , class _Allocator >
@@ -3325,15 +3335,16 @@ basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __
33253335template <class _CharT , class _Traits , class _Allocator >
33263336_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_NOINLINE void
33273337basic_string<_CharT, _Traits, _Allocator>::__erase_external_with_move (size_type __pos, size_type __n) {
3328- if (__n) {
3329- size_type __sz = size ();
3330- value_type* __p = std::__to_address (__get_pointer ());
3331- __n = std::min (__n, __sz - __pos);
3332- size_type __n_move = __sz - __pos - __n;
3333- if (__n_move != 0 )
3334- traits_type::move (__p + __pos, __p + __pos + __n, __n_move);
3335- __null_terminate_at (__p, __sz - __n);
3336- }
3338+ if (__n == 0 )
3339+ return ;
3340+
3341+ size_type __sz = size ();
3342+ value_type* __p = std::__to_address (__get_pointer ());
3343+ __n = std::min (__n, __sz - __pos);
3344+ size_type __n_move = __sz - __pos - __n;
3345+ if (__n_move != 0 )
3346+ traits_type::move (__p + __pos, __p + __pos + __n, __n_move);
3347+ __null_terminate_at (__p, __sz - __n);
33373348}
33383349
33393350template <class _CharT , class _Traits , class _Allocator >
0 commit comments