From 957fe99f41748b80c3108447e5dd5ce2be962f4e Mon Sep 17 00:00:00 2001 From: Nathan Ward <43621845+NathanSWard@users.noreply.github.com> Date: Thu, 17 Oct 2019 17:06:27 -0600 Subject: [PATCH] P0966R1 string::reserve() should not shrink (#176) Fixes #42. --- stl/inc/xstring | 22 ++++++++++++++++++++++ stl/inc/yvals_core.h | 19 +++++++++++++++++-- 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/stl/inc/xstring b/stl/inc/xstring index 27295e6d40..82d82d73ac 100644 --- a/stl/inc/xstring +++ b/stl/inc/xstring @@ -3616,6 +3616,27 @@ public: return _Mypair._Myval2._Myres; } +#if _HAS_CXX20 + void reserve(_CRT_GUARDOVERFLOW const size_type _Newcap) { // determine new minimum length of allocated storage + if (_Mypair._Myval2._Myres >= _Newcap) { // requested capacity is not larger than current capacity, ignore + return; // nothing to do + } + + const size_type _Old_size = _Mypair._Myval2._Mysize; + _Reallocate_grow_by( + _Newcap - _Old_size, [](_Elem* const _New_ptr, const _Elem* const _Old_ptr, const size_type _Old_size) { + _Traits::copy(_New_ptr, _Old_ptr, _Old_size + 1); + }); + + _Mypair._Myval2._Mysize = _Old_size; + } + + _CXX20_DEPRECATE_STRING_RESERVE_WITHOUT_ARGUMENT void reserve() { + if (_Mypair._Myval2._Mysize == 0 && _Mypair._Myval2._Large_string_engaged()) { + _Become_small(); + } + } +#else // _HAS_CXX20 void reserve(_CRT_GUARDOVERFLOW const size_type _Newcap = 0) { // determine new minimum length of allocated storage if (_Mypair._Myval2._Mysize > _Newcap) { // requested capacity is not large enough for current size, ignore return; // nothing to do @@ -3644,6 +3665,7 @@ public: // ignore requests to reserve to [_BUF_SIZE, _Myres) } +#endif // _HAS_CXX20 _NODISCARD bool empty() const noexcept { return size() == 0; diff --git a/stl/inc/yvals_core.h b/stl/inc/yvals_core.h index 1937ed44fa..e8c89e468a 100644 --- a/stl/inc/yvals_core.h +++ b/stl/inc/yvals_core.h @@ -44,6 +44,7 @@ // (partially implemented) // P0898R3 Standard Library Concepts // P0919R3 Heterogeneous Lookup For Unordered Containers +// P0966R1 string::reserve() Should Not Shrink // P1227R2 Signed std::ssize(), Unsigned span::size() // (partially implemented) // P1357R1 is_bounded_array, is_unbounded_array @@ -412,7 +413,7 @@ #define _CPPLIB_VER 650 #define _MSVC_STL_VERSION 142 -#define _MSVC_STL_UPDATE 201909L +#define _MSVC_STL_UPDATE 201910L #ifndef _ALLOW_COMPILER_AND_STL_VERSION_MISMATCH #ifdef __EDG__ @@ -799,7 +800,21 @@ #define _DEPRECATE_STDEXT_HASH_UPPER_BOUND #endif // ^^^ warning disabled ^^^ -// next warning number: STL4024 +// P0966R1 [depr.string.capacity] +#if _HAS_CXX20 && !defined(_SILENCE_CXX20_STRING_RESERVE_WITHOUT_ARGUMENT_DEPRECATION_WARNING) \ + && !defined(_SILENCE_ALL_CXX20_DEPRECATION_WARNINGS) +#define _CXX20_DEPRECATE_STRING_RESERVE_WITHOUT_ARGUMENT \ + [[deprecated("warning STL4024: " \ + "std::string::reserve() without an argument is deprecated in C++20. " \ + "To shrink the string's capacity, use std::string::shrink_to_fit() instead. Otherwise, provide an " \ + "argument to std::string::reserve(). " \ + "You can define _SILENCE_CXX20_STRING_RESERVE_WITHOUT_ARGUMENT_DEPRECATION_WARNING " \ + "or _SILENCE_ALL_CXX20_DEPRECATION_WARNINGS to acknowledge that you have received this warning.")]] +#else // ^^^ warning enabled / warning disabled vvv +#define _CXX20_DEPRECATE_STRING_RESERVE_WITHOUT_ARGUMENT +#endif // ^^^ warning disabled ^^^ + +// next warning number: STL4025 // LIBRARY FEATURE-TEST MACROS