@@ -2246,7 +2246,9 @@ private:
22462246 // Allocate a buffer of __capacity size with __alloc and return it
22472247 _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX20 __long
22482248 __allocate_long_buffer (_Allocator& __alloc, size_type __capacity) {
2249- auto __buffer = std::__allocate_at_least (__alloc, __recommend (__capacity) + 1 );
2249+ _LIBCPP_ASSERT_INTERNAL (!__fits_in_sso (__capacity),
2250+ " Trying to allocate long buffer for a capacity what would fit into the small buffer" );
2251+ auto __buffer = std::__allocate_at_least (__alloc, __align_allocation_size (__capacity));
22502252
22512253 if (__libcpp_is_constant_evaluated ()) {
22522254 for (size_type __i = 0 ; __i != __buffer.count ; ++__i)
@@ -2344,16 +2346,16 @@ private:
23442346 return (__s + (__a - 1 )) & ~(__a - 1 );
23452347 }
23462348 enum { __alignment = 8 };
2347- static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type __recommend (size_type __s) _NOEXCEPT {
2348- if (__s < __min_cap) {
2349- return static_cast <size_type>(__min_cap) - 1 ;
2350- }
2349+
2350+ _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
2351+ __align_allocation_size (size_type __size) _NOEXCEPT {
2352+ _LIBCPP_ASSERT_INTERNAL (__size > __min_cap, " Trying to align allocation of a size which would fit into the SSO " );
23512353 const size_type __boundary = sizeof (value_type) < __alignment ? __alignment / sizeof (value_type) : __endian_factor;
2352- size_type __guess = __align_it<__boundary>(__s + 1 ) - 1 ;
2353- if (__guess == __min_cap)
2354+ size_type __guess = __align_it<__boundary>(__size + 1 );
2355+ if (__guess == __min_cap + 1 )
23542356 __guess += __endian_factor;
23552357
2356- _LIBCPP_ASSERT_INTERNAL (__guess >= __s , " recommendation is below the requested size" );
2358+ _LIBCPP_ASSERT_INTERNAL (__guess >= __size , " aligned allocation size is below the requested size" );
23572359 return __guess;
23582360 }
23592361
@@ -2705,8 +2707,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 void basic_string<_CharT, _Traits, _Allocator>::__
27052707 if (__delta_cap > __ms - __old_cap)
27062708 __throw_length_error ();
27072709 pointer __old_p = __get_pointer ();
2708- size_type __cap =
2709- __old_cap < __ms / 2 - __alignment ? __recommend (std::max (__old_cap + __delta_cap, 2 * __old_cap)) : __ms;
2710+ size_type __cap = __old_cap < __ms / 2 - __alignment ? std::max (__old_cap + __delta_cap, 2 * __old_cap) : __ms;
27102711 __annotate_delete ();
27112712 auto __guard = std::__make_scope_guard (__annotate_new_size (*this ));
27122713 __long __buffer = __allocate_long_buffer (__alloc_, __cap);
@@ -2743,8 +2744,7 @@ _LIBCPP_DEPRECATED_("use __grow_by_without_replace") basic_string<_CharT, _Trait
27432744 if (__delta_cap > __ms - __old_cap)
27442745 this ->__throw_length_error ();
27452746 pointer __old_p = __get_pointer ();
2746- size_type __cap =
2747- __old_cap < __ms / 2 - __alignment ? __recommend (std::max (__old_cap + __delta_cap, 2 * __old_cap)) : __ms;
2747+ size_type __cap = __old_cap < __ms / 2 - __alignment ? std::max (__old_cap + __delta_cap, 2 * __old_cap) : __ms;
27482748 __long __buffer = __allocate_long_buffer (__alloc_, __cap);
27492749 if (__n_copy != 0 )
27502750 traits_type::copy (std::__to_address (__buffer.__data_ ), std::__to_address (__old_p), __n_copy);
@@ -3410,25 +3410,25 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 void basic_string<_CharT, _Traits, _Allocator>::re
34103410
34113411template <class _CharT , class _Traits , class _Allocator >
34123412inline _LIBCPP_CONSTEXPR_SINCE_CXX20 void basic_string<_CharT, _Traits, _Allocator>::shrink_to_fit () _NOEXCEPT {
3413- size_type __target_capacity = __recommend (size ());
3414- if (__target_capacity == capacity ())
3413+ if (!__is_long ())
34153414 return ;
34163415
3417- _LIBCPP_ASSERT_INTERNAL (__is_long (), " Trying to shrink small string" );
3418-
3419- // We're a long string and we're shrinking into the small buffer.
34203416 const auto __ptr = __get_long_pointer ();
34213417 const auto __size = __get_long_size ();
34223418 const auto __cap = __get_long_cap ();
34233419
3424- if (__fits_in_sso (__target_capacity)) {
3420+ // We're a long string and we're shrinking into the small buffer.
3421+ if (__fits_in_sso (__size)) {
34253422 __annotation_guard __g (*this );
34263423 __set_short_size (__size);
34273424 traits_type::copy (std::__to_address (__get_short_pointer ()), std::__to_address (__ptr), __size + 1 );
34283425 __alloc_traits::deallocate (__alloc_, __ptr, __cap);
34293426 return ;
34303427 }
34313428
3429+ if (__align_allocation_size (__size) == __cap)
3430+ return ;
3431+
34323432# if _LIBCPP_HAS_EXCEPTIONS
34333433 try {
34343434# endif // _LIBCPP_HAS_EXCEPTIONS
0 commit comments