[libcxx-commits] [libcxx] 05443a9 - [libc++] Refactor how we do amortized growth (#171117)
via libcxx-commits
libcxx-commits at lists.llvm.org
Tue Jan 27 05:27:52 PST 2026
Author: Nikolas Klauser
Date: 2026-01-27T14:27:48+01:00
New Revision: 05443a9807bca50e8dee8936f10b5d574a981e83
URL: https://github.com/llvm/llvm-project/commit/05443a9807bca50e8dee8936f10b5d574a981e83
DIFF: https://github.com/llvm/llvm-project/commit/05443a9807bca50e8dee8936f10b5d574a981e83.diff
LOG: [libc++] Refactor how we do amortized growth (#171117)
When doing amortized growth we currently have separate functions for
calculating the new capacity and allocating. However, we set the size to
the calculated capacity that way instead of the actually required size.
This makes the interface quite confusing, since the size has to be set
manually. Instead, this patch refactors the function to get the
amortized growth capacity to instead allocate and set the size
correctly.
Added:
Modified:
libcxx/include/string
Removed:
################################################################################
diff --git a/libcxx/include/string b/libcxx/include/string
index 1ced528135b97..b7c7a5a1462b5 100644
--- a/libcxx/include/string
+++ b/libcxx/include/string
@@ -2257,17 +2257,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.
@@ -2713,7 +2720,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));
@@ -2746,7 +2753,7 @@ _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));
+ __long __buffer = __allocate_long_buffer(__alloc_, 0, __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);
@@ -2755,7 +2762,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;
@@ -3404,8 +3410,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