@@ -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