Skip to content

Commit 2d08446

Browse files
committed
[libc++] Refactor basic_string::__grow_by calls
This patch introduces a few wrapper functions around `__grow_by` to make it clearer what the intention of the different calls is. Later these can probably be implemented in a simpler manner than `__grow_by`.
1 parent 4562efc commit 2d08446

File tree

1 file changed

+36
-32
lines changed

1 file changed

+36
-32
lines changed

libcxx/include/string

Lines changed: 36 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -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

25902601
template <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

Comments
 (0)