Skip to content

Commit bcfe101

Browse files
committed
[libc++] Refactor basic_string::__recommend
1 parent eca6144 commit bcfe101

File tree

1 file changed

+19
-18
lines changed

1 file changed

+19
-18
lines changed

libcxx/include/string

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2249,7 +2249,9 @@ private:
22492249
// Allocate a buffer of __capacity size with __alloc and return it
22502250
_LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX20 __long
22512251
__allocate_long_buffer(_Allocator& __alloc, size_type __capacity) {
2252-
auto __buffer = std::__allocate_at_least(__alloc, __recommend(__capacity) + 1);
2252+
_LIBCPP_ASSERT_INTERNAL(!__fits_in_sso(__capacity),
2253+
"Trying to allocate long buffer for a capacity what would fit into the small buffer");
2254+
auto __buffer = std::__allocate_at_least(__alloc, __align_allocation_size(__capacity));
22532255

22542256
if (__libcpp_is_constant_evaluated()) {
22552257
for (size_type __i = 0; __i != __buffer.count; ++__i)
@@ -2347,16 +2349,17 @@ private:
23472349
return (__s + (__a - 1)) & ~(__a - 1);
23482350
}
23492351
enum { __alignment = 8 };
2350-
static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type __recommend(size_type __s) _NOEXCEPT {
2351-
if (__s < __min_cap) {
2352-
return static_cast<size_type>(__min_cap) - 1;
2353-
}
2352+
2353+
_LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
2354+
__align_allocation_size(size_type __size) _NOEXCEPT {
2355+
_LIBCPP_ASSERT_INTERNAL(
2356+
!__fits_in_sso(__size), "Trying to align allocation of a size which would fit into the SSO");
23542357
const size_type __boundary = sizeof(value_type) < __alignment ? __alignment / sizeof(value_type) : __endian_factor;
2355-
size_type __guess = __align_it<__boundary>(__s + 1) - 1;
2356-
if (__guess == __min_cap)
2358+
size_type __guess = __align_it<__boundary>(__size + 1);
2359+
if (__guess == __min_cap + 1)
23572360
__guess += __endian_factor;
23582361

2359-
_LIBCPP_ASSERT_INTERNAL(__guess >= __s, "recommendation is below the requested size");
2362+
_LIBCPP_ASSERT_INTERNAL(__guess >= __size, "aligned allocation size is below the requested size");
23602363
return __guess;
23612364
}
23622365

@@ -2694,8 +2697,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 void basic_string<_CharT, _Traits, _Allocator>::__
26942697
if (__delta_cap > __ms - __old_cap)
26952698
__throw_length_error();
26962699
pointer __old_p = __get_pointer();
2697-
size_type __cap =
2698-
__old_cap < __ms / 2 - __alignment ? __recommend(std::max(__old_cap + __delta_cap, 2 * __old_cap)) : __ms;
2700+
size_type __cap = __old_cap < __ms / 2 - __alignment ? std::max(__old_cap + __delta_cap, 2 * __old_cap) : __ms;
26992701
__annotate_delete();
27002702
auto __guard = std::__make_scope_guard(__annotate_new_size(*this));
27012703
__long __buffer = __allocate_long_buffer(__alloc_, __cap);
@@ -2732,8 +2734,7 @@ _LIBCPP_DEPRECATED_("use __grow_by_without_replace") basic_string<_CharT, _Trait
27322734
if (__delta_cap > __ms - __old_cap)
27332735
this->__throw_length_error();
27342736
pointer __old_p = __get_pointer();
2735-
size_type __cap =
2736-
__old_cap < __ms / 2 - __alignment ? __recommend(std::max(__old_cap + __delta_cap, 2 * __old_cap)) : __ms;
2737+
size_type __cap = __old_cap < __ms / 2 - __alignment ? std::max(__old_cap + __delta_cap, 2 * __old_cap) : __ms;
27372738
__long __buffer = __allocate_long_buffer(__alloc_, __cap);
27382739
if (__n_copy != 0)
27392740
traits_type::copy(std::__to_address(__buffer.__data_), std::__to_address(__old_p), __n_copy);
@@ -3399,25 +3400,25 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 void basic_string<_CharT, _Traits, _Allocator>::re
33993400

34003401
template <class _CharT, class _Traits, class _Allocator>
34013402
inline _LIBCPP_CONSTEXPR_SINCE_CXX20 void basic_string<_CharT, _Traits, _Allocator>::shrink_to_fit() _NOEXCEPT {
3402-
size_type __target_capacity = __recommend(size());
3403-
if (__target_capacity == capacity())
3403+
if (!__is_long())
34043404
return;
34053405

3406-
_LIBCPP_ASSERT_INTERNAL(__is_long(), "Trying to shrink small string");
3407-
3408-
// We're a long string and we're shrinking into the small buffer.
34093406
const auto __ptr = __get_long_pointer();
34103407
const auto __size = __get_long_size();
34113408
const auto __cap = __get_long_cap();
34123409

3413-
if (__fits_in_sso(__target_capacity)) {
3410+
// We're a long string and we're shrinking into the small buffer.
3411+
if (__fits_in_sso(__size)) {
34143412
__annotation_guard __g(*this);
34153413
__set_short_size(__size);
34163414
traits_type::copy(std::__to_address(__get_short_pointer()), std::__to_address(__ptr), __size + 1);
34173415
__alloc_traits::deallocate(__alloc_, __ptr, __cap);
34183416
return;
34193417
}
34203418

3419+
if (__align_allocation_size(__size) == __cap)
3420+
return;
3421+
34213422
# if _LIBCPP_HAS_EXCEPTIONS
34223423
try {
34233424
# endif // _LIBCPP_HAS_EXCEPTIONS

0 commit comments

Comments
 (0)