@@ -1945,7 +1945,7 @@ private:
19451945 if (__n_move != 0 )
19461946 traits_type::move (__p + __ip + __n, __p + __ip, __n_move);
19471947 } else {
1948- __grow_by_without_replace (__cap, __sz + __n - __cap, __sz, __ip, 0 , __n);
1948+ __grow_to_with_hole ( __sz + __n, __ip, __n);
19491949 __p = std::__to_address (__get_long_pointer ());
19501950 }
19511951 __sz += __n;
@@ -2141,20 +2141,15 @@ private:
21412141# if _LIBCPP_ABI_VERSION >= 2 // We want to use the function in the dylib in ABIv1
21422142 _LIBCPP_HIDE_FROM_ABI
21432143# endif
2144- _LIBCPP_DEPRECATED_ (" use __grow_by_without_replace" ) void __grow_by (
2145- size_type __old_cap,
2146- size_type __delta_cap,
2147- size_type __old_sz,
2148- size_type __n_copy,
2149- size_type __n_del,
2150- size_type __n_add = 0 );
2151- _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __grow_by_without_replace (
2144+ _LIBCPP_DEPRECATED_ (" use __grow_to" ) void __grow_by (
21522145 size_type __old_cap,
21532146 size_type __delta_cap,
21542147 size_type __old_sz,
21552148 size_type __n_copy,
21562149 size_type __n_del,
21572150 size_type __n_add = 0 );
2151+ _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void
2152+ __grow_to (size_type __new_cap, size_type __n_copy, size_type __n_del, size_type __n_add = 0 );
21582153 _LIBCPP_CONSTEXPR_SINCE_CXX20 void __grow_by_and_replace (
21592154 size_type __old_cap,
21602155 size_type __delta_cap,
@@ -2164,6 +2159,22 @@ private:
21642159 size_type __n_add,
21652160 const value_type* __p_new_stuff);
21662161
2162+ // Allocate a new buffer of size __new_cap and copy data from the old buffer from
2163+ // [old_buffer, old_buffer + __hole_loc) into [new_buffer, new_buffer + __hole_loc) and
2164+ // [old_buffer + __hole_loc) into [new_buffer + __hole_loc + __hole_size).
2165+ //
2166+ // This means that all the data from the old buffer is copied into the new one, but an uninitialized area
2167+ // [new_buffer + __hole_loc, new_buffer + __hole_loc + __hole_size) is there as well, allowing insertion operations
2168+ _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void
2169+ __grow_to_with_hole (size_type __new_cap, size_type __hole_loc, size_type __hole_size) {
2170+ __grow_to (__new_cap, __hole_loc, 0 , __hole_size);
2171+ }
2172+
2173+ // Allocate a new buffer of size __capacity and replace the old one with it, but do not copy any data
2174+ _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __uninitialized_reallocate (size_type __capacity) {
2175+ __grow_to (__capacity, 0 , size ());
2176+ }
2177+
21672178 // __assign_no_alias is invoked for assignment operations where we
21682179 // have proof that the input does not alias the current instance.
21692180 // For example, operator=(basic_string) performs a 'self' check.
@@ -2559,7 +2570,7 @@ void _LIBCPP_CONSTEXPR_SINCE_CXX20
25592570# if _LIBCPP_ABI_VERSION >= 2 // We want to use the function in the dylib in ABIv1
25602571_LIBCPP_HIDE_FROM_ABI
25612572# endif
2562- _LIBCPP_DEPRECATED_ ( " use __grow_by_without_replace " ) basic_string<_CharT, _Traits, _Allocator>::__grow_by (
2573+ basic_string<_CharT, _Traits, _Allocator>::__grow_by (
25632574 size_type __old_cap,
25642575 size_type __delta_cap,
25652576 size_type __old_sz,
@@ -2588,18 +2599,15 @@ _LIBCPP_DEPRECATED_("use __grow_by_without_replace") basic_string<_CharT, _Trait
25882599}
25892600
25902601template <class _CharT , class _Traits , class _Allocator >
2591- void _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
2592- basic_string<_CharT, _Traits, _Allocator>::__grow_by_without_replace (
2593- size_type __old_cap,
2594- size_type __delta_cap,
2595- size_type __old_sz,
2596- size_type __n_copy,
2597- size_type __n_del,
2598- size_type __n_add) {
2602+ void _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI basic_string<_CharT, _Traits, _Allocator>::__grow_to (
2603+ size_type __new_cap, size_type __n_copy, size_type __n_del, size_type __n_add) {
25992604 __annotate_delete ();
26002605 auto __guard = std::__make_scope_guard (__annotate_new_size (*this ));
2606+
2607+ auto __old_cap = capacity ();
2608+ auto __old_sz = size ();
26012609 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
2602- __grow_by (__old_cap, __delta_cap , __old_sz, __n_copy, __n_del, __n_add);
2610+ __grow_by (__old_cap, __new_cap - __old_cap , __old_sz, __n_copy, __n_del, __n_add);
26032611 _LIBCPP_SUPPRESS_DEPRECATED_POP
26042612 __set_long_size (__old_sz - __n_del + __n_add);
26052613}
@@ -2660,7 +2668,7 @@ basic_string<_CharT, _Traits, _Allocator>::assign(size_type __n, value_type __c)
26602668 size_type __old_size = size ();
26612669 if (__cap < __n) {
26622670 size_type __sz = size ();
2663- __grow_by_without_replace (__cap, __n - __cap, __sz, 0 , __sz );
2671+ __uninitialized_reallocate ( __n);
26642672 __annotate_increase (__n);
26652673 } else if (__n > __old_size)
26662674 __annotate_increase (__n - __old_size);
@@ -2819,8 +2827,7 @@ basic_string<_CharT, _Traits, _Allocator>::__assign_trivial(_Iterator __first, _
28192827 // thus no reallocation would happen.
28202828 // 2. In the exotic case where the input range is the byte representation of the string itself, the string
28212829 // object itself stays valid even if reallocation happens.
2822- size_type __sz = size ();
2823- __grow_by_without_replace (__cap, __n - __cap, __sz, 0 , __sz);
2830+ __uninitialized_reallocate (__n);
28242831 __annotate_increase (__n);
28252832 } else if (__n > __old_size)
28262833 __annotate_increase (__n - __old_size);
@@ -2899,8 +2906,7 @@ basic_string<_CharT, _Traits, _Allocator>::append(size_type __n, value_type __c)
28992906 if (__n) {
29002907 size_type __cap = capacity ();
29012908 size_type __sz = size ();
2902- if (__cap - __sz < __n)
2903- __grow_by_without_replace (__cap, __sz + __n - __cap, __sz, __sz, 0 );
2909+ reserve (__sz + __n);
29042910 __annotate_increase (__n);
29052911 pointer __p = __get_pointer ();
29062912 traits_type::assign (std::__to_address (__p) + __sz, __n, __c);
@@ -2917,8 +2923,7 @@ basic_string<_CharT, _Traits, _Allocator>::__append_default_init(size_type __n)
29172923 if (__n) {
29182924 size_type __cap = capacity ();
29192925 size_type __sz = size ();
2920- if (__cap - __sz < __n)
2921- __grow_by_without_replace (__cap, __sz + __n - __cap, __sz, __sz, 0 );
2926+ reserve (__sz + __n);
29222927 __annotate_increase (__n);
29232928 pointer __p = __get_pointer ();
29242929 __sz += __n;
@@ -2940,7 +2945,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 void basic_string<_CharT, _Traits, _Allocator>::pu
29402945 __sz = __get_long_size ();
29412946 }
29422947 if (__sz == __cap) {
2943- __grow_by_without_replace (__cap, 1 , __sz, __sz, 0 );
2948+ reserve (__cap + 1 );
29442949 __annotate_increase (1 );
29452950 __is_short = false ; // the string is always long after __grow_by
29462951 } else
@@ -2966,8 +2971,7 @@ basic_string<_CharT, _Traits, _Allocator>::append(_ForwardIterator __first, _For
29662971 size_type __n = static_cast <size_type>(std::distance (__first, __last));
29672972 if (__n) {
29682973 if (__string_is_trivial_iterator<_ForwardIterator>::value && !__addr_in_range (*__first)) {
2969- if (__cap - __sz < __n)
2970- __grow_by_without_replace (__cap, __sz + __n - __cap, __sz, __sz, 0 );
2974+ reserve (__sz + __n);
29712975 __annotate_increase (__n);
29722976 auto __end = __copy_non_overlapping_range (__first, __last, std::__to_address (__get_pointer () + __sz));
29732977 traits_type::assign (*__end, value_type ());
@@ -3056,7 +3060,7 @@ basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, size_type __n
30563060 if (__n_move != 0 )
30573061 traits_type::move (__p + __pos + __n, __p + __pos, __n_move);
30583062 } else {
3059- __grow_by_without_replace (__cap, __sz + __n - __cap, __sz, __pos, 0 , __n);
3063+ __grow_to_with_hole ( __sz + __n, __pos, __n);
30603064 __p = std::__to_address (__get_long_pointer ());
30613065 }
30623066 traits_type::assign (__p + __pos, __n, __c);
@@ -3140,7 +3144,7 @@ basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, value_ty
31403144 size_type __cap = capacity ();
31413145 value_type* __p;
31423146 if (__cap == __sz) {
3143- __grow_by_without_replace (__cap, 1 , __sz, __ip, 0 , 1 );
3147+ __grow_to_with_hole (__cap + 1 , __ip, 1 );
31443148 __p = std::__to_address (__get_long_pointer ());
31453149 } else {
31463150 __annotate_increase (1 );
@@ -3221,7 +3225,7 @@ basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __
32213225 traits_type::move (__p + __pos + __n2, __p + __pos + __n1, __n_move);
32223226 }
32233227 } else {
3224- __grow_by_without_replace (__cap, __sz - __n1 + __n2 - __cap, __sz , __pos, __n1, __n2);
3228+ __grow_to ( __sz - __n1 + __n2, __pos, __n1, __n2);
32253229 __p = std::__to_address (__get_long_pointer ());
32263230 }
32273231 traits_type::assign (__p + __pos, __n2, __c);
0 commit comments