From acd082114f53b07a531435c6f85b59002e7a08db Mon Sep 17 00:00:00 2001 From: achabense <60953653+achabense@users.noreply.github.com> Date: Tue, 22 Aug 2023 10:54:09 +0800 Subject: [PATCH 1/6] merge `_Memcpy_val_from` --- stl/inc/xstring | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/stl/inc/xstring b/stl/inc/xstring index ae566f24af..058101ec05 100644 --- a/stl/inc/xstring +++ b/stl/inc/xstring @@ -3010,15 +3010,6 @@ public: } private: - void _Memcpy_val_from(const basic_string& _Right) noexcept { - _STL_INTERNAL_CHECK(_Can_memcpy_val); - const auto _My_data_mem = - reinterpret_cast(_STD addressof(_Mypair._Myval2)) + _Memcpy_val_offset; - const auto _Right_data_mem = - reinterpret_cast(_STD addressof(_Right._Mypair._Myval2)) + _Memcpy_val_offset; - _CSTD memcpy(_My_data_mem, _Right_data_mem, _Memcpy_val_size); - } - _CONSTEXPR20 void _Take_contents(basic_string& _Right) noexcept { // assign by stealing _Right's buffer // pre: this != &_Right @@ -3043,7 +3034,11 @@ private: } #endif // _ITERATOR_DEBUG_LEVEL != 0 - _Memcpy_val_from(_Right); + const auto _My_data_mem = + reinterpret_cast(_STD addressof(_Mypair._Myval2)) + _Memcpy_val_offset; + const auto _Right_data_mem = + reinterpret_cast(_STD addressof(_Right._Mypair._Myval2)) + _Memcpy_val_offset; + _CSTD memcpy(_My_data_mem, _Right_data_mem, _Memcpy_val_size); _Right._Tidy_init(); return; } From f7e81352b762cb05c85f40adc8fda5705019ad4c Mon Sep 17 00:00:00 2001 From: achabense <60953653+achabense@users.noreply.github.com> Date: Tue, 22 Aug 2023 10:59:37 +0800 Subject: [PATCH 2/6] simplify construction from initializer_list --- stl/inc/xstring | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/stl/inc/xstring b/stl/inc/xstring index 058101ec05..83030d42df 100644 --- a/stl/inc/xstring +++ b/stl/inc/xstring @@ -3086,11 +3086,7 @@ private: public: _CONSTEXPR20 basic_string(initializer_list<_Elem> _Ilist, const _Alloc& _Al = allocator_type()) : _Mypair(_One_then_variadic_args_t{}, _Al) { - auto&& _Alproxy = _GET_PROXY_ALLOCATOR(_Alty, _Getal()); - _Container_proxy_ptr<_Alty> _Proxy(_Alproxy, _Mypair._Myval2); - _Tidy_init(); - assign(_Ilist.begin(), _Convert_size(_Ilist.size())); - _Proxy._Release(); + _Construct<_Construct_strategy::_From_ptr>(_Ilist.begin(), _Convert_size(_Ilist.size())); } _CONSTEXPR20 basic_string& operator=(initializer_list<_Elem> _Ilist) { From 6ed3396b03720e8c1504e32130efb5e465f7dd80 Mon Sep 17 00:00:00 2001 From: achabense <60953653+achabense@users.noreply.github.com> Date: Tue, 22 Aug 2023 11:15:28 +0800 Subject: [PATCH 3/6] improve exception guarantee --- stl/inc/xstring | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/stl/inc/xstring b/stl/inc/xstring index 83030d42df..14b574f28f 100644 --- a/stl/inc/xstring +++ b/stl/inc/xstring @@ -3070,12 +3070,12 @@ private: const auto _Right_ptr = _Right_data._Myptr(); auto& _Al = _Getal(); if (_Allocators_equal(_Al, _Right._Getal()) && _Result_size > _Small_string_capacity) { + _Mypair._Myval2._Alloc_proxy(_GET_PROXY_ALLOCATOR(_Alty, _Al)); + if (_Roff != 0) { _Traits::move(_Right_ptr, _Right_ptr + _Roff, _Result_size); } _Right._Eos(_Result_size); - - _Mypair._Myval2._Alloc_proxy(_GET_PROXY_ALLOCATOR(_Alty, _Al)); _Take_contents(_Right); } else { _Construct<_Construct_strategy::_From_ptr>(_Right_ptr + _Roff, _Result_size); From 3cda46d301d8e4d46a5e7c64bc9c7b7ff8d89d10 Mon Sep 17 00:00:00 2001 From: achabense <60953653+achabense@users.noreply.github.com> Date: Tue, 22 Aug 2023 11:09:21 +0800 Subject: [PATCH 4/6] improve usage of `_Calculate_growth` --- stl/inc/xstring | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/stl/inc/xstring b/stl/inc/xstring index 14b574f28f..9e0c1d6526 100644 --- a/stl/inc/xstring +++ b/stl/inc/xstring @@ -2673,8 +2673,7 @@ private: return; } - _My_data._Myres = _Small_string_capacity; - size_type _New_capacity = _Calculate_growth(_Count); + size_type _New_capacity = _Calculate_growth(_Count, _Small_string_capacity, max_size()); const pointer _New_ptr = _Allocate_for_capacity(_Al, _New_capacity); // throws _Construct_in_place(_My_data._Bx._Ptr, _New_ptr); @@ -2731,7 +2730,7 @@ private: } _Elem* const _Old_ptr = _My_data._Myptr(); - size_type _New_capacity = _Calculate_growth(_My_data._Mysize); + size_type _New_capacity = _Calculate_growth(_My_data._Mysize + 1); const pointer _New_ptr = _Allocate_for_capacity(_Al, _New_capacity); // throws _Traits::copy(_Unfancy(_New_ptr), _Old_ptr, _My_data._Mysize); From 14b7558137b24e1f14bfc0a5b38f7862fad67f15 Mon Sep 17 00:00:00 2001 From: achabense <60953653+achabense@users.noreply.github.com> Date: Tue, 22 Aug 2023 21:37:31 +0800 Subject: [PATCH 5/6] noexcept enhancements --- stl/inc/xstring | 39 +++++++++++++++++++++++++-------------- 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/stl/inc/xstring b/stl/inc/xstring index 9e0c1d6526..ad68e987f5 100644 --- a/stl/inc/xstring +++ b/stl/inc/xstring @@ -4791,7 +4791,7 @@ private: return *this; } - _CONSTEXPR20 void _Become_small() { + _CONSTEXPR20 void _Become_small() noexcept { // release any held storage and return to small string mode auto& _My_data = _Mypair._Myval2; _STL_INTERNAL_CHECK(_My_data._Large_mode_engaged()); @@ -5011,7 +5011,7 @@ _NODISCARD _CONSTEXPR20 bool operator==( _EXPORT_STD template _NODISCARD _CONSTEXPR20 bool operator==( - const basic_string<_Elem, _Traits, _Alloc>& _Left, _In_z_ const _Elem* const _Right) { + const basic_string<_Elem, _Traits, _Alloc>& _Left, _In_z_ const _Elem* const _Right) noexcept /* strengthened */ { return _Left._Equal(_Right); } @@ -5024,12 +5024,13 @@ _NODISCARD constexpr _Get_comparison_category_t<_Traits> operator<=>( _EXPORT_STD template _NODISCARD constexpr _Get_comparison_category_t<_Traits> operator<=>( - const basic_string<_Elem, _Traits, _Alloc>& _Left, _In_z_ const _Elem* const _Right) { + const basic_string<_Elem, _Traits, _Alloc>& _Left, _In_z_ const _Elem* const _Right) noexcept /* strengthened */ { return static_cast<_Get_comparison_category_t<_Traits>>(_Left.compare(_Right) <=> 0); } #else // ^^^ _HAS_CXX20 / !_HAS_CXX20 vvv template -_NODISCARD bool operator==(_In_z_ const _Elem* const _Left, const basic_string<_Elem, _Traits, _Alloc>& _Right) { +_NODISCARD bool operator==(_In_z_ const _Elem* const _Left, const basic_string<_Elem, _Traits, _Alloc>& _Right) noexcept +/* strengthened */ { return _Right._Equal(_Left); } @@ -5040,12 +5041,14 @@ _NODISCARD bool operator!=( } template -_NODISCARD bool operator!=(_In_z_ const _Elem* const _Left, const basic_string<_Elem, _Traits, _Alloc>& _Right) { +_NODISCARD bool operator!=(_In_z_ const _Elem* const _Left, const basic_string<_Elem, _Traits, _Alloc>& _Right) noexcept +/* strengthened */ { return !(_Left == _Right); } template -_NODISCARD bool operator!=(const basic_string<_Elem, _Traits, _Alloc>& _Left, _In_z_ const _Elem* const _Right) { +_NODISCARD bool operator!=(const basic_string<_Elem, _Traits, _Alloc>& _Left, _In_z_ const _Elem* const _Right) noexcept +/* strengthened */ { return !(_Left == _Right); } @@ -5056,12 +5059,14 @@ _NODISCARD bool operator<( } template -_NODISCARD bool operator<(_In_z_ const _Elem* const _Left, const basic_string<_Elem, _Traits, _Alloc>& _Right) { +_NODISCARD bool operator<(_In_z_ const _Elem* const _Left, const basic_string<_Elem, _Traits, _Alloc>& _Right) noexcept +/* strengthened */ { return _Right.compare(_Left) > 0; } template -_NODISCARD bool operator<(const basic_string<_Elem, _Traits, _Alloc>& _Left, _In_z_ const _Elem* const _Right) { +_NODISCARD bool operator<(const basic_string<_Elem, _Traits, _Alloc>& _Left, _In_z_ const _Elem* const _Right) noexcept +/* strengthened */ { return _Left.compare(_Right) < 0; } @@ -5072,12 +5077,14 @@ _NODISCARD bool operator>( } template -_NODISCARD bool operator>(_In_z_ const _Elem* const _Left, const basic_string<_Elem, _Traits, _Alloc>& _Right) { +_NODISCARD bool operator>(_In_z_ const _Elem* const _Left, const basic_string<_Elem, _Traits, _Alloc>& _Right) noexcept +/* strengthened */ { return _Right < _Left; } template -_NODISCARD bool operator>(const basic_string<_Elem, _Traits, _Alloc>& _Left, _In_z_ const _Elem* const _Right) { +_NODISCARD bool operator>(const basic_string<_Elem, _Traits, _Alloc>& _Left, _In_z_ const _Elem* const _Right) noexcept +/* strengthened */ { return _Right < _Left; } @@ -5088,12 +5095,14 @@ _NODISCARD bool operator<=( } template -_NODISCARD bool operator<=(_In_z_ const _Elem* const _Left, const basic_string<_Elem, _Traits, _Alloc>& _Right) { +_NODISCARD bool operator<=(_In_z_ const _Elem* const _Left, const basic_string<_Elem, _Traits, _Alloc>& _Right) noexcept +/* strengthened */ { return !(_Right < _Left); } template -_NODISCARD bool operator<=(const basic_string<_Elem, _Traits, _Alloc>& _Left, _In_z_ const _Elem* const _Right) { +_NODISCARD bool operator<=(const basic_string<_Elem, _Traits, _Alloc>& _Left, _In_z_ const _Elem* const _Right) noexcept +/* strengthened */ { return !(_Right < _Left); } @@ -5104,12 +5113,14 @@ _NODISCARD bool operator>=( } template -_NODISCARD bool operator>=(_In_z_ const _Elem* const _Left, const basic_string<_Elem, _Traits, _Alloc>& _Right) { +_NODISCARD bool operator>=(_In_z_ const _Elem* const _Left, const basic_string<_Elem, _Traits, _Alloc>& _Right) noexcept +/* strengthened */ { return !(_Left < _Right); } template -_NODISCARD bool operator>=(const basic_string<_Elem, _Traits, _Alloc>& _Left, _In_z_ const _Elem* const _Right) { +_NODISCARD bool operator>=(const basic_string<_Elem, _Traits, _Alloc>& _Left, _In_z_ const _Elem* const _Right) noexcept +/* strengthened */ { return !(_Left < _Right); } #endif // ^^^ !_HAS_CXX20 ^^^ From a0716eb242d44ae1fc838b683a1353898c702f83 Mon Sep 17 00:00:00 2001 From: achabense <60953653+achabense@users.noreply.github.com> Date: Tue, 22 Aug 2023 21:17:04 +0800 Subject: [PATCH 6/6] nitpick --- stl/inc/xstring | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/stl/inc/xstring b/stl/inc/xstring index ad68e987f5..1136352d72 100644 --- a/stl/inc/xstring +++ b/stl/inc/xstring @@ -4264,9 +4264,6 @@ public: auto& _My_data = _Mypair._Myval2; auto& _Right_data = _Right._Mypair._Myval2; - const bool _My_large = _My_data._Large_mode_engaged(); - const bool _Right_large = _Right_data._Large_mode_engaged(); - #if !defined(_INSERT_STRING_ANNOTATION) if constexpr (_Can_memcpy_val) { #if _HAS_CXX20 @@ -4287,6 +4284,9 @@ public: } #endif // !defined(_INSERT_STRING_ANNOTATION) + const bool _My_large = _My_data._Large_mode_engaged(); + const bool _Right_large = _Right_data._Large_mode_engaged(); + if (_My_large && _Right_large) { // swap buffers, iterators preserved swap(_My_data._Bx._Ptr, _Right_data._Bx._Ptr); // intentional ADL } else if (_My_large) { // swap large with small