Skip to content

Conversation

philnik777
Copy link
Contributor

This does a couple of things:

  • code that is only useful for shrink_to_fit is moved into that function
  • shrink_to_fit is simplified a bit
  • __recommend is renamed to better reflect what the function actually does
  • __allocate_long_buffer asserts that the passed capacity doesn't fit into the SSO

@philnik777 philnik777 requested a review from a team as a code owner October 9, 2025 10:33
@llvmbot llvmbot added the libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi. label Oct 9, 2025
@llvmbot
Copy link
Member

llvmbot commented Oct 9, 2025

@llvm/pr-subscribers-libcxx

Author: Nikolas Klauser (philnik777)

Changes

This does a couple of things:

  • code that is only useful for shrink_to_fit is moved into that function
  • shrink_to_fit is simplified a bit
  • __recommend is renamed to better reflect what the function actually does
  • __allocate_long_buffer asserts that the passed capacity doesn't fit into the SSO

Full diff: https://github.com/llvm/llvm-project/pull/162631.diff

1 Files Affected:

  • (modified) libcxx/include/string (+10-12)
diff --git a/libcxx/include/string b/libcxx/include/string
index 363f27a51648c..f1e817a90c9ba 100644
--- a/libcxx/include/string
+++ b/libcxx/include/string
@@ -2246,7 +2246,9 @@ private:
   // Allocate a buffer of __capacity size with __alloc and return it
   _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX20 __long
   __allocate_long_buffer(_Allocator& __alloc, size_type __capacity) {
-    auto __buffer = std::__allocate_at_least(__alloc, __recommend(__capacity) + 1);
+    _LIBCPP_ASSERT_INTERNAL(
+        !__fits_in_sso(__capacity), "Trying to allocate long buffer which fits into the small buffer");
+    auto __buffer = std::__allocate_at_least(__alloc, __align_allocation_size(__capacity) + 1);
 
     if (__libcpp_is_constant_evaluated()) {
       for (size_type __i = 0; __i != __buffer.count; ++__i)
@@ -2344,16 +2346,15 @@ private:
     return (__s + (__a - 1)) & ~(__a - 1);
   }
   enum { __alignment = 8 };
-  static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type __recommend(size_type __s) _NOEXCEPT {
-    if (__s < __min_cap) {
-      return static_cast<size_type>(__min_cap) - 1;
-    }
+
+  _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
+  __align_allocation_size(size_type __size) _NOEXCEPT {
     const size_type __boundary = sizeof(value_type) < __alignment ? __alignment / sizeof(value_type) : __endian_factor;
-    size_type __guess          = __align_it<__boundary>(__s + 1) - 1;
+    size_type __guess          = __align_it<__boundary>(__size + 1) - 1;
     if (__guess == __min_cap)
       __guess += __endian_factor;
 
-    _LIBCPP_ASSERT_INTERNAL(__guess >= __s, "recommendation is below the requested size");
+    _LIBCPP_ASSERT_INTERNAL(__guess >= __size, "aligned allocation size is below the requested size");
     return __guess;
   }
 
@@ -3410,18 +3411,15 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 void basic_string<_CharT, _Traits, _Allocator>::re
 
 template <class _CharT, class _Traits, class _Allocator>
 inline _LIBCPP_CONSTEXPR_SINCE_CXX20 void basic_string<_CharT, _Traits, _Allocator>::shrink_to_fit() _NOEXCEPT {
-  size_type __target_capacity = __recommend(size());
-  if (__target_capacity == capacity())
+  if (!__is_long())
     return;
 
-  _LIBCPP_ASSERT_INTERNAL(__is_long(), "Trying to shrink small string");
-
   // We're a long string and we're shrinking into the small buffer.
   const auto __ptr  = __get_long_pointer();
   const auto __size = __get_long_size();
   const auto __cap  = __get_long_cap();
 
-  if (__fits_in_sso(__target_capacity)) {
+  if (__fits_in_sso(__align_allocation_size(size()))) {
     __annotation_guard __g(*this);
     __set_short_size(__size);
     traits_type::copy(std::__to_address(__get_short_pointer()), std::__to_address(__ptr), __size + 1);

@philnik777 philnik777 force-pushed the string_rename_recommend branch from 763312f to e78553f Compare October 13, 2025 09:41
@philnik777 philnik777 force-pushed the string_rename_recommend branch from e78553f to 9a38a2a Compare October 15, 2025 10:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants