[libcxx-commits] [libcxx] [libc++] Refactor how we do amortized growth (PR #171117)
Nikolas Klauser via libcxx-commits
libcxx-commits at lists.llvm.org
Fri Jan 23 04:38:44 PST 2026
https://github.com/philnik777 updated https://github.com/llvm/llvm-project/pull/171117
>From 29c7d38b77b55e42966bf0d80fccbe330415d6a5 Mon Sep 17 00:00:00 2001
From: Nikolas Klauser <nikolasklauser at berlin.de>
Date: Mon, 8 Dec 2025 13:07:30 +0100
Subject: [PATCH] [libc++] Refactor how we do amortized growth
---
libcxx/include/string | 28 ++++++++++++++++------------
1 file changed, 16 insertions(+), 12 deletions(-)
diff --git a/libcxx/include/string b/libcxx/include/string
index 34af7efb56659..8508ccf68b085 100644
--- a/libcxx/include/string
+++ b/libcxx/include/string
@@ -2272,17 +2272,24 @@ 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) {
- _LIBCPP_ASSERT_INTERNAL(!__fits_in_sso(__capacity),
+ __allocate_long_buffer(_Allocator& __alloc, size_type __size, size_type __min_capacity) {
+ _LIBCPP_ASSERT_INTERNAL(
+ __size <= __min_capacity, "Trying to allocate a long buffer with a smaller capacity than size");
+ _LIBCPP_ASSERT_INTERNAL(!__fits_in_sso(__min_capacity),
"Trying to allocate long buffer for a capacity what would fit into the small buffer");
- auto __buffer = std::__allocate_at_least(__alloc, __align_allocation_size(__capacity));
+ auto __buffer = std::__allocate_at_least(__alloc, __align_allocation_size(__min_capacity));
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);
+ return __long(__buffer, __size);
+ }
+
+ _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX20 __long
+ __allocate_long_buffer(_Allocator& __alloc, size_type __size) {
+ return __allocate_long_buffer(__alloc, __size, __size);
}
// Replace the current buffer with __new_rep. Deallocate the old long buffer if it exists.
@@ -2728,7 +2735,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 void basic_string<_CharT, _Traits, _Allocator>::__
size_type __n_del,
size_type __n_add,
const value_type* __p_new_stuff) {
- __long __buffer = __allocate_long_buffer(__alloc_, __get_amortized_growth_capacity(__old_cap + __delta_cap));
+ __long __buffer = __allocate_long_buffer(__alloc_, 0, __get_amortized_growth_capacity(__old_cap + __delta_cap));
pointer __old_p = __get_pointer();
__annotate_delete();
auto __guard = std::__make_scope_guard(__annotate_new_size(*this));
@@ -2761,7 +2768,9 @@ _LIBCPP_DEPRECATED_("use __grow_by_without_replace") basic_string<_CharT, _Trait
size_type __n_copy,
size_type __n_del,
size_type __n_add) {
- __long __buffer = __allocate_long_buffer(__alloc_, __get_amortized_growth_capacity(__old_cap + __delta_cap));
+ // The size is -1 to make sure the caller sets the size properly, since old versions of this function didn't set the
+ // size at all.
+ __long __buffer = __allocate_long_buffer(__alloc_, -1, __get_amortized_growth_capacity(__old_cap + __delta_cap));
pointer __old_p = __get_pointer();
if (__n_copy != 0)
traits_type::copy(std::__to_address(__buffer.__data_), std::__to_address(__old_p), __n_copy);
@@ -2770,10 +2779,6 @@ _LIBCPP_DEPRECATED_("use __grow_by_without_replace") basic_string<_CharT, _Trait
traits_type::copy(std::__to_address(__buffer.__data_) + __n_copy + __n_add,
std::__to_address(__old_p) + __n_copy + __n_del,
__sec_cp_sz);
-
- // This is -1 to make sure the caller sets the size properly, since old versions of this function didn't set the size
- // at all.
- __buffer.__size_ = -1;
__reset_internal_buffer(__buffer);
}
@@ -3419,8 +3424,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);
- __buffer.__size_ = size();
+ __long __buffer = __allocate_long_buffer(__alloc_, size(), __requested_capacity);
traits_type::copy(std::__to_address(__buffer.__data_), data(), __buffer.__size_ + 1);
__reset_internal_buffer(__buffer);
}
More information about the libcxx-commits
mailing list