From 9b0e5906f68481e733ffcdee78db9ab11dc93d10 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Thu, 27 Jul 2023 18:45:21 -0700 Subject: [PATCH] Restore `shrink_to_fit` to allocate exactly. --- stl/inc/xstring | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/stl/inc/xstring b/stl/inc/xstring index f161000e47..de80f3d711 100644 --- a/stl/inc/xstring +++ b/stl/inc/xstring @@ -2606,10 +2606,21 @@ public: } private: + enum class _Reallocation_policy { _At_least, _Exactly }; + + template <_Reallocation_policy _Policy = _Reallocation_policy::_At_least> _NODISCARD static _CONSTEXPR20 pointer _Allocate_for_capacity(_Alty& _Al, size_type& _Capacity) { _STL_INTERNAL_CHECK(_Entails_large_string(_Capacity)); ++_Capacity; // Take null terminator into consideration - const pointer _Fancy_ptr = _Allocate_at_least_helper(_Al, _Capacity); + + pointer _Fancy_ptr; + if constexpr (_Policy == _Reallocation_policy::_At_least) { + _Fancy_ptr = _Allocate_at_least_helper(_Al, _Capacity); + } else { + _STL_INTERNAL_STATIC_ASSERT(_Policy == _Reallocation_policy::_Exactly); + _Fancy_ptr = _Al.allocate(_Capacity); + } + #if _HAS_CXX20 // Start element lifetimes to avoid UB. This is a more general mechanism than _String_val::_Activate_SSO_buffer, // but likely more impactful to throughput. @@ -3993,8 +4004,9 @@ public: size_type _Target_capacity = (_STD min)(_My_data._Mysize | _ALLOC_MASK, max_size()); if (_Target_capacity < _My_data._Myres) { // worth shrinking, do it - auto& _Al = _Getal(); - const pointer _New_ptr = _Allocate_for_capacity(_Al, _Target_capacity); // throws + auto& _Al = _Getal(); + const pointer _New_ptr = + _Allocate_for_capacity<_Reallocation_policy::_Exactly>(_Al, _Target_capacity); // throws _ASAN_STRING_REMOVE(*this); _My_data._Orphan_all();