[libcxx-commits] [libcxx] [libc++] Make __allocate_long_buffer a constructor of __long (PR #166451)

Nikolas Klauser via libcxx-commits libcxx-commits at lists.llvm.org
Mon Nov 10 02:28:55 PST 2025


https://github.com/philnik777 updated https://github.com/llvm/llvm-project/pull/166451

>From 4a9bb8e48c47c3f287d67a32f91f0aec6d27d831 Mon Sep 17 00:00:00 2001
From: Nikolas Klauser <nikolasklauser at berlin.de>
Date: Tue, 4 Nov 2025 22:47:43 +0100
Subject: [PATCH] [libc++] Make __allocate_long_buffer a constructor of __long

---
 libcxx/include/string | 42 +++++++++++++++++++-----------------------
 1 file changed, 19 insertions(+), 23 deletions(-)

diff --git a/libcxx/include/string b/libcxx/include/string
index ede42467b99fe..8318190330713 100644
--- a/libcxx/include/string
+++ b/libcxx/include/string
@@ -884,9 +884,18 @@ private:
   struct __long {
     __long() = default;
 
-    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __long(__alloc_result __alloc, size_type __size)
-        : __is_long_(true), __cap_(__alloc.count / __endian_factor), __size_(__size), __data_(__alloc.ptr) {
-      _LIBCPP_ASSERT_INTERNAL(!__fits_in_sso(__alloc.count), "Long capacity should always be larger than the SSO");
+    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __long(_Allocator& __alloc, size_type __size)
+        : __is_long_(true), __size_(__size) {
+      _LIBCPP_ASSERT_INTERNAL(!__fits_in_sso(__size), "Long capacity should always be larger than the SSO");
+      auto __allocation = std::__allocate_at_least(__alloc, __recommend(__size) + 1);
+
+      __cap_  = __allocation.count / __endian_factor;
+      __data_ = __allocation.ptr;
+
+      if (__libcpp_is_constant_evaluated()) {
+        for (size_type __i = 0; __i != __allocation.count; ++__i)
+          std::__construct_at(std::addressof(__allocation.ptr[__i]));
+      }
     }
 
     struct _LIBCPP_PACKED {
@@ -2255,19 +2264,6 @@ private:
   // These functions are only responsible for managing the buffer itself, not the value inside the buffer. As such,
   // none of these facilities ensure that there is a null terminator at `data()[size()]`.
 
-  // 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);
-
-    if (__libcpp_is_constant_evaluated()) {
-      for (size_type __i = 0; __i != __buffer.count; ++__i)
-        std::__construct_at(std::addressof(__buffer.ptr[__i]));
-    }
-
-    return __long(__buffer, __capacity);
-  }
-
   // Replace the current buffer with __new_rep. Deallocate the old long buffer if it exists.
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __reset_internal_buffer(__rep __new_rep = __short()) {
     __annotate_delete();
@@ -2290,7 +2286,7 @@ private:
       __annotate_new(__size);
       return __get_short_pointer();
     } else {
-      __rep_.__l = __allocate_long_buffer(__alloc_, __size);
+      __rep_ = __long(__alloc_, __size);
       __annotate_new(__size);
       return __get_long_pointer();
     }
@@ -2447,7 +2443,7 @@ private:
         __annotate_delete();
         auto __guard = std::__make_scope_guard(__annotate_new_size(*this));
         auto __alloc = __str.__alloc_;
-        __reset_internal_buffer(__allocate_long_buffer(__alloc, __str.size()));
+        __reset_internal_buffer(__long(__alloc, __str.size()));
         __alloc_ = std::move(__alloc);
       }
     }
@@ -2700,8 +2696,8 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 void basic_string<_CharT, _Traits, _Allocator>::__
   size_type __cap =
       __old_cap < __ms / 2 - __alignment ? __recommend(std::max(__old_cap + __delta_cap, 2 * __old_cap)) : __ms;
   __annotate_delete();
-  auto __guard    = std::__make_scope_guard(__annotate_new_size(*this));
-  __long __buffer = __allocate_long_buffer(__alloc_, __cap);
+  auto __guard = std::__make_scope_guard(__annotate_new_size(*this));
+  __long __buffer(__alloc_, __cap);
   if (__n_copy != 0)
     traits_type::copy(std::__to_address(__buffer.__data_), std::__to_address(__old_p), __n_copy);
   if (__n_add != 0)
@@ -2737,7 +2733,7 @@ _LIBCPP_DEPRECATED_("use __grow_by_without_replace") basic_string<_CharT, _Trait
   pointer __old_p = __get_pointer();
   size_type __cap =
       __old_cap < __ms / 2 - __alignment ? __recommend(std::max(__old_cap + __delta_cap, 2 * __old_cap)) : __ms;
-  __long __buffer = __allocate_long_buffer(__alloc_, __cap);
+  __long __buffer(__alloc_, __cap);
   if (__n_copy != 0)
     traits_type::copy(std::__to_address(__buffer.__data_), std::__to_address(__old_p), __n_copy);
   size_type __sec_cp_sz = __old_sz - __n_del - __n_copy;
@@ -3394,7 +3390,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 void basic_string<_CharT, _Traits, _Allocator>::re
     return;
 
   __annotation_guard __g(*this);
-  __long __buffer  = __allocate_long_buffer(__alloc_, __requested_capacity);
+  __long __buffer(__alloc_, __requested_capacity);
   __buffer.__size_ = size();
   traits_type::copy(std::__to_address(__buffer.__data_), data(), __buffer.__size_ + 1);
   __reset_internal_buffer(__buffer);
@@ -3425,7 +3421,7 @@ inline _LIBCPP_CONSTEXPR_SINCE_CXX20 void basic_string<_CharT, _Traits, _Allocat
   try {
 #  endif // _LIBCPP_HAS_EXCEPTIONS
     __annotation_guard __g(*this);
-    __long __buffer = __allocate_long_buffer(__alloc_, __size);
+    __long __buffer(__alloc_, __size);
 
     // The Standard mandates shrink_to_fit() does not increase the capacity.
     // With equal capacity keep the existing buffer. This avoids extra work



More information about the libcxx-commits mailing list