diff --git a/stl/inc/deque b/stl/inc/deque index c605cd56de6..b57c45eb523 100644 --- a/stl/inc/deque +++ b/stl/inc/deque @@ -722,43 +722,37 @@ public: _Take_contents(_Right); } -private: - void _Move_assign(deque& _Right, _Equal_allocators) noexcept { - _Tidy(); - _Pocma(_Getal(), _Right._Getal()); - _Take_contents(_Right); - } - - void _Move_assign(deque& _Right, _Propagate_allocators) { - auto& _Al = _Getal(); - auto& _Right_al = _Right._Getal(); - if (_Al == _Right_al) { - _Move_assign(_Right, _Equal_allocators{}); - } else { - _Alproxy_ty _Alproxy(_Al); - _Alproxy_ty _Right_alproxy(_Right_al); - _Container_proxy_ptr12<_Alproxy_ty> _Proxy(_Right_alproxy, _Leave_proxy_unbound{}); - _Tidy(); - _Pocma(_Al, _Right_al); - _Proxy._Bind(_Alproxy, _STD addressof(_Get_data())); - _Take_contents(_Right); +public: + deque& operator=(deque&& _Right) noexcept(_Alty_traits::is_always_equal::value) { + if (this == _STD addressof(_Right)) { + return *this; } - } - void _Move_assign(deque& _Right, _No_propagate_allocators) { - if (_Getal() == _Right._Getal()) { - _Move_assign(_Right, _Equal_allocators{}); - } else { - assign( - _STD make_move_iterator(_Right._Unchecked_begin()), _STD make_move_iterator(_Right._Unchecked_end())); + auto& _Al = _Getal(); + auto& _Right_al = _Right._Getal(); + constexpr auto _Pocma_val = _Choose_pocma_v<_Alty>; + if constexpr (_Pocma_val == _Pocma_values::_Propagate_allocators) { + if (_Al != _Right_al) { + _Alproxy_ty _Alproxy(_Al); + _Alproxy_ty _Right_alproxy(_Right_al); + _Container_proxy_ptr12<_Alproxy_ty> _Proxy(_Right_alproxy, _Leave_proxy_unbound{}); + _Tidy(); + _Pocma(_Al, _Right_al); + _Proxy._Bind(_Alproxy, _STD addressof(_Get_data())); + _Take_contents(_Right); + return *this; + } + } else if constexpr (_Pocma_val == _Pocma_values::_No_propagate_allocators) { + if (_Al != _Right_al) { + assign(_STD make_move_iterator(_Right._Unchecked_begin()), + _STD make_move_iterator(_Right._Unchecked_end())); + return *this; + } } - } -public: - deque& operator=(deque&& _Right) noexcept(_Alty_traits::is_always_equal::value) { - if (this != _STD addressof(_Right)) { - _Move_assign(_Right, _Choose_pocma<_Alty>{}); - } + _Tidy(); + _Pocma(_Al, _Right_al); + _Take_contents(_Right); return *this; } @@ -875,25 +869,23 @@ public: _Delete_plain_internal(_Proxy_allocator, _STD exchange(_Get_data()._Myproxy, nullptr)); } - void _Copy_assign(const deque& _Right, false_type) { - _Pocca(_Getal(), _Right._Getal()); - assign(_Right._Unchecked_begin(), _Right._Unchecked_end()); - } - - void _Copy_assign(const deque& _Right, true_type) { - if (_Getal() != _Right._Getal()) { - _Tidy(); - _Get_data()._Reload_proxy(static_cast<_Alproxy_ty>(_Getal()), static_cast<_Alproxy_ty>(_Right._Getal())); + deque& operator=(const deque& _Right) { + if (this == _STD addressof(_Right)) { + return *this; } - _Copy_assign(_Right, false_type{}); - } - - deque& operator=(const deque& _Right) { - if (this != _STD addressof(_Right)) { - _Copy_assign(_Right, _Choose_pocca<_Alty>{}); + auto& _Al = _Getal(); + auto& _Right_al = _Right._Getal(); + if constexpr (_Choose_pocca_v<_Alty>) { + if (_Al != _Right_al) { + _Tidy(); + _Get_data()._Reload_proxy(static_cast<_Alproxy_ty>(_Al), static_cast<_Alproxy_ty>(_Right_al)); + } } + _Pocca(_Al, _Right_al); + assign(_Right._Unchecked_begin(), _Right._Unchecked_end()); + return *this; } diff --git a/stl/inc/forward_list b/stl/inc/forward_list index a26a34c93b8..b2b0087c35d 100644 --- a/stl/inc/forward_list +++ b/stl/inc/forward_list @@ -630,41 +630,35 @@ public: _Take_head(_Right); } -private: - void _Move_assign(forward_list& _Right, _Equal_allocators) noexcept { - clear(); - _Pocma(_Getal(), _Right._Getal()); - _Take_head(_Right); - } - - void _Move_assign(forward_list& _Right, _Propagate_allocators) noexcept { - if (_Getal() == _Right._Getal()) { - _Move_assign(_Right, _Equal_allocators{}); - } else { - _Mypair._Myval2._Orphan_all(); - clear(); - _Mypair._Myval2._Reload_proxy( - _GET_PROXY_ALLOCATOR(_Alty, _Getal()), _GET_PROXY_ALLOCATOR(_Alty, _Right._Getal())); - _Pocma(_Getal(), _Right._Getal()); - _Take_head(_Right); - } - } - - void _Move_assign(forward_list& _Right, _No_propagate_allocators) { - if (_Getal() == _Right._Getal()) { - _Move_assign(_Right, _Equal_allocators{}); - } else { - _Assign_unchecked(_STD make_move_iterator(_Right._Unchecked_begin()), _Right._Unchecked_end()); - } - } - public: forward_list& operator=(forward_list&& _Right) noexcept( - noexcept(_Move_assign(_Right, _Choose_pocma<_Alnode>{}))) /* strengthened */ { - if (this != _STD addressof(_Right)) { - _Move_assign(_Right, _Choose_pocma<_Alnode>{}); + _Choose_pocma_v<_Alnode> != _Pocma_values::_No_propagate_allocators) /* strengthened */ { + if (this == _STD addressof(_Right)) { + return *this; + } + + auto& _Al = _Getal(); + auto& _Right_al = _Right._Getal(); + constexpr auto _Pocma_val = _Choose_pocma_v<_Alnode>; + if constexpr (_Pocma_val == _Pocma_values::_Propagate_allocators) { + if (_Al != _Right_al) { + _Mypair._Myval2._Orphan_all(); + clear(); + _Mypair._Myval2._Reload_proxy(_GET_PROXY_ALLOCATOR(_Alty, _Al), _GET_PROXY_ALLOCATOR(_Alty, _Right_al)); + _Pocma(_Al, _Right_al); + _Take_head(_Right); + return *this; + } + } else if constexpr (_Pocma_val == _Pocma_values::_No_propagate_allocators) { + if (_Al != _Right_al) { + _Assign_unchecked(_STD make_move_iterator(_Right._Unchecked_begin()), _Right._Unchecked_end()); + return *this; + } } + clear(); + _Pocma(_Al, _Right_al); + _Take_head(_Right); return *this; } @@ -744,29 +738,26 @@ public: #endif // _ITERATOR_DEBUG_LEVEL != 0 } -private: - void _Copy_assign(const forward_list& _Right, false_type) { - _Pocca(_Getal(), _Right._Getal()); - _Assign_unchecked(_Right._Unchecked_begin(), _Right._Unchecked_end()); - } - - void _Copy_assign(const forward_list& _Right, true_type) { - if (_Getal() != _Right._Getal()) { - _Mypair._Myval2._Orphan_all(); - clear(); - _Mypair._Myval2._Reload_proxy( - _GET_PROXY_ALLOCATOR(_Alnode, _Getal()), _GET_PROXY_ALLOCATOR(_Alnode, _Right._Getal())); - } - - _Copy_assign(_Right, _No_propagate_allocators{}); - } - public: forward_list& operator=(const forward_list& _Right) { - if (this != _STD addressof(_Right)) { - _Copy_assign(_Right, _Choose_pocca<_Alnode>{}); + if (this == _STD addressof(_Right)) { + return *this; + } + + auto& _Al = _Getal(); + auto& _Right_al = _Right._Getal(); + if constexpr (_Choose_pocca_v<_Alnode>) { + if (_Al != _Right_al) { + _Mypair._Myval2._Orphan_all(); + clear(); + _Mypair._Myval2._Reload_proxy( + _GET_PROXY_ALLOCATOR(_Alnode, _Al), _GET_PROXY_ALLOCATOR(_Alnode, _Right_al)); + } } + _Pocca(_Al, _Right_al); + _Assign_unchecked(_Right._Unchecked_begin(), _Right._Unchecked_end()); + return *this; } diff --git a/stl/inc/list b/stl/inc/list index f4548c4340d..607f9c41e7a 100644 --- a/stl/inc/list +++ b/stl/inc/list @@ -898,50 +898,44 @@ public: _Swap_val(_Right); } -private: - void _Move_assign(list& _Right, _Equal_allocators) noexcept { - clear(); - _Pocma(_Getal(), _Right._Getal()); - _Swap_val(_Right); - } - - void _Move_assign(list& _Right, _Propagate_allocators) { - auto& _Al = _Getal(); - auto& _Right_al = _Right._Getal(); - if (_Al == _Right_al) { - _Move_assign(_Right, _Equal_allocators{}); - } else { - auto&& _Alproxy = _GET_PROXY_ALLOCATOR(_Alnode, _Al); - auto&& _Right_alproxy = _GET_PROXY_ALLOCATOR(_Alnode, _Right_al); - _Container_proxy_ptr<_Alty> _Proxy(_Right_alproxy, _Leave_proxy_unbound{}); - auto& _My_data = _Mypair._Myval2; - auto& _Right_data = _Right._Mypair._Myval2; - const auto _Newhead = _STD exchange(_Right_data._Myhead, _Node::_Buyheadnode(_Right_al)); - const auto _Newsize = _STD exchange(_Right_data._Mysize, size_type{0}); - _Tidy(); - _Pocma(_Al, _Right_al); - _My_data._Myhead = _Newhead; - _My_data._Mysize = _Newsize; - _Proxy._Bind(_Alproxy, _STD addressof(_My_data)); - _My_data._Swap_proxy_and_iterators(_Right_data); +public: + list& operator=(list&& _Right) noexcept( + _Choose_pocma_v<_Alnode> == _Pocma_values::_Equal_allocators) /* strengthened */ { + if (this == _STD addressof(_Right)) { + return *this; } - } - void _Move_assign(list& _Right, _No_propagate_allocators) { - if (_Getal() == _Right._Getal()) { - _Move_assign(_Right, _Equal_allocators{}); - } else { - assign( - _STD make_move_iterator(_Right._Unchecked_begin()), _STD make_move_iterator(_Right._Unchecked_end())); + auto& _Al = _Getal(); + auto& _Right_al = _Right._Getal(); + constexpr auto _Pocma_val = _Choose_pocma_v<_Alnode>; + if constexpr (_Pocma_val == _Pocma_values::_Propagate_allocators) { + if (_Al != _Right_al) { + auto&& _Alproxy = _GET_PROXY_ALLOCATOR(_Alnode, _Al); + auto&& _Right_alproxy = _GET_PROXY_ALLOCATOR(_Alnode, _Right_al); + _Container_proxy_ptr<_Alty> _Proxy(_Right_alproxy, _Leave_proxy_unbound{}); + auto& _My_data = _Mypair._Myval2; + auto& _Right_data = _Right._Mypair._Myval2; + const auto _Newhead = _STD exchange(_Right_data._Myhead, _Node::_Buyheadnode(_Right_al)); + const auto _Newsize = _STD exchange(_Right_data._Mysize, size_type{0}); + _Tidy(); + _Pocma(_Al, _Right_al); + _My_data._Myhead = _Newhead; + _My_data._Mysize = _Newsize; + _Proxy._Bind(_Alproxy, _STD addressof(_My_data)); + _My_data._Swap_proxy_and_iterators(_Right_data); + return *this; + } + } else if constexpr (_Pocma_val == _Pocma_values::_No_propagate_allocators) { + if (_Al != _Right_al) { + assign(_STD make_move_iterator(_Right._Unchecked_begin()), + _STD make_move_iterator(_Right._Unchecked_end())); + return *this; + } } - } -public: - list& operator=(list&& _Right) noexcept( - noexcept(_Move_assign(_Right, _Choose_pocma<_Alnode>{}))) /* strengthened */ { - if (this != _STD addressof(_Right)) { - _Move_assign(_Right, _Choose_pocma<_Alnode>{}); - } + clear(); + _Pocma(_Al, _Right_al); + _Swap_val(_Right); return *this; } @@ -1057,25 +1051,23 @@ private: _Proxy._Bind(_Alproxy, _STD addressof(_Mypair._Myval2)); } - void _Copy_assign(const list& _Right, false_type) { - _Pocca(_Getal(), _Right._Getal()); - assign(_Right._Unchecked_begin(), _Right._Unchecked_end()); - } - - void _Copy_assign(const list& _Right, true_type) { - if (_Getal() != _Right._Getal()) { - _Reload_sentinel_and_proxy(_Right); - } - - assign(_Right._Unchecked_begin(), _Right._Unchecked_end()); - } - public: list& operator=(const list& _Right) { - if (this != _STD addressof(_Right)) { - _Copy_assign(_Right, _Choose_pocca<_Alnode>{}); + if (this == _STD addressof(_Right)) { + return *this; + } + + auto& _Al = _Getal(); + auto& _Right_al = _Right._Getal(); + if constexpr (_Choose_pocca_v<_Alnode>) { + if (_Al != _Right_al) { + _Reload_sentinel_and_proxy(_Right); + } + } else { + _Pocca(_Al, _Right_al); } + assign(_Right._Unchecked_begin(), _Right._Unchecked_end()); return *this; } diff --git a/stl/inc/sstream b/stl/inc/sstream index b99d6d094f2..a312671ebfe 100644 --- a/stl/inc/sstream +++ b/stl/inc/sstream @@ -204,27 +204,20 @@ public: _Init(_Newstr.c_str(), _Newstr.size(), _Mystate); } - void _Str(_Mystr&& _Newstr, _Equal_allocators) { - _Tidy(); - _Pocma(_Al, _Newstr._Getal()); - _Init_string_inplace(_STD move(_Newstr), _Mystate); - } - - void _Str(_Mystr&& _Newstr, _Propagate_allocators) { - _Str(_STD move(_Newstr), _Equal_allocators{}); - } - - void _Str(_Mystr&& _Newstr, _No_propagate_allocators) { - if (_Al == _Newstr._Getal()) { - _Str(_STD move(_Newstr), _Equal_allocators{}); - } else { - _Tidy(); - _Init(_Newstr.c_str(), _Newstr.size(), _Mystate); + void str(_Mystr&& _Newstr) { + auto& _Newstr_al = _Newstr._Getal(); + constexpr auto _Pocma_val = _Choose_pocma_v<_Alloc>; + if constexpr (_Pocma_val == _Pocma_values::_No_propagate_allocators) { + if (_Al != _Newstr_al) { + _Tidy(); + _Init(_Newstr.c_str(), _Newstr.size(), _Mystate); + return; + } } - } - void str(_Mystr&& _Newstr) { - _Str(_STD move(_Newstr), _Choose_pocma<_Alloc>{}); + _Tidy(); + _Pocma(_Al, _Newstr_al); + _Init_string_inplace(_STD move(_Newstr), _Mystate); } _NODISCARD allocator_type get_allocator() const noexcept { diff --git a/stl/inc/syncstream b/stl/inc/syncstream index 106382f95bf..a7a92ead700 100644 --- a/stl/inc/syncstream +++ b/stl/inc/syncstream @@ -108,9 +108,40 @@ public: basic_syncbuf& operator=(basic_syncbuf&& _Right) { // see LWG-3498 regarding noexcept emit(); - if (this != _STD addressof(_Right)) { - _Move_assign(_STD move(_Right), _Choose_pocma<_Alloc>{}); + + if (this == _STD addressof(_Right)) { + return *this; } + + auto& _Al = _Getal(); + auto& _Right_al = _Right._Getal(); + constexpr auto _Pocma_val = _Choose_pocma_v<_Alloc>; + if constexpr (_Pocma_val == _Pocma_values::_No_propagate_allocators) { + if (_Al != _Right_al) { + _Tidy(); + + const _Size_type _Right_buf_size = _Right._Get_buffer_size(); + const _Size_type _Right_data_size = _Right._Get_data_size(); + + _Elem* const _New_ptr = _Unfancy(_Al.allocate(_Right_buf_size)); + _Traits::copy(_New_ptr, _Right.pbase(), _Right_data_size); + + streambuf_type::setp(_New_ptr, _New_ptr + _Right_data_size, _New_ptr + _Right_buf_size); + _STD swap(streambuf_type::_Plocale, _Right._Plocale); + + _STD swap(_Mybase::_Emit_on_sync, _Right._Emit_on_sync); + _STD swap(_Mybase::_Sync_recorded, _Right._Sync_recorded); + _STD swap(_Wrapped, _Right._Wrapped); + _STD swap(_Get_mutex(), _Right._Get_mutex()); + + _Right._Tidy(); + return *this; + } + } + + _Tidy(); + _Pocma(_Al, _Right_al); + _Swap_except_al(_Right); return *this; } @@ -221,43 +252,6 @@ private: } } - void _Move_assign(basic_syncbuf&& _Right, _Equal_allocators) { // see LWG-3498 regarding noexcept - _Tidy(); - _Pocma(_Getal(), _Right._Getal()); - _Swap_except_al(_Right); - } - - void _Move_assign(basic_syncbuf&& _Right, _Propagate_allocators) { // see LWG-3498 regarding noexcept - _Tidy(); - _Pocma(_Getal(), _Right._Getal()); - _Swap_except_al(_Right); - } - - void _Move_assign(basic_syncbuf&& _Right, _No_propagate_allocators) { // see LWG-3498 regarding noexcept - auto& _Al = _Getal(); - if (_Al == _Right._Getal()) { - _Move_assign(_STD move(_Right), _Equal_allocators{}); - } else { - _Tidy(); - - const _Size_type _Right_buf_size = _Right._Get_buffer_size(); - const _Size_type _Right_data_size = _Right._Get_data_size(); - - _Elem* const _New_ptr = _Unfancy(_Al.allocate(_Right_buf_size)); - _Traits::copy(_New_ptr, _Right.pbase(), _Right_data_size); - - streambuf_type::setp(_New_ptr, _New_ptr + _Right_data_size, _New_ptr + _Right_buf_size); - _STD swap(streambuf_type::_Plocale, _Right._Plocale); - - _STD swap(_Mybase::_Emit_on_sync, _Right._Emit_on_sync); - _STD swap(_Mybase::_Sync_recorded, _Right._Sync_recorded); - _STD swap(_Wrapped, _Right._Wrapped); - _STD swap(_Get_mutex(), _Right._Get_mutex()); - - _Right._Tidy(); - } - } - void _Swap_except_al(basic_syncbuf& _Right) { // see LWG-3498 regarding noexcept _Mybase::_Swap(_Right); _STD swap(_Wrapped, _Right._Wrapped); diff --git a/stl/inc/vector b/stl/inc/vector index d300d12e32f..f880602918f 100644 --- a/stl/inc/vector +++ b/stl/inc/vector @@ -565,14 +565,15 @@ public: } _CONSTEXPR20 vector& operator=(vector&& _Right) noexcept( - !is_same_v<_Choose_pocma<_Alty>, _No_propagate_allocators>) { + _Choose_pocma_v<_Alty> != _Pocma_values::_No_propagate_allocators) { if (this == _STD addressof(_Right)) { return *this; } - _Alty& _Al = _Getal(); - _Alty& _Right_al = _Right._Getal(); - if constexpr (is_same_v<_Choose_pocma<_Alty>, _No_propagate_allocators>) { + _Alty& _Al = _Getal(); + _Alty& _Right_al = _Right._Getal(); + constexpr auto _Pocma_val = _Choose_pocma_v<_Alty>; + if constexpr (_Pocma_val == _Pocma_values::_No_propagate_allocators) { if (_Al != _Right_al) { _Move_assign_unequal_alloc(_Right); return *this; @@ -581,7 +582,7 @@ public: _Tidy(); #if _ITERATOR_DEBUG_LEVEL != 0 - if constexpr (is_same_v<_Choose_pocma<_Alty>, _Propagate_allocators>) { + if constexpr (_Pocma_val == _Pocma_values::_Propagate_allocators) { if (_Al != _Right_al) { // intentionally slams into noexcept on OOM, TRANSITION, VSO-466800 _Mypair._Myval2._Reload_proxy(_GET_PROXY_ALLOCATOR(_Alty, _Al), _GET_PROXY_ALLOCATOR(_Alty, _Right_al)); @@ -1076,29 +1077,25 @@ public: _Assign_range(_Ilist.begin(), _Ilist.end(), random_access_iterator_tag{}); } -private: - _CONSTEXPR20 void _Copy_assign(const vector& _Right, false_type) { - _Pocca(_Getal(), _Right._Getal()); - auto& _Right_data = _Right._Mypair._Myval2; - assign(_Right_data._Myfirst, _Right_data._Mylast); - } - - _CONSTEXPR20 void _Copy_assign(const vector& _Right, true_type) { - if (_Getal() != _Right._Getal()) { - _Tidy(); - _Mypair._Myval2._Reload_proxy( - _GET_PROXY_ALLOCATOR(_Alty, _Getal()), _GET_PROXY_ALLOCATOR(_Alty, _Right._Getal())); - } - - _Copy_assign(_Right, false_type{}); - } - public: _CONSTEXPR20 vector& operator=(const vector& _Right) { - if (this != _STD addressof(_Right)) { - _Copy_assign(_Right, _Choose_pocca<_Alty>{}); + if (this == _STD addressof(_Right)) { + return *this; } + auto& _Al = _Getal(); + auto& _Right_al = _Right._Getal(); + if constexpr (_Choose_pocca_v<_Alty>) { + if (_Al != _Right_al) { + _Tidy(); + _Mypair._Myval2._Reload_proxy(_GET_PROXY_ALLOCATOR(_Alty, _Al), _GET_PROXY_ALLOCATOR(_Alty, _Right_al)); + } + } + + _Pocca(_Al, _Right_al); + auto& _Right_data = _Right._Mypair._Myval2; + assign(_Right_data._Myfirst, _Right_data._Mylast); + return *this; } @@ -2478,58 +2475,52 @@ public: this->_Swap_proxy_and_iterators(_Right); } -private: -#if _ITERATOR_DEBUG_LEVEL != 0 - _CONSTEXPR20 void _Move_assign(vector& _Right, _Equal_allocators) noexcept { - this->_Myvec = _STD move(_Right._Myvec); - this->_Mysize = _STD exchange(_Right._Mysize, size_type{0}); - this->_Swap_proxy_and_iterators(_Right); - } - - _CONSTEXPR20 void _Move_assign(vector& _Right, _Propagate_allocators) noexcept { - using _Alproxy_type = _Rebind_alloc_t<_Alvbase, _Container_proxy>; - if (this->_Getal() != _Right._Getal()) { // reload proxy - // intentionally slams into noexcept on OOM, TRANSITION, VSO-466800 - _Alproxy_type _Oldal(this->_Getal()); - _Alproxy_type _Right_proxy_al(_Right._Getal()); - _Container_proxy_ptr<_Alvbase> _Proxy(_Right_proxy_al, _Leave_proxy_unbound{}); - this->_Myvec = _STD move(_Right._Myvec); - this->_Mysize = _STD exchange(_Right._Mysize, size_type{0}); - _Proxy._Bind(_Oldal, this); - this->_Swap_proxy_and_iterators(_Right); - return; +public: + _CONSTEXPR20 vector& operator=(vector&& _Right) noexcept(is_nothrow_move_assignable_v<_Mybase>) { + if (this == _STD addressof(_Right)) { + return *this; } +#if _ITERATOR_DEBUG_LEVEL == 0 this->_Myvec = _STD move(_Right._Myvec); this->_Mysize = _STD exchange(_Right._Mysize, size_type{0}); - this->_Swap_proxy_and_iterators(_Right); - } +#else // ^^^ _ITERATOR_DEBUG_LEVEL == 0 ^^^ // vvv _ITERATOR_DEBUG_LEVEL != 0 vvv + this->_Orphan_all(); + auto& _Al = this->_Getal(); + auto& _Right_al = _Right._Getal(); + constexpr auto _Pocma_val = _Choose_pocma_v<_Alvbase>; + if constexpr (_Pocma_val == _Pocma_values::_Propagate_allocators) { + using _Alproxy_type = _Rebind_alloc_t<_Alvbase, _Container_proxy>; + if (_Al != _Right_al) { // reload proxy + // intentionally slams into noexcept on OOM, TRANSITION, VSO-466800 + _Alproxy_type _Oldal(_Al); + _Alproxy_type _Right_proxy_al(_Right_al); + _Container_proxy_ptr<_Alvbase> _Proxy(_Right_proxy_al, _Leave_proxy_unbound{}); + this->_Myvec = _STD move(_Right._Myvec); + this->_Mysize = _STD exchange(_Right._Mysize, size_type{0}); + _Proxy._Bind(_Oldal, this); + this->_Swap_proxy_and_iterators(_Right); + return *this; + } + } else if constexpr (_Pocma_val == _Pocma_values::_No_propagate_allocators) { + this->_Myvec = _STD move(_Right._Myvec); + this->_Mysize = _Right._Mysize; + if (_Right._Myvec.empty()) { + // we took _Right's buffer, so zero out size + _Right._Mysize = 0; + } - _CONSTEXPR20 void _Move_assign(vector& _Right, _No_propagate_allocators) { - this->_Myvec = _STD move(_Right._Myvec); - this->_Mysize = _Right._Mysize; - if (_Right._Myvec.empty()) { - // we took _Right's buffer, so zero out size - _Right._Mysize = 0; + if (_Al == _Right_al) { + this->_Swap_proxy_and_iterators(_Right); + } + return *this; } - if (this->_Getal() == _Right._Getal()) { - this->_Swap_proxy_and_iterators(_Right); - } - } -#endif // _ITERATOR_DEBUG_LEVEL != 0 + this->_Myvec = _STD move(_Right._Myvec); + this->_Mysize = _STD exchange(_Right._Mysize, size_type{0}); + this->_Swap_proxy_and_iterators(_Right); -public: - _CONSTEXPR20 vector& operator=(vector&& _Right) noexcept(is_nothrow_move_assignable_v<_Mybase>) { - if (this != _STD addressof(_Right)) { -#if _ITERATOR_DEBUG_LEVEL == 0 - this->_Myvec = _STD move(_Right._Myvec); - this->_Mysize = _STD exchange(_Right._Mysize, size_type{0}); -#else // ^^^ _ITERATOR_DEBUG_LEVEL == 0 ^^^ // vvv _ITERATOR_DEBUG_LEVEL != 0 vvv - this->_Orphan_all(); - _Move_assign(_Right, _Choose_pocma<_Alvbase>{}); #endif // _ITERATOR_DEBUG_LEVEL == 0 - } return *this; } @@ -2568,41 +2559,37 @@ public: _CONSTEXPR20 ~vector() noexcept {} -private: -#if _ITERATOR_DEBUG_LEVEL != 0 - _CONSTEXPR20 void _Copy_assign(const vector& _Right, false_type) { - this->_Myvec = _Right._Myvec; - this->_Mysize = _Right._Mysize; - } - - _CONSTEXPR20 void _Copy_assign(const vector& _Right, true_type) { - if (this->_Getal() == _Right._Getal()) { - _Copy_assign(_Right, false_type{}); - } else { - // reload proxy - using _Alproxy_type = _Rebind_alloc_t<_Alvbase, _Container_proxy>; - _Alproxy_type _Oldal(this->_Getal()); - _Alproxy_type _Right_proxy_al(_Right._Getal()); - _Container_proxy_ptr<_Alvbase> _Proxy(_Right_proxy_al, _Leave_proxy_unbound{}); - this->_Myvec = _Right._Myvec; - this->_Mysize = _Right._Mysize; - _Proxy._Bind(_Oldal, this); - } - } -#endif // _ITERATOR_DEBUG_LEVEL != 0 - public: _CONSTEXPR20 vector& operator=(const vector& _Right) { - if (this != _STD addressof(_Right)) { + if (this == _STD addressof(_Right)) { + return *this; + } + #if _ITERATOR_DEBUG_LEVEL == 0 - this->_Myvec = _Right._Myvec; - this->_Mysize = _Right._Mysize; + this->_Myvec = _Right._Myvec; + this->_Mysize = _Right._Mysize; #else // ^^^ _ITERATOR_DEBUG_LEVEL == 0 ^^^ // vvv _ITERATOR_DEBUG_LEVEL != 0 vvv - this->_Orphan_all(); - _Copy_assign(_Right, _Choose_pocca<_Alvbase>{}); -#endif // _ITERATOR_DEBUG_LEVEL == 0 + this->_Orphan_all(); + auto& _Al = this->_Getal(); + auto& _Right_al = _Right._Getal(); + if constexpr (_Choose_pocca_v<_Alvbase>) { + if (_Al != _Right_al) { + // reload proxy + using _Alproxy_type = _Rebind_alloc_t<_Alvbase, _Container_proxy>; + _Alproxy_type _Oldal(_Al); + _Alproxy_type _Right_proxy_al(_Right_al); + _Container_proxy_ptr<_Alvbase> _Proxy(_Right_proxy_al, _Leave_proxy_unbound{}); + this->_Myvec = _Right._Myvec; + this->_Mysize = _Right._Mysize; + _Proxy._Bind(_Oldal, this); + return *this; + } } + this->_Myvec = _Right._Myvec; + this->_Mysize = _Right._Mysize; +#endif // _ITERATOR_DEBUG_LEVEL == 0 + return *this; } diff --git a/stl/inc/xhash b/stl/inc/xhash index 33df721894c..0298227a63c 100644 --- a/stl/inc/xhash +++ b/stl/inc/xhash @@ -472,89 +472,102 @@ private: } }; - void _Move_assign(_Hash& _Right, _Equal_allocators) { - clear(); - _Traitsobj = _Right._Traitsobj; - _Pocma_both(_Right); - _Swap_val(_Right); - } - - void _Move_assign(_Hash& _Right, _Propagate_allocators) { - if (_Getal() == _Right._Getal()) { - _Move_assign(_Right, _Equal_allocators{}); - } else { - // allocate all the parts necessary to maintain _Hash invariants using _Right's allocator - auto&& _Alproxy = _GET_PROXY_ALLOCATOR(_Alnode, _Getal()); - auto&& _Right_alproxy = _GET_PROXY_ALLOCATOR(_Alnode, _Right._Getal()); - _Container_proxy_ptr<_Alnode> _List_proxy(_Right_alproxy, _Leave_proxy_unbound{}); - _Container_proxy_ptr<_Alnode> _Vec_proxy(_Right_alproxy, _Leave_proxy_unbound{}); - _List_head_construct_ptr<_Alnode> _Newhead(_Right._Getal()); - _Min_buckets_construct_ptr _Buckets(_Right._Vec._Mypair._Get_first()); - - // assign the hash/compare ops; we have no control over whether this throws, and if it does we want to do - // nothing - _Traitsobj = _Right._Traitsobj; - - // nothrow hereafter - - // release any state we are currently owning, and propagate the allocators - _List._Tidy(); - _Vec._Tidy(); - _Pocma_both(_Right); - - // assign the empty list to _Right._List (except the allocators), and take _Right's _List data - auto& _List_data = _List._Mypair._Myval2; - auto& _Right_list_data = _Right._List._Mypair._Myval2; - _List_data._Myhead = _STD exchange(_Right_list_data._Myhead, _Newhead._Release()); - _List_data._Mysize = _STD exchange(_Right_list_data._Mysize, size_type{0}); - _List_proxy._Bind(_Alproxy, _STD addressof(_List_data)); - _List_data._Swap_proxy_and_iterators(_Right_list_data); - - // assign the _Min_buckets into _Right's _Vec data and take _Right's _Vec data - auto& _Vec_data = _Vec._Mypair._Myval2; - auto& _Right_vec_data = _Right._Vec._Mypair._Myval2; +#ifdef _ENABLE_STL_INTERNAL_CHECK + struct _NODISCARD _Check_container_invariants_guard { + const _Hash& _Target; - const auto _Newfirst = _Buckets._Release(_Right._Unchecked_end()); - const auto _Newlast = _Newfirst + _Min_buckets * 2; + explicit _Check_container_invariants_guard(const _Hash& _Target_) : _Target(_Target_) {} - _Vec_data._Myfirst = _STD exchange(_Right_vec_data._Myfirst, _Newfirst); - _Vec_data._Mylast = _STD exchange(_Right_vec_data._Mylast, _Newlast); - _Vec_data._Myend = _STD exchange(_Right_vec_data._Myend, _Newlast); - _Vec_proxy._Bind(_Alproxy, _STD addressof(_Vec_data)); - _Vec_data._Swap_proxy_and_iterators(_Right_vec_data); + _Check_container_invariants_guard(const _Check_container_invariants_guard&) = delete; + _Check_container_invariants_guard& operator=(const _Check_container_invariants_guard&) = delete; - // give _Right the default _Mask and _Maxidx values and take its former values - _Mask = _STD exchange(_Right._Mask, _Min_buckets - 1); - _Maxidx = _STD exchange(_Right._Maxidx, _Min_buckets); + ~_Check_container_invariants_guard() { + _Target._Stl_internal_check_container_invariants(); } - } - - void _Move_assign(_Hash& _Right, _No_propagate_allocators) { - if (_Getal() == _Right._Getal()) { - _Move_assign(_Right, _Equal_allocators{}); - return; - } - - _Clear_guard _Guard{this}; - _Traitsobj = _Right._Traitsobj; - using _Adapter = _Reinterpret_move_iter; - _List.template _Assign_cast<_Mutable_value_type&>( - _Adapter{_Right._List._Unchecked_begin()}, _Adapter{_Right._List._Unchecked_end()}); - _Reinsert_with_invalid_vec(); - _Guard._Target = nullptr; - } + }; +#endif // _ENABLE_STL_INTERNAL_CHECK public: _Hash& operator=(_Hash&& _Right) { // assign by moving _Right - if (this != _STD addressof(_Right)) { - _Move_assign(_Right, _Choose_pocma<_Alnode>{}); + if (this == _STD addressof(_Right)) { + return *this; + } #ifdef _ENABLE_STL_INTERNAL_CHECK - _Stl_internal_check_container_invariants(); - _Right._Stl_internal_check_container_invariants(); + _Check_container_invariants_guard _Check_self{*this}; + _Check_container_invariants_guard _Check_right{_Right}; #endif // _ENABLE_STL_INTERNAL_CHECK + + auto& _Al = _Getal(); + auto& _Right_al = _Right._Getal(); + constexpr auto _Pocma_val = _Choose_pocma_v<_Alnode>; + if constexpr (_Pocma_val == _Pocma_values::_Propagate_allocators) { + if (_Al != _Right_al) { + // allocate all the parts necessary to maintain _Hash invariants using _Right's allocator + auto&& _Alproxy = _GET_PROXY_ALLOCATOR(_Alnode, _Al); + auto&& _Right_alproxy = _GET_PROXY_ALLOCATOR(_Alnode, _Right_al); + _Container_proxy_ptr<_Alnode> _List_proxy(_Right_alproxy, _Leave_proxy_unbound{}); + _Container_proxy_ptr<_Alnode> _Vec_proxy(_Right_alproxy, _Leave_proxy_unbound{}); + _List_head_construct_ptr<_Alnode> _Newhead(_Right_al); + _Min_buckets_construct_ptr _Buckets(_Right._Vec._Mypair._Get_first()); + + // assign the hash/compare ops; we have no control over whether this throws, and if it does we want + // to do nothing + _Traitsobj = _Right._Traitsobj; + + // nothrow hereafter + + // release any state we are currently owning, and propagate the allocators + _List._Tidy(); + _Vec._Tidy(); + _Pocma_both(_Right); + + // assign the empty list to _Right._List (except the allocators), and take _Right's _List data + auto& _List_data = _List._Mypair._Myval2; + auto& _Right_list_data = _Right._List._Mypair._Myval2; + _List_data._Myhead = _STD exchange(_Right_list_data._Myhead, _Newhead._Release()); + _List_data._Mysize = _STD exchange(_Right_list_data._Mysize, size_type{0}); + _List_proxy._Bind(_Alproxy, _STD addressof(_List_data)); + _List_data._Swap_proxy_and_iterators(_Right_list_data); + + // assign the _Min_buckets into _Right's _Vec data and take _Right's _Vec data + auto& _Vec_data = _Vec._Mypair._Myval2; + auto& _Right_vec_data = _Right._Vec._Mypair._Myval2; + + const auto _Newfirst = _Buckets._Release(_Right._Unchecked_end()); + const auto _Newlast = _Newfirst + _Min_buckets * 2; + + _Vec_data._Myfirst = _STD exchange(_Right_vec_data._Myfirst, _Newfirst); + _Vec_data._Mylast = _STD exchange(_Right_vec_data._Mylast, _Newlast); + _Vec_data._Myend = _STD exchange(_Right_vec_data._Myend, _Newlast); + _Vec_proxy._Bind(_Alproxy, _STD addressof(_Vec_data)); + _Vec_data._Swap_proxy_and_iterators(_Right_vec_data); + + // give _Right the default _Mask and _Maxidx values and take its former values + _Mask = _STD exchange(_Right._Mask, _Min_buckets - 1); + _Maxidx = _STD exchange(_Right._Maxidx, _Min_buckets); + + return *this; + } + } else if constexpr (_Pocma_val == _Pocma_values::_No_propagate_allocators) { + if (_Al != _Right_al) { + _Clear_guard _Guard{this}; + _Traitsobj = _Right._Traitsobj; + using _Adapter = _Reinterpret_move_iter; + _List.template _Assign_cast<_Mutable_value_type&>( + _Adapter{_Right._List._Unchecked_begin()}, _Adapter{_Right._List._Unchecked_end()}); + _Reinsert_with_invalid_vec(); + _Guard._Target = nullptr; + + return *this; + } } + clear(); + _Traitsobj = _Right._Traitsobj; + _Pocma_both(_Right); + _Swap_val(_Right); + return *this; } @@ -711,49 +724,47 @@ private: _Pocca(_Vec._Mypair._Get_first(), _Right._Vec._Mypair._Get_first()); } - void _Copy_assign(const _Hash& _Right, false_type) { - _Clear_guard _Guard{this}; - _Traitsobj = _Right._Traitsobj; - _Pocca_both(_Right); - _List.template _Assign_cast<_Mutable_value_type&>( - _Right._List._Unchecked_begin(), _Right._List._Unchecked_end()); - _Reinsert_with_invalid_vec(); - _Guard._Target = nullptr; - } - - void _Copy_assign(const _Hash& _Right, true_type) { - auto& _Al = _Getal(); - const auto& _Right_al = _Right._Getal(); - if (_Al == _Right_al) { - _Copy_assign(_Right, false_type{}); - return; +public: + _Hash& operator=(const _Hash& _Right) { + if (this == _STD addressof(_Right)) { + return *this; } - auto&& _Alproxy = _GET_PROXY_ALLOCATOR(_Alnode, _Al); - auto&& _Right_alproxy = _GET_PROXY_ALLOCATOR(_Alnode, _Right_al); - _Container_proxy_ptr<_Alnode> _Vec_proxy(_Right_alproxy, _Leave_proxy_unbound{}); - _List._Reload_sentinel_and_proxy(_Right._List); - _Vec._Tidy(); - _Pocca_both(_Right); - _Vec_proxy._Bind(_Alproxy, _STD addressof(_Vec._Mypair._Myval2)); +#ifdef _ENABLE_STL_INTERNAL_CHECK + _Check_container_invariants_guard _Check_self{*this}; + _Check_container_invariants_guard _Check_right{_Right}; +#endif // _ENABLE_STL_INTERNAL_CHECK + + if constexpr (_Choose_pocca_v<_Alnode>) { + auto& _Al = _Getal(); + const auto& _Right_al = _Right._Getal(); + if (_Al != _Right_al) { + auto&& _Alproxy = _GET_PROXY_ALLOCATOR(_Alnode, _Al); + auto&& _Right_alproxy = _GET_PROXY_ALLOCATOR(_Alnode, _Right_al); + _Container_proxy_ptr<_Alnode> _Vec_proxy(_Right_alproxy, _Leave_proxy_unbound{}); + _List._Reload_sentinel_and_proxy(_Right._List); + _Vec._Tidy(); + _Pocca_both(_Right); + _Vec_proxy._Bind(_Alproxy, _STD addressof(_Vec._Mypair._Myval2)); + + _Clear_guard _Guard{this}; + _Traitsobj = _Right._Traitsobj; + _List.template _Assign_cast<_Mutable_value_type&>( + _Right._List._Unchecked_begin(), _Right._List._Unchecked_end()); + _Reinsert_with_invalid_vec(); + _Guard._Target = nullptr; + + return *this; + } + } _Clear_guard _Guard{this}; _Traitsobj = _Right._Traitsobj; + _Pocca_both(_Right); _List.template _Assign_cast<_Mutable_value_type&>( _Right._List._Unchecked_begin(), _Right._List._Unchecked_end()); _Reinsert_with_invalid_vec(); _Guard._Target = nullptr; - } - -public: - _Hash& operator=(const _Hash& _Right) { - if (this != _STD addressof(_Right)) { - _Copy_assign(_Right, _Choose_pocca<_Alnode>{}); -#ifdef _ENABLE_STL_INTERNAL_CHECK - _Stl_internal_check_container_invariants(); - _Right._Stl_internal_check_container_invariants(); -#endif // _ENABLE_STL_INTERNAL_CHECK - } return *this; } diff --git a/stl/inc/xmemory b/stl/inc/xmemory index 78c8a963f6c..46665303fd0 100644 --- a/stl/inc/xmemory +++ b/stl/inc/xmemory @@ -704,19 +704,25 @@ template struct allocator_traits : conditional_t<_Is_default_allocator<_Alloc>::value, _Default_allocator_traits<_Alloc>, _Normal_allocator_traits<_Alloc>> {}; -// _Choose_pocca returns whether an attempt to propagate allocators is necessary in copy assignment operations. +// _Choose_pocca_v returns whether an attempt to propagate allocators is necessary in copy assignment operations. // Note that even when false_type, callers should call _Pocca as we want to assign allocators even when equal. template -using _Choose_pocca = bool_constant::propagate_on_container_copy_assignment::value - && !allocator_traits<_Alloc>::is_always_equal::value>; +_INLINE_VAR constexpr bool _Choose_pocca_v = allocator_traits<_Alloc>::propagate_on_container_copy_assignment::value + && !allocator_traits<_Alloc>::is_always_equal::value; -struct _Equal_allocators {}; // usually allows contents to be stolen (e.g. with swap) -using _Propagate_allocators = true_type; // usually allows the allocator to be propagated, and then contents stolen -using _No_propagate_allocators = false_type; // usually turns moves into copies +enum class _Pocma_values { + _Equal_allocators, // usually allows contents to be stolen (e.g. with swap) + _Propagate_allocators, // usually allows the allocator to be propagated, and then contents stolen + _No_propagate_allocators, // usually turns moves into copies +}; template -using _Choose_pocma = conditional_t::is_always_equal::value, _Equal_allocators, - typename allocator_traits<_Alloc>::propagate_on_container_move_assignment::type>; +_INLINE_VAR constexpr _Pocma_values + _Choose_pocma_v = allocator_traits<_Alloc>::is_always_equal::value + ? _Pocma_values::_Equal_allocators + : (allocator_traits<_Alloc>::propagate_on_container_move_assignment::value + ? _Pocma_values::_Propagate_allocators + : _Pocma_values::_No_propagate_allocators); template using _Rebind_alloc_t = typename allocator_traits<_Alloc>::template rebind_alloc<_Value_type>; diff --git a/stl/inc/xstring b/stl/inc/xstring index 1f1c7a16702..776320431ef 100644 --- a/stl/inc/xstring +++ b/stl/inc/xstring @@ -2794,34 +2794,6 @@ public: } #endif // _HAS_CXX20 -private: - _CONSTEXPR20 void _Move_assign(basic_string& _Right, _Equal_allocators) noexcept { - _Tidy_deallocate(); - _Pocma(_Getal(), _Right._Getal()); - _Take_contents(_Right); - } - - _CONSTEXPR20 void _Move_assign(basic_string& _Right, _Propagate_allocators) noexcept { - if (_Getal() == _Right._Getal()) { - _Move_assign(_Right, _Equal_allocators{}); - } else { - // intentionally slams into noexcept on OOM, TRANSITION, VSO-466800 - _Mypair._Myval2._Orphan_all(); - _Mypair._Myval2._Reload_proxy( - _GET_PROXY_ALLOCATOR(_Alty, _Getal()), _GET_PROXY_ALLOCATOR(_Alty, _Right._Getal())); - _Pocma(_Getal(), _Right._Getal()); - _Take_contents(_Right); - } - } - - _CONSTEXPR20 void _Move_assign(basic_string& _Right, _No_propagate_allocators) { - if (_Getal() == _Right._Getal()) { - _Move_assign(_Right, _Equal_allocators{}); - } else { - assign(_Right._Mypair._Myval2._Myptr(), _Right._Mypair._Myval2._Mysize); - } - } - public: #if _HAS_CXX20 _NODISCARD bool _Move_assign_from_buffer(_Elem* const _Right, const size_type _Size, const size_type _Res) { @@ -2869,11 +2841,34 @@ public: #endif // _HAS_CXX20 _CONSTEXPR20 basic_string& operator=(basic_string&& _Right) noexcept( - noexcept(_Move_assign(_Right, _Choose_pocma<_Alty>{}))) { - if (this != _STD addressof(_Right)) { - _Move_assign(_Right, _Choose_pocma<_Alty>{}); + _Choose_pocma_v<_Alty> != _Pocma_values::_No_propagate_allocators) { + if (this == _STD addressof(_Right)) { + return *this; } + auto& _Al = _Getal(); + auto& _Right_al = _Right._Getal(); + constexpr auto _Pocma_val = _Choose_pocma_v<_Alty>; + if constexpr (_Pocma_val == _Pocma_values::_Propagate_allocators) { + if (_Al != _Right_al) { + // intentionally slams into noexcept on OOM, TRANSITION, VSO-466800 + _Mypair._Myval2._Orphan_all(); + _Mypair._Myval2._Reload_proxy(_GET_PROXY_ALLOCATOR(_Alty, _Al), _GET_PROXY_ALLOCATOR(_Alty, _Right_al)); + _Pocma(_Al, _Right_al); + _Take_contents(_Right); + return *this; + } + } else if constexpr (_Pocma_val == _Pocma_values::_No_propagate_allocators) { + if (_Al != _Right_al) { + assign(_Right._Mypair._Myval2._Myptr(), _Right._Mypair._Myval2._Mysize); + return *this; + } + } + + _Tidy_deallocate(); + _Pocma(_Al, _Right_al); + _Take_contents(_Right); + return *this; } @@ -3053,54 +3048,50 @@ private: } } - _CONSTEXPR20 void _Copy_assign(const basic_string& _Right, false_type) { - _Pocca(_Getal(), _Right._Getal()); - assign(_Right._Mypair._Myval2._Myptr(), _Right._Mypair._Myval2._Mysize); - } +public: + _CONSTEXPR20 basic_string& operator=(const basic_string& _Right) { + if (this == _STD addressof(_Right)) { + return *this; + } - _CONSTEXPR20 void _Copy_assign(const basic_string& _Right, true_type) { auto& _Al = _Getal(); const auto& _Right_al = _Right._Getal(); - if (_Al == _Right_al) { - _Copy_assign(_Right, false_type{}); - return; - } - - auto&& _Alproxy = _GET_PROXY_ALLOCATOR(_Alty, _Al); - auto&& _Right_alproxy = _GET_PROXY_ALLOCATOR(_Alty, _Right_al); - _Container_proxy_ptr<_Alty> _New_proxy(_Right_alproxy, _Leave_proxy_unbound{}); // throws - - if (_Right._Mypair._Myval2._Large_string_engaged()) { - const auto _New_size = _Right._Mypair._Myval2._Mysize; - const auto _New_capacity = _Calculate_growth(_New_size, 0, _Right.max_size()); - auto _Right_al_non_const = _Right_al; - const auto _New_ptr = _Right_al_non_const.allocate(_New_capacity); // throws + if constexpr (_Choose_pocca_v<_Alty>) { + if (_Al != _Right_al) { + auto&& _Alproxy = _GET_PROXY_ALLOCATOR(_Alty, _Al); + auto&& _Right_alproxy = _GET_PROXY_ALLOCATOR(_Alty, _Right_al); + _Container_proxy_ptr<_Alty> _New_proxy(_Right_alproxy, _Leave_proxy_unbound{}); // throws + + if (_Right._Mypair._Myval2._Large_string_engaged()) { + const auto _New_size = _Right._Mypair._Myval2._Mysize; + const auto _New_capacity = _Calculate_growth(_New_size, 0, _Right.max_size()); + auto _Right_al_non_const = _Right_al; + const auto _New_ptr = _Right_al_non_const.allocate(_New_capacity); // throws #if _HAS_CXX20 - if (_STD is_constant_evaluated()) { // Begin the lifetimes of the objects before copying to avoid UB - _Traits::assign(_Unfancy(_New_ptr), _New_size + 1, _Elem()); - } + if (_STD is_constant_evaluated()) { // Begin the lifetimes of the objects before copying to + // avoid UB + _Traits::assign(_Unfancy(_New_ptr), _New_size + 1, _Elem()); + } #endif // _HAS_CXX20 - _Traits::copy(_Unfancy(_New_ptr), _Unfancy(_Right._Mypair._Myval2._Bx._Ptr), _New_size + 1); - _Tidy_deallocate(); - _Mypair._Myval2._Bx._Ptr = _New_ptr; - _Mypair._Myval2._Mysize = _New_size; - _Mypair._Myval2._Myres = _New_capacity; - } else { - _Copy_assign_val_from_small(_Right); - } - - _Pocca(_Al, _Right_al); - _New_proxy._Bind(_Alproxy, _STD addressof(_Mypair._Myval2)); - } + _Traits::copy(_Unfancy(_New_ptr), _Unfancy(_Right._Mypair._Myval2._Bx._Ptr), _New_size + 1); + _Tidy_deallocate(); + _Mypair._Myval2._Bx._Ptr = _New_ptr; + _Mypair._Myval2._Mysize = _New_size; + _Mypair._Myval2._Myres = _New_capacity; + } else { + _Copy_assign_val_from_small(_Right); + } -public: - _CONSTEXPR20 basic_string& operator=(const basic_string& _Right) { - if (this != _STD addressof(_Right)) { - _Copy_assign(_Right, _Choose_pocca<_Alty>{}); + _Pocca(_Al, _Right_al); + _New_proxy._Bind(_Alproxy, _STD addressof(_Mypair._Myval2)); + return *this; + } } + _Pocca(_Al, _Right_al); + assign(_Right._Mypair._Myval2._Myptr(), _Right._Mypair._Myval2._Mysize); return *this; } diff --git a/stl/inc/xtree b/stl/inc/xtree index 11918980c41..718682e1f72 100644 --- a/stl/inc/xtree +++ b/stl/inc/xtree @@ -936,51 +936,48 @@ public: _Swap_val_excluding_comp(_Right); } -private: - void _Move_assign(_Tree& _Right, _Equal_allocators) noexcept(is_nothrow_move_assignable_v) { - clear(); - _Getcomp() = _Right._Getcomp(); // intentionally copy comparator, see LWG-2227 - _Pocma(_Getal(), _Right._Getal()); - _Swap_val_excluding_comp(_Right); - } - - void _Move_assign(_Tree& _Right, _Propagate_allocators) { - if (_Getal() == _Right._Getal()) { - _Move_assign(_Right, _Equal_allocators{}); - } else { - clear(); - _Getcomp() = _Right._Getcomp(); // intentionally copy comparator, see LWG-2227 - auto&& _Alproxy = _GET_PROXY_ALLOCATOR(_Alnode, _Getal()); - auto&& _Right_alproxy = _GET_PROXY_ALLOCATOR(_Alnode, _Right._Getal()); - _Container_proxy_ptr<_Alty> _Proxy(_Right_alproxy, _Leave_proxy_unbound{}); - const auto _Scary = _Get_scary(); - const auto _Right_scary = _Right._Get_scary(); - const auto _Newhead = _STD exchange(_Right_scary->_Myhead, _Node::_Buyheadnode(_Right._Getal())); - const auto _Newsize = _STD exchange(_Right_scary->_Mysize, size_type{0}); - _Scary->_Erase_head(_Getal()); - _Pocma(_Getal(), _Right._Getal()); - _Scary->_Myhead = _Newhead; - _Scary->_Mysize = _Newsize; - _Proxy._Bind(_Alproxy, _Scary); - _Scary->_Swap_proxy_and_iterators(*_Right_scary); +public: + _Tree& operator=(_Tree&& _Right) noexcept( + _Choose_pocma_v<_Alnode> == _Pocma_values::_Equal_allocators && is_nothrow_move_assignable_v) { + if (this == _STD addressof(_Right)) { + return *this; } - } - void _Move_assign(_Tree& _Right, _No_propagate_allocators) { - if (_Getal() == _Right._Getal()) { - _Move_assign(_Right, _Equal_allocators{}); - } else { - clear(); - _Getcomp() = _Right._Getcomp(); // intentionally copy comparator, see LWG-2227 - _Copy(_Right, _Move_tag{}); + auto& _Al = _Getal(); + auto& _Right_al = _Right._Getal(); + constexpr auto _Pocma_val = _Choose_pocma_v<_Alnode>; + if constexpr (_Pocma_val == _Pocma_values::_Propagate_allocators) { + if (_Al != _Right_al) { + clear(); + _Getcomp() = _Right._Getcomp(); // intentionally copy comparator, see LWG-2227 + auto&& _Alproxy = _GET_PROXY_ALLOCATOR(_Alnode, _Al); + auto&& _Right_alproxy = _GET_PROXY_ALLOCATOR(_Alnode, _Right_al); + _Container_proxy_ptr<_Alty> _Proxy(_Right_alproxy, _Leave_proxy_unbound{}); + const auto _Scary = _Get_scary(); + const auto _Right_scary = _Right._Get_scary(); + const auto _Newhead = _STD exchange(_Right_scary->_Myhead, _Node::_Buyheadnode(_Right_al)); + const auto _Newsize = _STD exchange(_Right_scary->_Mysize, size_type{0}); + _Scary->_Erase_head(_Al); + _Pocma(_Al, _Right_al); + _Scary->_Myhead = _Newhead; + _Scary->_Mysize = _Newsize; + _Proxy._Bind(_Alproxy, _Scary); + _Scary->_Swap_proxy_and_iterators(*_Right_scary); + return *this; + } + } else if constexpr (_Pocma_val == _Pocma_values::_No_propagate_allocators) { + if (_Al != _Right_al) { + clear(); + _Getcomp() = _Right._Getcomp(); // intentionally copy comparator, see LWG-2227 + _Copy(_Right, _Move_tag{}); + return *this; + } } - } -public: - _Tree& operator=(_Tree&& _Right) noexcept(noexcept(_Move_assign(_Right, _Choose_pocma<_Alnode>{}))) { - if (this != _STD addressof(_Right)) { - _Move_assign(_Right, _Choose_pocma<_Alnode>{}); - } + clear(); + _Getcomp() = _Right._Getcomp(); // intentionally copy comparator, see LWG-2227 + _Pocma(_Al, _Right_al); + _Swap_val_excluding_comp(_Right); return *this; } @@ -1090,43 +1087,39 @@ public: #endif // _ITERATOR_DEBUG_LEVEL != 0 } -private: - void _Copy_assign(const _Tree& _Right, false_type) { - clear(); - _Getcomp() = _Right._Getcomp(); - _Pocca(_Getal(), _Right._Getal()); - _Copy(_Right, _Copy_tag{}); - } - - void _Copy_assign(const _Tree& _Right, true_type) { - if (_Getal() == _Right._Getal()) { - _Copy_assign(_Right, false_type{}); - } else { - clear(); - const auto _Scary = _Get_scary(); - _Scary->_Orphan_all(); - auto& _Al = _Getal(); - auto&& _Alproxy = _GET_PROXY_ALLOCATOR(_Alnode, _Al); - const auto& _Right_al = _Right._Getal(); - auto&& _Right_alproxy = _GET_PROXY_ALLOCATOR(_Alnode, _Right_al); - _Container_proxy_ptr<_Alty> _Proxy(_Right_alproxy, _Leave_proxy_unbound{}); - auto _Right_al_non_const = _Right_al; - auto _Newhead = _Node::_Buyheadnode(_Right_al_non_const); - _Node::_Freenode0(_Al, _Scary->_Myhead); - _Pocca(_Al, _Right_al); - _Scary->_Myhead = _Newhead; - _Proxy._Bind(_Alproxy, _Scary); - _Getcomp() = _Right._Getcomp(); - _Copy(_Right, _Copy_tag{}); - } - } - public: _Tree& operator=(const _Tree& _Right) { - if (this != _STD addressof(_Right)) { - _Copy_assign(_Right, _Choose_pocca<_Alnode>{}); + if (this == _STD addressof(_Right)) { + return *this; + } + + auto& _Al = _Getal(); + auto& _Right_al = _Right._Getal(); + if constexpr (_Choose_pocca_v<_Alnode>) { + if (_Al != _Right_al) { + clear(); + const auto _Scary = _Get_scary(); + _Scary->_Orphan_all(); + auto&& _Alproxy = _GET_PROXY_ALLOCATOR(_Alnode, _Al); + auto&& _Right_alproxy = _GET_PROXY_ALLOCATOR(_Alnode, _Right_al); + _Container_proxy_ptr<_Alty> _Proxy(_Right_alproxy, _Leave_proxy_unbound{}); + auto _Right_al_non_const = _Right_al; + auto _Newhead = _Node::_Buyheadnode(_Right_al_non_const); + _Node::_Freenode0(_Al, _Scary->_Myhead); + _Pocca(_Al, _Right_al); + _Scary->_Myhead = _Newhead; + _Proxy._Bind(_Alproxy, _Scary); + _Getcomp() = _Right._Getcomp(); + _Copy(_Right, _Copy_tag{}); + return *this; + } } + clear(); + _Getcomp() = _Right._Getcomp(); + _Pocca(_Al, _Right_al); + _Copy(_Right, _Copy_tag{}); + return *this; }