Skip to content

Commit 4d1a441

Browse files
committed
[libc++] Introduce basic_string::__recommend_growing
1 parent e95c5c8 commit 4d1a441

File tree

1 file changed

+19
-11
lines changed

1 file changed

+19
-11
lines changed

libcxx/include/string

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2285,6 +2285,22 @@ private:
22852285
return __long(__buffer, __capacity);
22862286
}
22872287

2288+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __long
2289+
__allocate_long_buffer_for_growing(_Allocator& __alloc, size_type __required_capacity) {
2290+
auto __growth_capacity = [&] {
2291+
size_type __max_size = max_size();
2292+
if (__required_capacity > __max_size)
2293+
__throw_length_error();
2294+
size_type __current_cap = capacity();
2295+
_LIBCPP_ASSERT_INTERNAL(
2296+
__current_cap < __required_capacity, "Trying to grow string even though there is enough capacity already?");
2297+
if (__current_cap > __max_size / 2 - __alignment)
2298+
return __max_size;
2299+
return std::max(__required_capacity, 2 * __current_cap);
2300+
}();
2301+
return __allocate_long_buffer(__alloc, __growth_capacity);
2302+
}
2303+
22882304
// Replace the current buffer with __new_rep. Deallocate the old long buffer if it exists.
22892305
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __reset_internal_buffer(__rep __new_rep = __short()) {
22902306
__annotate_delete();
@@ -2714,14 +2730,10 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 void basic_string<_CharT, _Traits, _Allocator>::__
27142730
size_type __n_del,
27152731
size_type __n_add,
27162732
const value_type* __p_new_stuff) {
2717-
size_type __ms = max_size();
2718-
if (__delta_cap > __ms - __old_cap)
2719-
__throw_length_error();
2733+
__long __buffer = __allocate_long_buffer_for_growing(__alloc_, __old_cap + __delta_cap);
27202734
pointer __old_p = __get_pointer();
2721-
size_type __cap = __old_cap < __ms / 2 - __alignment ? std::max(__old_cap + __delta_cap, 2 * __old_cap) : __ms;
27222735
__annotate_delete();
2723-
auto __guard = std::__make_scope_guard(__annotate_new_size(*this));
2724-
__long __buffer = __allocate_long_buffer(__alloc_, __cap);
2736+
auto __guard = std::__make_scope_guard(__annotate_new_size(*this));
27252737
if (__n_copy != 0)
27262738
traits_type::copy(std::__to_address(__buffer.__data_), std::__to_address(__old_p), __n_copy);
27272739
if (__n_add != 0)
@@ -2751,12 +2763,8 @@ _LIBCPP_DEPRECATED_("use __grow_by_without_replace") basic_string<_CharT, _Trait
27512763
size_type __n_copy,
27522764
size_type __n_del,
27532765
size_type __n_add) {
2754-
size_type __ms = max_size();
2755-
if (__delta_cap > __ms - __old_cap)
2756-
this->__throw_length_error();
2766+
__long __buffer = __allocate_long_buffer_for_growing(__alloc_, __old_cap + __delta_cap);
27572767
pointer __old_p = __get_pointer();
2758-
size_type __cap = __old_cap < __ms / 2 - __alignment ? std::max(__old_cap + __delta_cap, 2 * __old_cap) : __ms;
2759-
__long __buffer = __allocate_long_buffer(__alloc_, __cap);
27602768
if (__n_copy != 0)
27612769
traits_type::copy(std::__to_address(__buffer.__data_), std::__to_address(__old_p), __n_copy);
27622770
size_type __sec_cp_sz = __old_sz - __n_del - __n_copy;

0 commit comments

Comments
 (0)