From 9ef5885ef19d16f6dda365864283b372e68485ee Mon Sep 17 00:00:00 2001 From: Michael Schellenberger Costa Date: Tue, 23 Mar 2021 09:44:09 +0100 Subject: [PATCH 01/13] Inline _UFill --- stl/inc/vector | 36 +++++++++++++++++++----------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/stl/inc/vector b/stl/inc/vector index 9a943420d43..92c62028e7a 100644 --- a/stl/inc/vector +++ b/stl/inc/vector @@ -490,8 +490,12 @@ private: if (_Count != 0) { _Buy_nonzero(_Count); _Tidy_guard _Guard{this}; - _My_data._Mylast = _Ufill(_My_data._Myfirst, _Count, _Val); - _Guard._Target = nullptr; + if constexpr (is_same_v<_Ty2, _Ty>) { + _My_data._Mylast = _Uninitialized_fill_n(_My_data._Myfirst, _Count, _Val, _Getal()); + } else { + _My_data._Mylast = _Uninitialized_value_construct_n(_My_data._Myfirst, _Count, _Getal()); + } + _Guard._Target = nullptr; } _Proxy._Release(); @@ -880,7 +884,7 @@ public: pointer _Constructed_first = _Constructed_last; _TRY_BEGIN - _Ufill(_Newvec + _Whereoff, _Count, _Val); + _Uninitialized_fill_n(_Newvec + _Whereoff, _Count, _Val, _Getal()); _Constructed_first = _Newvec + _Whereoff; if (_One_at_back) { // provide strong guarantee @@ -906,7 +910,7 @@ public: _Orphan_range(_Whereptr, _Oldlast); if (_Count > _Affected_elements) { // new stuff spills off end - _Mylast = _Ufill(_Oldlast, _Count - _Affected_elements, _Tmp); + _Mylast = _Uninitialized_fill_n(_Oldlast, _Count - _Affected_elements, _Tmp, _Getal()); _Mylast = _Umove(_Whereptr, _Oldlast, _Mylast); _STD fill(_Whereptr, _Oldlast, _Tmp); } else { // new stuff can all be assigned @@ -1094,7 +1098,7 @@ public: _STD fill(_Myfirst, _Mylast, _Val); } - _Mylast = _Ufill(_Mylast, _Newsize - _Oldsize, _Val); + _Mylast = _Uninitialized_fill_n(_Mylast, _Newsize - _Oldsize, _Val, _Getal()); } else { const pointer _Newlast = _Myfirst + _Newsize; _STD fill(_Myfirst, _Newlast, _Val); @@ -1243,7 +1247,11 @@ private: pointer _Appended_last = _Appended_first; _TRY_BEGIN - _Appended_last = _Ufill(_Appended_first, _Newsize - _Oldsize, _Val); + if constexpr (is_same_v<_Ty2, _Ty>) { + _Appended_last = _Uninitialized_fill_n(_Appended_first, _Newsize - _Oldsize, _Val, _Getal()); + } else { + _Appended_last = _Uninitialized_value_construct_n(_Appended_first, _Newsize - _Oldsize, _Getal()); + } _Umove_if_noexcept(_Myfirst, _Mylast, _Newvec); _CATCH_ALL _Destroy(_Appended_first, _Appended_last); @@ -1277,7 +1285,11 @@ private: } const pointer _Oldlast = _Mylast; - _Mylast = _Ufill(_Oldlast, _Newsize - _Oldsize, _Val); + if constexpr (is_same_v<_Ty2, _Ty>) { + _Mylast = _Uninitialized_fill_n(_Oldlast, _Newsize - _Oldsize, _Val, _Getal()); + } else { + _Mylast = _Uninitialized_value_construct_n(_Oldlast, _Newsize - _Oldsize, _Getal()); + } _Orphan_range(_Oldlast, _Oldlast); } @@ -1638,16 +1650,6 @@ public: } private: - _CONSTEXPR20_CONTAINER pointer _Ufill(pointer _Dest, const size_type _Count, const _Ty& _Val) { - // fill raw _Dest with _Count copies of _Val, using allocator - return _Uninitialized_fill_n(_Dest, _Count, _Val, _Getal()); - } - - _CONSTEXPR20_CONTAINER pointer _Ufill(pointer _Dest, const size_type _Count, _Value_init_tag) { - // fill raw _Dest with _Count value-initialized objects, using allocator - return _Uninitialized_value_construct_n(_Dest, _Count, _Getal()); - } - template _CONSTEXPR20_CONTAINER pointer _Ucopy(_Iter _First, _Iter _Last, pointer _Dest) { // copy [_First, _Last) to raw _Dest, using allocator From e5379d6de4db8215ecb3b54018c2da71b0a49332 Mon Sep 17 00:00:00 2001 From: Michael Schellenberger Costa Date: Tue, 23 Mar 2021 09:47:19 +0100 Subject: [PATCH 02/13] Inline _Ucopy --- stl/inc/vector | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/stl/inc/vector b/stl/inc/vector index 92c62028e7a..b5794a1e833 100644 --- a/stl/inc/vector +++ b/stl/inc/vector @@ -531,7 +531,7 @@ private: _Buy_nonzero(_Count); _Tidy_guard _Guard{this}; auto& _My_data = _Mypair._Myval2; - _My_data._Mylast = _Ucopy(_First, _Last, _My_data._Myfirst); + _My_data._Mylast = _Uninitialized_copy(_First, _Last, _My_data._Myfirst, _Getal()); _Guard._Target = nullptr; } } @@ -566,7 +566,7 @@ public: if (_Rightfirst != _Rightlast) { _Buy_raw(static_cast(_Rightlast - _Rightfirst)); _Tidy_guard _Guard{this}; - _My_data._Mylast = _Ucopy(_Rightfirst, _Rightlast, _My_data._Myfirst); + _My_data._Mylast = _Uninitialized_copy(_Rightfirst, _Rightlast, _My_data._Myfirst, _Getal()); _Guard._Target = nullptr; } @@ -583,7 +583,7 @@ public: if (_Rightfirst != _Rightlast) { _Buy_raw(static_cast(_Rightlast - _Rightfirst)); _Tidy_guard _Guard{this}; - _My_data._Mylast = _Ucopy(_Rightfirst, _Rightlast, _My_data._Myfirst); + _My_data._Mylast = _Uninitialized_copy(_Rightfirst, _Rightlast, _My_data._Myfirst, _Getal()); _Guard._Target = nullptr; } @@ -980,7 +980,7 @@ private: pointer _Constructed_first = _Constructed_last; _TRY_BEGIN - _Ucopy(_First, _Last, _Newvec + _Whereoff); + _Uninitialized_copy(_First, _Last, _Newvec + _Whereoff, _Getal()); _Constructed_first = _Newvec + _Whereoff; if (_Count == 1 && _Whereptr == _Oldlast) { // one at back, provide strong guarantee @@ -1009,7 +1009,7 @@ private: _Destroy(_Whereptr, _Whereptr + _Count); _TRY_BEGIN - _Ucopy(_First, _Last, _Whereptr); + _Uninitialized_copy(_First, _Last, _Whereptr, _Getal()); _CATCH_ALL // glue the broken pieces back together @@ -1034,7 +1034,7 @@ private: _Destroy(_Whereptr, _Oldlast); _TRY_BEGIN - _Ucopy(_First, _Last, _Whereptr); + _Uninitialized_copy(_First, _Last, _Whereptr, _Getal()); _CATCH_ALL // glue the broken pieces back together @@ -1177,7 +1177,7 @@ private: // performance note: traversing [_First, _Mid) twice const _Iter _Mid = _STD next(_First, static_cast(_Oldsize)); _Copy_unchecked(_First, _Mid, _Myfirst); - _Mylast = _Ucopy(_Mid, _Last, _Mylast); + _Mylast = _Uninitialized_copy(_Mid, _Last, _Mylast, _Getal()); } else { const pointer _Newlast = _Myfirst + _Newsize; _Copy_unchecked(_First, _Last, _Myfirst); @@ -1650,12 +1650,6 @@ public: } private: - template - _CONSTEXPR20_CONTAINER pointer _Ucopy(_Iter _First, _Iter _Last, pointer _Dest) { - // copy [_First, _Last) to raw _Dest, using allocator - return _Uninitialized_copy(_First, _Last, _Dest, _Getal()); - } - _CONSTEXPR20_CONTAINER pointer _Umove(pointer _First, pointer _Last, pointer _Dest) { // move [_First, _Last) to raw _Dest, using allocator return _Uninitialized_move(_First, _Last, _Dest, _Getal()); From ba7ea4f3d18a6dbb0088a4f7c9b8dc19dd3914bc Mon Sep 17 00:00:00 2001 From: Michael Schellenberger Costa Date: Tue, 23 Mar 2021 09:55:12 +0100 Subject: [PATCH 03/13] Inline _Umove --- stl/inc/vector | 33 ++++++++++++++------------------- 1 file changed, 14 insertions(+), 19 deletions(-) diff --git a/stl/inc/vector b/stl/inc/vector index b5794a1e833..1b508a33ea2 100644 --- a/stl/inc/vector +++ b/stl/inc/vector @@ -607,7 +607,7 @@ private: _Buy_raw(static_cast(_Rightlast - _Rightfirst)); _Tidy_guard _Guard{this}; auto& _My_data = _Mypair._Myval2; - _My_data._Mylast = _Umove(_Rightfirst, _Rightlast, _My_data._Myfirst); + _My_data._Mylast = _Uninitialized_move(_Rightfirst, _Rightlast, _My_data._Myfirst, _Getal()); _Guard._Target = nullptr; } return; @@ -691,7 +691,7 @@ private: const pointer _Mid = _First + _Oldsize; _Move_unchecked(_First, _Mid, _Myfirst); - _Mylast = _Umove(_Mid, _Last, _Mylast); + _Mylast = _Uninitialized_move(_Mid, _Last, _Mylast, _Getal()); } else { const pointer _Newlast = _Myfirst + _Newsize; _Move_unchecked(_First, _Last, _Myfirst); @@ -796,9 +796,9 @@ public: if (_Whereptr == _Mylast) { // at back, provide strong guarantee _Umove_if_noexcept(_Myfirst, _Mylast, _Newvec); } else { // provide basic guarantee - _Umove(_Myfirst, _Whereptr, _Newvec); + _Uninitialized_move(_Myfirst, _Whereptr, _Newvec, _Getal()); _Constructed_first = _Newvec; - _Umove(_Whereptr, _Mylast, _Newvec + _Whereoff + 1); + _Uninitialized_move(_Whereptr, _Mylast, _Newvec + _Whereoff + 1, _Getal()); } _CATCH_ALL _Destroy(_Constructed_first, _Constructed_last); @@ -890,9 +890,9 @@ public: if (_One_at_back) { // provide strong guarantee _Umove_if_noexcept(_Oldfirst, _Oldlast, _Newvec); } else { // provide basic guarantee - _Umove(_Oldfirst, _Whereptr, _Newvec); + _Uninitialized_move(_Oldfirst, _Whereptr, _Newvec, _Getal()); _Constructed_first = _Newvec; - _Umove(_Whereptr, _Oldlast, _Newvec + _Whereoff + _Count); + _Uninitialized_move(_Whereptr, _Oldlast, _Newvec + _Whereoff + _Count, _Getal()); } _CATCH_ALL _Destroy(_Constructed_first, _Constructed_last); @@ -911,10 +911,10 @@ public: if (_Count > _Affected_elements) { // new stuff spills off end _Mylast = _Uninitialized_fill_n(_Oldlast, _Count - _Affected_elements, _Tmp, _Getal()); - _Mylast = _Umove(_Whereptr, _Oldlast, _Mylast); + _Mylast = _Uninitialized_move(_Whereptr, _Oldlast, _Mylast, _Getal()); _STD fill(_Whereptr, _Oldlast, _Tmp); } else { // new stuff can all be assigned - _Mylast = _Umove(_Oldlast - _Count, _Oldlast, _Oldlast); + _Mylast = _Uninitialized_move(_Oldlast - _Count, _Oldlast, _Oldlast, _Getal()); _Move_backward_unchecked(_Whereptr, _Oldlast - _Count, _Oldlast); _STD fill(_Whereptr, _Whereptr + _Count, _Tmp); } @@ -986,9 +986,9 @@ private: if (_Count == 1 && _Whereptr == _Oldlast) { // one at back, provide strong guarantee _Umove_if_noexcept(_Oldfirst, _Oldlast, _Newvec); } else { // provide basic guarantee - _Umove(_Oldfirst, _Whereptr, _Newvec); + _Uninitialized_move(_Oldfirst, _Whereptr, _Newvec, _Getal()); _Constructed_first = _Newvec; - _Umove(_Whereptr, _Oldlast, _Newvec + _Whereoff + _Count); + _Uninitialized_move(_Whereptr, _Oldlast, _Newvec + _Whereoff + _Count, _Getal()); } _CATCH_ALL _Destroy(_Constructed_first, _Constructed_last); @@ -1004,7 +1004,7 @@ private: const auto _Affected_elements = static_cast(_Oldlast - _Whereptr); if (_Count < _Affected_elements) { // some affected elements must be assigned - _Mylast = _Umove(_Oldlast - _Count, _Oldlast, _Oldlast); + _Mylast = _Uninitialized_move(_Oldlast - _Count, _Oldlast, _Oldlast, _Getal()); _Move_backward_unchecked(_Whereptr, _Oldlast - _Count, _Oldlast); _Destroy(_Whereptr, _Whereptr + _Count); @@ -1014,7 +1014,7 @@ private: // glue the broken pieces back together _TRY_BEGIN - _Umove(_Whereptr + _Count, _Whereptr + 2 * _Count, _Whereptr); + _Uninitialized_move(_Whereptr + _Count, _Whereptr + 2 * _Count, _Whereptr, _Getal()); _CATCH_ALL // vaporize the detached piece _Orphan_range(_Whereptr, _Oldlast); @@ -1030,7 +1030,7 @@ private: _CATCH_END } else { // affected elements don't overlap before/after const pointer _Relocated = _Whereptr + _Count; - _Mylast = _Umove(_Whereptr, _Oldlast, _Relocated); + _Mylast = _Uninitialized_move(_Whereptr, _Oldlast, _Relocated, _Getal()); _Destroy(_Whereptr, _Oldlast); _TRY_BEGIN @@ -1039,7 +1039,7 @@ private: // glue the broken pieces back together _TRY_BEGIN - _Umove(_Relocated, _Mylast, _Whereptr); + _Uninitialized_move(_Relocated, _Mylast, _Whereptr, _Getal()); _CATCH_ALL // vaporize the detached piece _Orphan_range(_Whereptr, _Oldlast); @@ -1650,11 +1650,6 @@ public: } private: - _CONSTEXPR20_CONTAINER pointer _Umove(pointer _First, pointer _Last, pointer _Dest) { - // move [_First, _Last) to raw _Dest, using allocator - return _Uninitialized_move(_First, _Last, _Dest, _Getal()); - } - _CONSTEXPR20_CONTAINER void _Umove_if_noexcept1(pointer _First, pointer _Last, pointer _Dest, true_type) { // move [_First, _Last) to raw _Dest, using allocator _Uninitialized_move(_First, _Last, _Dest, _Getal()); From f75448e30ad3cd1b95ffb413bf9f8c81b8c22876 Mon Sep 17 00:00:00 2001 From: Michael Schellenberger Costa Date: Tue, 23 Mar 2021 09:58:46 +0100 Subject: [PATCH 04/13] Inline _Umove_if_noexcept --- stl/inc/vector | 46 +++++++++++++++++++++++++--------------------- 1 file changed, 25 insertions(+), 21 deletions(-) diff --git a/stl/inc/vector b/stl/inc/vector index 1b508a33ea2..9bea3b528ea 100644 --- a/stl/inc/vector +++ b/stl/inc/vector @@ -794,7 +794,11 @@ public: _Constructed_first = _Newvec + _Whereoff; if (_Whereptr == _Mylast) { // at back, provide strong guarantee - _Umove_if_noexcept(_Myfirst, _Mylast, _Newvec); + if constexpr (is_nothrow_move_constructible_v<_Ty> || !is_copy_constructible_v<_Ty>) { + _Uninitialized_move(_Myfirst, _Mylast, _Newvec, _Getal()); + } else { + _Uninitialized_copy(_Myfirst, _Mylast, _Newvec, _Getal()); + } } else { // provide basic guarantee _Uninitialized_move(_Myfirst, _Whereptr, _Newvec, _Getal()); _Constructed_first = _Newvec; @@ -888,7 +892,11 @@ public: _Constructed_first = _Newvec + _Whereoff; if (_One_at_back) { // provide strong guarantee - _Umove_if_noexcept(_Oldfirst, _Oldlast, _Newvec); + if constexpr (is_nothrow_move_constructible_v<_Ty> || !is_copy_constructible_v<_Ty>) { + _Uninitialized_move(_Oldfirst, _Oldlast, _Newvec, _Getal()); + } else { + _Uninitialized_copy(_Oldfirst, _Oldlast, _Newvec, _Getal()); + } } else { // provide basic guarantee _Uninitialized_move(_Oldfirst, _Whereptr, _Newvec, _Getal()); _Constructed_first = _Newvec; @@ -984,7 +992,11 @@ private: _Constructed_first = _Newvec + _Whereoff; if (_Count == 1 && _Whereptr == _Oldlast) { // one at back, provide strong guarantee - _Umove_if_noexcept(_Oldfirst, _Oldlast, _Newvec); + if constexpr (is_nothrow_move_constructible_v<_Ty> || !is_copy_constructible_v<_Ty>) { + _Uninitialized_move(_Oldfirst, _Oldlast, _Newvec, _Getal()); + } else { + _Uninitialized_copy(_Oldfirst, _Oldlast, _Newvec, _Getal()); + } } else { // provide basic guarantee _Uninitialized_move(_Oldfirst, _Whereptr, _Newvec, _Getal()); _Constructed_first = _Newvec; @@ -1252,7 +1264,11 @@ private: } else { _Appended_last = _Uninitialized_value_construct_n(_Appended_first, _Newsize - _Oldsize, _Getal()); } - _Umove_if_noexcept(_Myfirst, _Mylast, _Newvec); + if constexpr (is_nothrow_move_constructible_v<_Ty> || !is_copy_constructible_v<_Ty>) { + _Uninitialized_move(_Myfirst, _Mylast, _Newvec, _Getal()); + } else { + _Uninitialized_copy(_Myfirst, _Mylast, _Newvec, _Getal()); + } _CATCH_ALL _Destroy(_Appended_first, _Appended_last); _Getal().deallocate(_Newvec, _Newcapacity); @@ -1319,7 +1335,11 @@ private: const pointer _Newvec = _Getal().allocate(_Newcapacity); _TRY_BEGIN - _Umove_if_noexcept(_Myfirst, _Mylast, _Newvec); + if constexpr (is_nothrow_move_constructible_v<_Ty> || !is_copy_constructible_v<_Ty>) { + _Uninitialized_move(_Myfirst, _Mylast, _Newvec, _Getal()); + } else { + _Uninitialized_copy(_Myfirst, _Mylast, _Newvec, _Getal()); + } _CATCH_ALL _Getal().deallocate(_Newvec, _Newcapacity); _RERAISE; @@ -1650,22 +1670,6 @@ public: } private: - _CONSTEXPR20_CONTAINER void _Umove_if_noexcept1(pointer _First, pointer _Last, pointer _Dest, true_type) { - // move [_First, _Last) to raw _Dest, using allocator - _Uninitialized_move(_First, _Last, _Dest, _Getal()); - } - - _CONSTEXPR20_CONTAINER void _Umove_if_noexcept1(pointer _First, pointer _Last, pointer _Dest, false_type) { - // copy [_First, _Last) to raw _Dest, using allocator - _Uninitialized_copy(_First, _Last, _Dest, _Getal()); - } - - _CONSTEXPR20_CONTAINER void _Umove_if_noexcept(pointer _First, pointer _Last, pointer _Dest) { - // move_if_noexcept [_First, _Last) to raw _Dest, using allocator - _Umove_if_noexcept1(_First, _Last, _Dest, - bool_constant, negation>>>{}); - } - _CONSTEXPR20_CONTAINER void _Destroy(pointer _First, pointer _Last) { // destroy [_First, _Last) using allocator _Destroy_range(_First, _Last, _Getal()); From 49aab9ac66c8d7edbe21357cd438aded90d98c76 Mon Sep 17 00:00:00 2001 From: Michael Schellenberger Costa Date: Tue, 23 Mar 2021 10:01:05 +0100 Subject: [PATCH 05/13] Inline _Destroy --- stl/inc/vector | 45 ++++++++++++++++++++------------------------- 1 file changed, 20 insertions(+), 25 deletions(-) diff --git a/stl/inc/vector b/stl/inc/vector index 9bea3b528ea..b9bd7f09395 100644 --- a/stl/inc/vector +++ b/stl/inc/vector @@ -695,7 +695,7 @@ private: } else { const pointer _Newlast = _Myfirst + _Newsize; _Move_unchecked(_First, _Last, _Myfirst); - _Destroy(_Newlast, _Mylast); + _Destroy_range(_Newlast, _Mylast, _Getal()); _Mylast = _Newlast; } } @@ -805,7 +805,7 @@ public: _Uninitialized_move(_Whereptr, _Mylast, _Newvec + _Whereoff + 1, _Getal()); } _CATCH_ALL - _Destroy(_Constructed_first, _Constructed_last); + _Destroy_range(_Constructed_first, _Constructed_last, _Getal()); _Al.deallocate(_Newvec, _Newcapacity); _RERAISE; _CATCH_END @@ -903,7 +903,7 @@ public: _Uninitialized_move(_Whereptr, _Oldlast, _Newvec + _Whereoff + _Count, _Getal()); } _CATCH_ALL - _Destroy(_Constructed_first, _Constructed_last); + _Destroy_range(_Constructed_first, _Constructed_last, _Getal()); _Getal().deallocate(_Newvec, _Newcapacity); _RERAISE; _CATCH_END @@ -1003,7 +1003,7 @@ private: _Uninitialized_move(_Whereptr, _Oldlast, _Newvec + _Whereoff + _Count, _Getal()); } _CATCH_ALL - _Destroy(_Constructed_first, _Constructed_last); + _Destroy_range(_Constructed_first, _Constructed_last, _Getal()); _Getal().deallocate(_Newvec, _Newcapacity); _RERAISE; _CATCH_END @@ -1018,7 +1018,7 @@ private: if (_Count < _Affected_elements) { // some affected elements must be assigned _Mylast = _Uninitialized_move(_Oldlast - _Count, _Oldlast, _Oldlast, _Getal()); _Move_backward_unchecked(_Whereptr, _Oldlast - _Count, _Oldlast); - _Destroy(_Whereptr, _Whereptr + _Count); + _Destroy_range(_Whereptr, _Whereptr + _Count, _Getal()); _TRY_BEGIN _Uninitialized_copy(_First, _Last, _Whereptr, _Getal()); @@ -1030,20 +1030,20 @@ private: _CATCH_ALL // vaporize the detached piece _Orphan_range(_Whereptr, _Oldlast); - _Destroy(_Whereptr + _Count, _Mylast); + _Destroy_range(_Whereptr + _Count, _Mylast, _Getal()); _Mylast = _Whereptr; _RERAISE; _CATCH_END _Move_unchecked(_Whereptr + 2 * _Count, _Mylast, _Whereptr + _Count); - _Destroy(_Oldlast, _Mylast); + _Destroy_range(_Oldlast, _Mylast, _Getal()); _Mylast = _Oldlast; _RERAISE; _CATCH_END } else { // affected elements don't overlap before/after const pointer _Relocated = _Whereptr + _Count; _Mylast = _Uninitialized_move(_Whereptr, _Oldlast, _Relocated, _Getal()); - _Destroy(_Whereptr, _Oldlast); + _Destroy_range(_Whereptr, _Oldlast, _Getal()); _TRY_BEGIN _Uninitialized_copy(_First, _Last, _Whereptr, _Getal()); @@ -1055,12 +1055,12 @@ private: _CATCH_ALL // vaporize the detached piece _Orphan_range(_Whereptr, _Oldlast); - _Destroy(_Relocated, _Mylast); + _Destroy_range(_Relocated, _Mylast, _Getal()); _Mylast = _Whereptr; _RERAISE; _CATCH_END - _Destroy(_Relocated, _Mylast); + _Destroy_range(_Relocated, _Mylast, _Getal()); _Mylast = _Oldlast; _RERAISE; _CATCH_END @@ -1114,7 +1114,7 @@ public: } else { const pointer _Newlast = _Myfirst + _Newsize; _STD fill(_Myfirst, _Newlast, _Val); - _Destroy(_Newlast, _Mylast); + _Destroy_range(_Newlast, _Mylast, _Getal()); _Mylast = _Newlast; } } @@ -1141,7 +1141,7 @@ private: // If we've exhausted both: Trim does nothing, then Append does nothing. // Trim. - _Destroy(_Next, _Mylast); + _Destroy_range(_Next, _Mylast, _Getal()); _Mylast = _Next; // Append. @@ -1193,7 +1193,7 @@ private: } else { const pointer _Newlast = _Myfirst + _Newsize; _Copy_unchecked(_First, _Last, _Myfirst); - _Destroy(_Newlast, _Mylast); + _Destroy_range(_Newlast, _Mylast, _Getal()); _Mylast = _Newlast; } } @@ -1270,7 +1270,7 @@ private: _Uninitialized_copy(_Myfirst, _Mylast, _Newvec, _Getal()); } _CATCH_ALL - _Destroy(_Appended_first, _Appended_last); + _Destroy_range(_Appended_first, _Appended_last, _Getal()); _Getal().deallocate(_Newvec, _Newcapacity); _RERAISE; _CATCH_END @@ -1288,7 +1288,7 @@ private: if (_Newsize < _Oldsize) { // trim const pointer _Newlast = _Myfirst + _Newsize; _Orphan_range(_Newlast, _Mylast); - _Destroy(_Newlast, _Mylast); + _Destroy_range(_Newlast, _Mylast, _Getal()); _Mylast = _Newlast; return; } @@ -1386,7 +1386,7 @@ private: const size_type _Newcapacity = _Calculate_growth(_Newsize); if (_Myfirst) { // destroy and deallocate old array - _Destroy(_Myfirst, _Mylast); + _Destroy_range(_Myfirst, _Mylast, _Getal()); _Getal().deallocate(_Myfirst, static_cast(_Myend - _Myfirst)); _Myfirst = nullptr; @@ -1471,7 +1471,7 @@ public: _Orphan_range(_Firstptr, _Mylast); const pointer _Newlast = _Move_unchecked(_Lastptr, _Mylast, _Firstptr); - _Destroy(_Newlast, _Mylast); + _Destroy_range(_Newlast, _Mylast, _Getal()); _Mylast = _Newlast; } @@ -1484,7 +1484,7 @@ public: pointer& _Mylast = _My_data._Mylast; _My_data._Orphan_all(); - _Destroy(_Myfirst, _Mylast); + _Destroy_range(_Myfirst, _Mylast, _Getal()); _Mylast = _Myfirst; } @@ -1670,11 +1670,6 @@ public: } private: - _CONSTEXPR20_CONTAINER void _Destroy(pointer _First, pointer _Last) { - // destroy [_First, _Last) using allocator - _Destroy_range(_First, _Last, _Getal()); - } - _CONSTEXPR20_CONTAINER size_type _Calculate_growth(const size_type _Newsize) const { // given _Oldcapacity and _Newsize, calculate geometric growth const size_type _Oldcapacity = capacity(); @@ -1738,7 +1733,7 @@ private: _My_data._Orphan_all(); if (_Myfirst) { // destroy and deallocate old array - _Destroy(_Myfirst, _Mylast); + _Destroy_range(_Myfirst, _Mylast, _Getal()); _Getal().deallocate(_Myfirst, static_cast(_Myend - _Myfirst)); } @@ -1756,7 +1751,7 @@ private: _My_data._Orphan_all(); if (_Myfirst) { // destroy and deallocate old array - _Destroy(_Myfirst, _Mylast); + _Destroy_range(_Myfirst, _Mylast, _Getal()); _Getal().deallocate(_Myfirst, static_cast(_Myend - _Myfirst)); _Myfirst = nullptr; From f387efe075e6fc9fc65eeb7f18484b4c6df9c1f4 Mon Sep 17 00:00:00 2001 From: Michael Schellenberger Costa Date: Tue, 23 Mar 2021 10:07:50 +0100 Subject: [PATCH 06/13] Pull some calls to _Getal() into a local variable --- stl/inc/vector | 127 +++++++++++++++++++++++++++---------------------- 1 file changed, 69 insertions(+), 58 deletions(-) diff --git a/stl/inc/vector b/stl/inc/vector index b9bd7f09395..66cd02491d4 100644 --- a/stl/inc/vector +++ b/stl/inc/vector @@ -485,15 +485,16 @@ private: template _CONSTEXPR20_CONTAINER void _Construct_n_copies_of_ty(_CRT_GUARDOVERFLOW const size_type _Count, const _Ty2& _Val) { auto&& _Alproxy = _GET_PROXY_ALLOCATOR(_Alty, _Getal()); + auto& _Al = _Getal(); auto& _My_data = _Mypair._Myval2; _Container_proxy_ptr<_Alty> _Proxy(_Alproxy, _My_data); if (_Count != 0) { _Buy_nonzero(_Count); _Tidy_guard _Guard{this}; if constexpr (is_same_v<_Ty2, _Ty>) { - _My_data._Mylast = _Uninitialized_fill_n(_My_data._Myfirst, _Count, _Val, _Getal()); + _My_data._Mylast = _Uninitialized_fill_n(_My_data._Myfirst, _Count, _Val, _Al); } else { - _My_data._Mylast = _Uninitialized_value_construct_n(_My_data._Myfirst, _Count, _Getal()); + _My_data._Mylast = _Uninitialized_value_construct_n(_My_data._Myfirst, _Count, _Al); } _Guard._Target = nullptr; } @@ -859,6 +860,7 @@ public: // insert _Count * _Val at _Where const pointer _Whereptr = _Where._Ptr; + auto& _Al = _Getal(); auto& _My_data = _Mypair._Myval2; pointer& _Mylast = _My_data._Mylast; @@ -883,28 +885,28 @@ public: const size_type _Newsize = _Oldsize + _Count; const size_type _Newcapacity = _Calculate_growth(_Newsize); - const pointer _Newvec = _Getal().allocate(_Newcapacity); + const pointer _Newvec = _Al.allocate(_Newcapacity); const pointer _Constructed_last = _Newvec + _Whereoff + _Count; pointer _Constructed_first = _Constructed_last; _TRY_BEGIN - _Uninitialized_fill_n(_Newvec + _Whereoff, _Count, _Val, _Getal()); + _Uninitialized_fill_n(_Newvec + _Whereoff, _Count, _Val, _Al); _Constructed_first = _Newvec + _Whereoff; if (_One_at_back) { // provide strong guarantee if constexpr (is_nothrow_move_constructible_v<_Ty> || !is_copy_constructible_v<_Ty>) { - _Uninitialized_move(_Oldfirst, _Oldlast, _Newvec, _Getal()); + _Uninitialized_move(_Oldfirst, _Oldlast, _Newvec, _Al); } else { - _Uninitialized_copy(_Oldfirst, _Oldlast, _Newvec, _Getal()); + _Uninitialized_copy(_Oldfirst, _Oldlast, _Newvec, _Al); } } else { // provide basic guarantee - _Uninitialized_move(_Oldfirst, _Whereptr, _Newvec, _Getal()); + _Uninitialized_move(_Oldfirst, _Whereptr, _Newvec, _Al); _Constructed_first = _Newvec; - _Uninitialized_move(_Whereptr, _Oldlast, _Newvec + _Whereoff + _Count, _Getal()); + _Uninitialized_move(_Whereptr, _Oldlast, _Newvec + _Whereoff + _Count, _Al); } _CATCH_ALL - _Destroy_range(_Constructed_first, _Constructed_last, _Getal()); - _Getal().deallocate(_Newvec, _Newcapacity); + _Destroy_range(_Constructed_first, _Constructed_last, _Al); + _Al.deallocate(_Newvec, _Newcapacity); _RERAISE; _CATCH_END @@ -912,17 +914,17 @@ public: } else if (_One_at_back) { // provide strong guarantee _Emplace_back_with_unused_capacity(_Val); } else { // provide basic guarantee - const _Alloc_temporary<_Alty> _Tmp_storage(_Getal(), _Val); // handle aliasing + const _Alloc_temporary<_Alty> _Tmp_storage(_Al, _Val); // handle aliasing const auto& _Tmp = _Tmp_storage._Storage._Value; const auto _Affected_elements = static_cast(_Oldlast - _Whereptr); _Orphan_range(_Whereptr, _Oldlast); if (_Count > _Affected_elements) { // new stuff spills off end - _Mylast = _Uninitialized_fill_n(_Oldlast, _Count - _Affected_elements, _Tmp, _Getal()); - _Mylast = _Uninitialized_move(_Whereptr, _Oldlast, _Mylast, _Getal()); + _Mylast = _Uninitialized_fill_n(_Oldlast, _Count - _Affected_elements, _Tmp, _Al); + _Mylast = _Uninitialized_move(_Whereptr, _Oldlast, _Mylast, _Al); _STD fill(_Whereptr, _Oldlast, _Tmp); } else { // new stuff can all be assigned - _Mylast = _Uninitialized_move(_Oldlast - _Count, _Oldlast, _Oldlast, _Getal()); + _Mylast = _Uninitialized_move(_Oldlast - _Count, _Oldlast, _Oldlast, _Al); _Move_backward_unchecked(_Whereptr, _Oldlast - _Count, _Oldlast); _STD fill(_Whereptr, _Whereptr + _Count, _Tmp); } @@ -964,6 +966,7 @@ private: const pointer _Whereptr = _Where._Ptr; const auto _Count = _Convert_size(static_cast(_STD distance(_First, _Last))); + auto& _Al = _Getal(); auto& _My_data = _Mypair._Myval2; pointer& _Mylast = _My_data._Mylast; @@ -982,29 +985,29 @@ private: const size_type _Newsize = _Oldsize + _Count; const size_type _Newcapacity = _Calculate_growth(_Newsize); - const pointer _Newvec = _Getal().allocate(_Newcapacity); + const pointer _Newvec = _Al.allocate(_Newcapacity); const auto _Whereoff = static_cast(_Whereptr - _Oldfirst); const pointer _Constructed_last = _Newvec + _Whereoff + _Count; pointer _Constructed_first = _Constructed_last; _TRY_BEGIN - _Uninitialized_copy(_First, _Last, _Newvec + _Whereoff, _Getal()); + _Uninitialized_copy(_First, _Last, _Newvec + _Whereoff, _Al); _Constructed_first = _Newvec + _Whereoff; if (_Count == 1 && _Whereptr == _Oldlast) { // one at back, provide strong guarantee if constexpr (is_nothrow_move_constructible_v<_Ty> || !is_copy_constructible_v<_Ty>) { - _Uninitialized_move(_Oldfirst, _Oldlast, _Newvec, _Getal()); + _Uninitialized_move(_Oldfirst, _Oldlast, _Newvec, _Al); } else { - _Uninitialized_copy(_Oldfirst, _Oldlast, _Newvec, _Getal()); + _Uninitialized_copy(_Oldfirst, _Oldlast, _Newvec, _Al); } } else { // provide basic guarantee - _Uninitialized_move(_Oldfirst, _Whereptr, _Newvec, _Getal()); + _Uninitialized_move(_Oldfirst, _Whereptr, _Newvec, _Al); _Constructed_first = _Newvec; - _Uninitialized_move(_Whereptr, _Oldlast, _Newvec + _Whereoff + _Count, _Getal()); + _Uninitialized_move(_Whereptr, _Oldlast, _Newvec + _Whereoff + _Count, _Al); } _CATCH_ALL - _Destroy_range(_Constructed_first, _Constructed_last, _Getal()); - _Getal().deallocate(_Newvec, _Newcapacity); + _Destroy_range(_Constructed_first, _Constructed_last, _Al); + _Al.deallocate(_Newvec, _Newcapacity); _RERAISE; _CATCH_END @@ -1016,51 +1019,51 @@ private: const auto _Affected_elements = static_cast(_Oldlast - _Whereptr); if (_Count < _Affected_elements) { // some affected elements must be assigned - _Mylast = _Uninitialized_move(_Oldlast - _Count, _Oldlast, _Oldlast, _Getal()); + _Mylast = _Uninitialized_move(_Oldlast - _Count, _Oldlast, _Oldlast, _Al); _Move_backward_unchecked(_Whereptr, _Oldlast - _Count, _Oldlast); - _Destroy_range(_Whereptr, _Whereptr + _Count, _Getal()); + _Destroy_range(_Whereptr, _Whereptr + _Count, _Al); _TRY_BEGIN - _Uninitialized_copy(_First, _Last, _Whereptr, _Getal()); + _Uninitialized_copy(_First, _Last, _Whereptr, _Al); _CATCH_ALL // glue the broken pieces back together _TRY_BEGIN - _Uninitialized_move(_Whereptr + _Count, _Whereptr + 2 * _Count, _Whereptr, _Getal()); + _Uninitialized_move(_Whereptr + _Count, _Whereptr + 2 * _Count, _Whereptr, _Al); _CATCH_ALL // vaporize the detached piece _Orphan_range(_Whereptr, _Oldlast); - _Destroy_range(_Whereptr + _Count, _Mylast, _Getal()); + _Destroy_range(_Whereptr + _Count, _Mylast, _Al); _Mylast = _Whereptr; _RERAISE; _CATCH_END _Move_unchecked(_Whereptr + 2 * _Count, _Mylast, _Whereptr + _Count); - _Destroy_range(_Oldlast, _Mylast, _Getal()); + _Destroy_range(_Oldlast, _Mylast, _Al); _Mylast = _Oldlast; _RERAISE; _CATCH_END } else { // affected elements don't overlap before/after const pointer _Relocated = _Whereptr + _Count; - _Mylast = _Uninitialized_move(_Whereptr, _Oldlast, _Relocated, _Getal()); - _Destroy_range(_Whereptr, _Oldlast, _Getal()); + _Mylast = _Uninitialized_move(_Whereptr, _Oldlast, _Relocated, _Al); + _Destroy_range(_Whereptr, _Oldlast, _Al); _TRY_BEGIN - _Uninitialized_copy(_First, _Last, _Whereptr, _Getal()); + _Uninitialized_copy(_First, _Last, _Whereptr, _Al); _CATCH_ALL // glue the broken pieces back together _TRY_BEGIN - _Uninitialized_move(_Relocated, _Mylast, _Whereptr, _Getal()); + _Uninitialized_move(_Relocated, _Mylast, _Whereptr, _Al); _CATCH_ALL // vaporize the detached piece _Orphan_range(_Whereptr, _Oldlast); - _Destroy_range(_Relocated, _Mylast, _Getal()); + _Destroy_range(_Relocated, _Mylast, _Al); _Mylast = _Whereptr; _RERAISE; _CATCH_END - _Destroy_range(_Relocated, _Mylast, _Getal()); + _Destroy_range(_Relocated, _Mylast, _Al); _Mylast = _Oldlast; _RERAISE; _CATCH_END @@ -1094,6 +1097,7 @@ public: _CONSTEXPR20_CONTAINER void assign(_CRT_GUARDOVERFLOW const size_type _Newsize, const _Ty& _Val) { // assign _Newsize * _Val + auto& _Al = _Getal(); auto& _My_data = _Mypair._Myval2; pointer& _Myfirst = _My_data._Myfirst; pointer& _Mylast = _My_data._Mylast; @@ -1110,11 +1114,11 @@ public: _STD fill(_Myfirst, _Mylast, _Val); } - _Mylast = _Uninitialized_fill_n(_Mylast, _Newsize - _Oldsize, _Val, _Getal()); + _Mylast = _Uninitialized_fill_n(_Mylast, _Newsize - _Oldsize, _Val, _Al); } else { const pointer _Newlast = _Myfirst + _Newsize; _STD fill(_Myfirst, _Newlast, _Val); - _Destroy_range(_Newlast, _Mylast, _Getal()); + _Destroy_range(_Newlast, _Mylast, _Al); _Mylast = _Newlast; } } @@ -1154,6 +1158,7 @@ private: _CONSTEXPR20_CONTAINER void _Assign_range(_Iter _First, _Iter _Last, forward_iterator_tag) { // assign forward range [_First, _Last) const auto _Newsize = _Convert_size(static_cast(_STD distance(_First, _Last))); + auto& _Al = _Getal(); auto& _My_data = _Mypair._Myval2; pointer& _Myfirst = _My_data._Myfirst; pointer& _Mylast = _My_data._Mylast; @@ -1189,11 +1194,11 @@ private: // performance note: traversing [_First, _Mid) twice const _Iter _Mid = _STD next(_First, static_cast(_Oldsize)); _Copy_unchecked(_First, _Mid, _Myfirst); - _Mylast = _Uninitialized_copy(_Mid, _Last, _Mylast, _Getal()); + _Mylast = _Uninitialized_copy(_Mid, _Last, _Mylast, _Al); } else { const pointer _Newlast = _Myfirst + _Newsize; _Copy_unchecked(_First, _Last, _Myfirst); - _Destroy_range(_Newlast, _Mylast, _Getal()); + _Destroy_range(_Newlast, _Mylast, _Al); _Mylast = _Newlast; } } @@ -1247,6 +1252,7 @@ private: _Xlength(); } + auto& _Al = _Getal(); auto& _My_data = _Mypair._Myval2; pointer& _Myfirst = _My_data._Myfirst; pointer& _Mylast = _My_data._Mylast; @@ -1254,24 +1260,24 @@ private: const auto _Oldsize = static_cast(_Mylast - _Myfirst); const size_type _Newcapacity = _Calculate_growth(_Newsize); - const pointer _Newvec = _Getal().allocate(_Newcapacity); + const pointer _Newvec = _Al.allocate(_Newcapacity); const pointer _Appended_first = _Newvec + _Oldsize; pointer _Appended_last = _Appended_first; _TRY_BEGIN if constexpr (is_same_v<_Ty2, _Ty>) { - _Appended_last = _Uninitialized_fill_n(_Appended_first, _Newsize - _Oldsize, _Val, _Getal()); + _Appended_last = _Uninitialized_fill_n(_Appended_first, _Newsize - _Oldsize, _Val, _Al); } else { - _Appended_last = _Uninitialized_value_construct_n(_Appended_first, _Newsize - _Oldsize, _Getal()); + _Appended_last = _Uninitialized_value_construct_n(_Appended_first, _Newsize - _Oldsize, _Al); } if constexpr (is_nothrow_move_constructible_v<_Ty> || !is_copy_constructible_v<_Ty>) { - _Uninitialized_move(_Myfirst, _Mylast, _Newvec, _Getal()); + _Uninitialized_move(_Myfirst, _Mylast, _Newvec, _Al); } else { - _Uninitialized_copy(_Myfirst, _Mylast, _Newvec, _Getal()); + _Uninitialized_copy(_Myfirst, _Mylast, _Newvec, _Al); } _CATCH_ALL - _Destroy_range(_Appended_first, _Appended_last, _Getal()); - _Getal().deallocate(_Newvec, _Newcapacity); + _Destroy_range(_Appended_first, _Appended_last, _Al); + _Al.deallocate(_Newvec, _Newcapacity); _RERAISE; _CATCH_END @@ -1281,6 +1287,7 @@ private: template _CONSTEXPR20_CONTAINER void _Resize(const size_type _Newsize, const _Ty2& _Val) { // trim or append elements, provide strong guarantee + auto& _Al = _Getal(); auto& _My_data = _Mypair._Myval2; pointer& _Myfirst = _My_data._Myfirst; pointer& _Mylast = _My_data._Mylast; @@ -1288,7 +1295,7 @@ private: if (_Newsize < _Oldsize) { // trim const pointer _Newlast = _Myfirst + _Newsize; _Orphan_range(_Newlast, _Mylast); - _Destroy_range(_Newlast, _Mylast, _Getal()); + _Destroy_range(_Newlast, _Mylast, _Al); _Mylast = _Newlast; return; } @@ -1302,9 +1309,9 @@ private: const pointer _Oldlast = _Mylast; if constexpr (is_same_v<_Ty2, _Ty>) { - _Mylast = _Uninitialized_fill_n(_Oldlast, _Newsize - _Oldsize, _Val, _Getal()); + _Mylast = _Uninitialized_fill_n(_Oldlast, _Newsize - _Oldsize, _Val, _Al); } else { - _Mylast = _Uninitialized_value_construct_n(_Oldlast, _Newsize - _Oldsize, _Getal()); + _Mylast = _Uninitialized_value_construct_n(_Oldlast, _Newsize - _Oldsize, _Al); } _Orphan_range(_Oldlast, _Oldlast); } @@ -1326,22 +1333,23 @@ public: private: _CONSTEXPR20_CONTAINER void _Reallocate_exactly(const size_type _Newcapacity) { // set capacity to _Newcapacity (without geometric growth), provide strong guarantee + auto& _Al = _Getal(); auto& _My_data = _Mypair._Myval2; pointer& _Myfirst = _My_data._Myfirst; pointer& _Mylast = _My_data._Mylast; const auto _Size = static_cast(_Mylast - _Myfirst); - const pointer _Newvec = _Getal().allocate(_Newcapacity); + const pointer _Newvec = _Al.allocate(_Newcapacity); _TRY_BEGIN if constexpr (is_nothrow_move_constructible_v<_Ty> || !is_copy_constructible_v<_Ty>) { - _Uninitialized_move(_Myfirst, _Mylast, _Newvec, _Getal()); + _Uninitialized_move(_Myfirst, _Mylast, _Newvec, _Al); } else { - _Uninitialized_copy(_Myfirst, _Mylast, _Newvec, _Getal()); + _Uninitialized_copy(_Myfirst, _Mylast, _Newvec, _Al); } _CATCH_ALL - _Getal().deallocate(_Newvec, _Newcapacity); + _Al.deallocate(_Newvec, _Newcapacity); _RERAISE; _CATCH_END @@ -1369,6 +1377,7 @@ private: #endif // _ITERATOR_DEBUG_LEVEL != 0 && defined(_ENABLE_STL_INTERNAL_CHECK) _CONSTEXPR20_CONTAINER void _Clear_and_reserve_geometric(const size_type _Newsize) { + auto& _Al = _Getal(); auto& _My_data = _Mypair._Myval2; pointer& _Myfirst = _My_data._Myfirst; pointer& _Mylast = _My_data._Mylast; @@ -1386,8 +1395,8 @@ private: const size_type _Newcapacity = _Calculate_growth(_Newsize); if (_Myfirst) { // destroy and deallocate old array - _Destroy_range(_Myfirst, _Mylast, _Getal()); - _Getal().deallocate(_Myfirst, static_cast(_Myend - _Myfirst)); + _Destroy_range(_Myfirst, _Mylast, _Al); + _Al.deallocate(_Myfirst, static_cast(_Myend - _Myfirst)); _Myfirst = nullptr; _Mylast = nullptr; @@ -1725,6 +1734,7 @@ private: _CONSTEXPR20_CONTAINER void _Change_array( const pointer _Newvec, const size_type _Newsize, const size_type _Newcapacity) { // orphan all iterators, discard old array, acquire new array + auto& _Al = _Getal(); auto& _My_data = _Mypair._Myval2; pointer& _Myfirst = _My_data._Myfirst; pointer& _Mylast = _My_data._Mylast; @@ -1733,8 +1743,8 @@ private: _My_data._Orphan_all(); if (_Myfirst) { // destroy and deallocate old array - _Destroy_range(_Myfirst, _Mylast, _Getal()); - _Getal().deallocate(_Myfirst, static_cast(_Myend - _Myfirst)); + _Destroy_range(_Myfirst, _Mylast, _Al); + _Al.deallocate(_Myfirst, static_cast(_Myend - _Myfirst)); } _Myfirst = _Newvec; @@ -1743,6 +1753,7 @@ private: } _CONSTEXPR20_CONTAINER void _Tidy() noexcept { // free all storage + auto& _Al = _Getal(); auto& _My_data = _Mypair._Myval2; pointer& _Myfirst = _My_data._Myfirst; pointer& _Mylast = _My_data._Mylast; @@ -1751,8 +1762,8 @@ private: _My_data._Orphan_all(); if (_Myfirst) { // destroy and deallocate old array - _Destroy_range(_Myfirst, _Mylast, _Getal()); - _Getal().deallocate(_Myfirst, static_cast(_Myend - _Myfirst)); + _Destroy_range(_Myfirst, _Mylast, _Al); + _Al.deallocate(_Myfirst, static_cast(_Myend - _Myfirst)); _Myfirst = nullptr; _Mylast = nullptr; From 7cb8c2e35d8c0a8169a531cc81c0f029ee56c907 Mon Sep 17 00:00:00 2001 From: Michael Schellenberger Costa Date: Tue, 23 Mar 2021 11:02:45 +0100 Subject: [PATCH 07/13] Cleanup construction of vector with known size --- stl/inc/vector | 135 +++++++++++++++++++------------------------------ 1 file changed, 51 insertions(+), 84 deletions(-) diff --git a/stl/inc/vector b/stl/inc/vector index 66cd02491d4..e1003c8b057 100644 --- a/stl/inc/vector +++ b/stl/inc/vector @@ -481,114 +481,56 @@ public: _Mypair._Myval2._Alloc_proxy(_GET_PROXY_ALLOCATOR(_Alty, _Getal())); } -private: - template - _CONSTEXPR20_CONTAINER void _Construct_n_copies_of_ty(_CRT_GUARDOVERFLOW const size_type _Count, const _Ty2& _Val) { - auto&& _Alproxy = _GET_PROXY_ALLOCATOR(_Alty, _Getal()); - auto& _Al = _Getal(); - auto& _My_data = _Mypair._Myval2; - _Container_proxy_ptr<_Alty> _Proxy(_Alproxy, _My_data); - if (_Count != 0) { - _Buy_nonzero(_Count); - _Tidy_guard _Guard{this}; - if constexpr (is_same_v<_Ty2, _Ty>) { - _My_data._Mylast = _Uninitialized_fill_n(_My_data._Myfirst, _Count, _Val, _Al); - } else { - _My_data._Mylast = _Uninitialized_value_construct_n(_My_data._Myfirst, _Count, _Al); - } - _Guard._Target = nullptr; - } - - _Proxy._Release(); - } - -public: _CONSTEXPR20_CONTAINER explicit vector(_CRT_GUARDOVERFLOW const size_type _Count, const _Alloc& _Al = _Alloc()) : _Mypair(_One_then_variadic_args_t{}, _Al) { - _Construct_n_copies_of_ty(_Count, _Value_init_tag{}); + _Construct_n(_Count); } _CONSTEXPR20_CONTAINER vector( _CRT_GUARDOVERFLOW const size_type _Count, const _Ty& _Val, const _Alloc& _Al = _Alloc()) : _Mypair(_One_then_variadic_args_t{}, _Al) { - _Construct_n_copies_of_ty(_Count, _Val); - } - -private: - template - _CONSTEXPR20_CONTAINER void _Range_construct_or_tidy(_Iter _First, _Iter _Last, input_iterator_tag) { - _Tidy_guard _Guard{this}; - for (; _First != _Last; ++_First) { - emplace_back(*_First); // performance note: emplace_back()'s strong guarantee is unnecessary here - } - - _Guard._Target = nullptr; + _Construct_n(_Count, _Val); } - template - _CONSTEXPR20_CONTAINER void _Range_construct_or_tidy(_Iter _First, _Iter _Last, forward_iterator_tag) { - const auto _Count = _Convert_size(static_cast(_STD distance(_First, _Last))); - if (_Count != 0) { - _Buy_nonzero(_Count); - _Tidy_guard _Guard{this}; - auto& _My_data = _Mypair._Myval2; - _My_data._Mylast = _Uninitialized_copy(_First, _Last, _My_data._Myfirst, _Getal()); - _Guard._Target = nullptr; - } - } - -public: template , int> = 0> _CONSTEXPR20_CONTAINER vector(_Iter _First, _Iter _Last, const _Alloc& _Al = _Alloc()) : _Mypair(_One_then_variadic_args_t{}, _Al) { - auto&& _Alproxy = _GET_PROXY_ALLOCATOR(_Alty, _Getal()); - _Container_proxy_ptr<_Alty> _Proxy(_Alproxy, _Mypair._Myval2); _Adl_verify_range(_First, _Last); - _Range_construct_or_tidy(_Get_unwrapped(_First), _Get_unwrapped(_Last), _Iter_cat_t<_Iter>{}); - _Proxy._Release(); + auto _UFirst = _Get_unwrapped(_First); + auto _ULast = _Get_unwrapped(_Last); + if constexpr (is_same_v<_Iter_cat_t<_Iter>, input_iterator_tag>) { + auto&& _Alproxy = _GET_PROXY_ALLOCATOR(_Alty, _Getal()); + _Container_proxy_ptr<_Alty> _Proxy(_Alproxy, _Mypair._Myval2); + _Tidy_guard _Guard{this}; + + for (; _UFirst != _ULast; ++_UFirst) { + emplace_back(*_UFirst); // performance note: emplace_back()'s strong guarantee is unnecessary here + } + + _Guard._Target = nullptr; + _Proxy._Release(); + } else { + const auto _Count = _Convert_size(static_cast(_STD distance(_UFirst, _ULast))); + _Construct_n(_Count, _STD move(_UFirst), _STD move(_ULast)); + } } _CONSTEXPR20_CONTAINER vector(initializer_list<_Ty> _Ilist, const _Alloc& _Al = _Alloc()) : _Mypair(_One_then_variadic_args_t{}, _Al) { - auto&& _Alproxy = _GET_PROXY_ALLOCATOR(_Alty, _Getal()); - _Container_proxy_ptr<_Alty> _Proxy(_Alproxy, _Mypair._Myval2); - _Range_construct_or_tidy(_Ilist.begin(), _Ilist.end(), random_access_iterator_tag{}); - _Proxy._Release(); + _Construct_n(static_cast(_Ilist.size()), _Ilist.begin(), _Ilist.end()); } _CONSTEXPR20_CONTAINER vector(const vector& _Right) : _Mypair(_One_then_variadic_args_t{}, _Alty_traits::select_on_container_copy_construction(_Right._Getal())) { - auto&& _Alproxy = _GET_PROXY_ALLOCATOR(_Alty, _Getal()); - auto& _My_data = _Mypair._Myval2; - const auto& _Right_data = _Right._Mypair._Myval2; - const pointer _Rightfirst = _Right_data._Myfirst; - const pointer _Rightlast = _Right_data._Mylast; - _Container_proxy_ptr<_Alty> _Proxy(_Alproxy, _My_data); - if (_Rightfirst != _Rightlast) { - _Buy_raw(static_cast(_Rightlast - _Rightfirst)); - _Tidy_guard _Guard{this}; - _My_data._Mylast = _Uninitialized_copy(_Rightfirst, _Rightlast, _My_data._Myfirst, _Getal()); - _Guard._Target = nullptr; - } - - _Proxy._Release(); + const auto& _Right_data = _Right._Mypair._Myval2; + const auto _Count = static_cast(_Right_data._Mylast - _Right_data._Myfirst); + _Construct_n(_Count, _Right_data._Myfirst, _Right_data._Mylast); } _CONSTEXPR20_CONTAINER vector(const vector& _Right, const _Alloc& _Al) : _Mypair(_One_then_variadic_args_t{}, _Al) { - auto&& _Alproxy = _GET_PROXY_ALLOCATOR(_Alty, _Getal()); - auto& _My_data = _Mypair._Myval2; - const auto& _Right_data = _Right._Mypair._Myval2; - const pointer _Rightfirst = _Right_data._Myfirst; - const pointer _Rightlast = _Right_data._Mylast; - _Container_proxy_ptr<_Alty> _Proxy(_Alproxy, _My_data); - if (_Rightfirst != _Rightlast) { - _Buy_raw(static_cast(_Rightlast - _Rightfirst)); - _Tidy_guard _Guard{this}; - _My_data._Mylast = _Uninitialized_copy(_Rightfirst, _Rightlast, _My_data._Myfirst, _Getal()); - _Guard._Target = nullptr; - } - - _Proxy._Release(); + const auto& _Right_data = _Right._Mypair._Myval2; + const auto _Count = static_cast(_Right_data._Mylast - _Right_data._Myfirst); + _Construct_n(_Count, _Right_data._Myfirst, _Right_data._Mylast); } private: @@ -1771,6 +1713,31 @@ private: } } + template + _CONSTEXPR20_CONTAINER void _Construct_n(_CRT_GUARDOVERFLOW const size_type _Count, _Valty&&... _Val) { + auto& _Al = _Getal(); + auto&& _Alproxy = _GET_PROXY_ALLOCATOR(_Alty, _Al); + auto& _My_data = _Mypair._Myval2; + _Container_proxy_ptr<_Alty> _Proxy(_Alproxy, _My_data); + if (_Count != 0) { + _Buy_nonzero(_Count); + _Tidy_guard _Guard{this}; + if constexpr (sizeof...(_Val) == 0) { + _My_data._Mylast = _Uninitialized_value_construct_n(_My_data._Myfirst, _Count, _Al); + } else if constexpr (sizeof...(_Val) == 1) { + static_assert(is_same_v<_Valty..., const _Ty&>, "Wrong type passed to _Construct_n"); + _My_data._Mylast = _Uninitialized_fill_n(_My_data._Myfirst, _Count, _Val..., _Al); + } else if constexpr (sizeof...(_Val) == 2) { + _My_data._Mylast = _Uninitialized_copy(_STD forward<_Valty>(_Val)..., _My_data._Myfirst, _Al); + } else { + static_assert(_Always_false<_Ty>, "Should be unreachable"); + } + _Guard._Target = nullptr; + } + + _Proxy._Release(); + } + [[noreturn]] static void _Xlength() { _Xlength_error("vector too long"); } From 4e98f2cbac8f53f166a42e3995f354f826380a34 Mon Sep 17 00:00:00 2001 From: Michael Schellenberger Costa Date: Tue, 23 Mar 2021 14:37:16 +0100 Subject: [PATCH 08/13] There was only one use of _Move_construct and the tag dispatch did nothing --- stl/inc/vector | 54 ++++++++++++++++++++------------------------------ 1 file changed, 22 insertions(+), 32 deletions(-) diff --git a/stl/inc/vector b/stl/inc/vector index e1003c8b057..f0fb570860a 100644 --- a/stl/inc/vector +++ b/stl/inc/vector @@ -533,34 +533,6 @@ public: _Construct_n(_Count, _Right_data._Myfirst, _Right_data._Mylast); } -private: - _CONSTEXPR20_CONTAINER void _Move_construct(vector& _Right, true_type) noexcept { - // move from _Right, stealing its contents - _Mypair._Myval2._Take_contents(_Right._Mypair._Myval2); - } - - _CONSTEXPR20_CONTAINER void _Move_construct(vector& _Right, false_type) { - // move from _Right, possibly moving its contents - if constexpr (!_Alty_traits::is_always_equal::value) { - if (_Getal() != _Right._Getal()) { - const auto& _Right_data = _Right._Mypair._Myval2; - const pointer _Rightfirst = _Right_data._Myfirst; - const pointer _Rightlast = _Right_data._Mylast; - if (_Rightfirst != _Rightlast) { - _Buy_raw(static_cast(_Rightlast - _Rightfirst)); - _Tidy_guard _Guard{this}; - auto& _My_data = _Mypair._Myval2; - _My_data._Mylast = _Uninitialized_move(_Rightfirst, _Rightlast, _My_data._Myfirst, _Getal()); - _Guard._Target = nullptr; - } - return; - } - } - - _Move_construct(_Right, true_type{}); - } - -public: _CONSTEXPR20_CONTAINER vector(vector&& _Right) noexcept : _Mypair(_One_then_variadic_args_t{}, _STD move(_Right._Getal()), _STD exchange(_Right._Mypair._Myval2._Myfirst, nullptr), @@ -570,12 +542,30 @@ public: _Mypair._Myval2._Swap_proxy_and_iterators(_Right._Mypair._Myval2); } - _CONSTEXPR20_CONTAINER vector(vector&& _Right, const _Alloc& _Al) noexcept( + _CONSTEXPR20_CONTAINER vector(vector&& _Right, const _Alloc& _Al_) noexcept( _Alty_traits::is_always_equal::value) // strengthened - : _Mypair(_One_then_variadic_args_t{}, _Al) { - auto&& _Alproxy = _GET_PROXY_ALLOCATOR(_Alty, _Getal()); + : _Mypair(_One_then_variadic_args_t{}, _Al_) { + _Alty& _Al = _Getal(); + auto&& _Alproxy = _GET_PROXY_ALLOCATOR(_Alty, _Al); _Container_proxy_ptr<_Alty> _Proxy(_Alproxy, _Mypair._Myval2); - _Move_construct(_Right, typename _Alty_traits::is_always_equal::type{}); + + if constexpr (!_Alty_traits::is_always_equal::value) { + if (_Al != _Right._Getal()) { + const auto& _Right_data = _Right._Mypair._Myval2; + const auto _Count = static_cast(_Right_data._Mylast - _Right_data._Myfirst); + if (_Count != 0) { + _Buy_raw(_Count); + _Tidy_guard _Guard{this}; + auto& _My_data = _Mypair._Myval2; + _My_data._Mylast = + _Uninitialized_move(_Right_data._Myfirst, _Right_data._Mylast, _My_data._Myfirst, _Al); + _Guard._Target = nullptr; + } + return; + } + } + + _Mypair._Myval2._Take_contents(_Right._Mypair._Myval2); _Proxy._Release(); } From 1ac385e451e9c3e92e8b3d19f526fee8f310f04a Mon Sep 17 00:00:00 2001 From: Michael Schellenberger Costa Date: Tue, 23 Mar 2021 19:34:42 +0100 Subject: [PATCH 09/13] Move_assign is only used once and can be simplified a lot --- stl/inc/vector | 130 +++++++++++++++++++++++-------------------------- 1 file changed, 62 insertions(+), 68 deletions(-) diff --git a/stl/inc/vector b/stl/inc/vector index f0fb570860a..418c3c1195b 100644 --- a/stl/inc/vector +++ b/stl/inc/vector @@ -569,79 +569,19 @@ public: _Proxy._Release(); } -private: - _CONSTEXPR20_CONTAINER void _Move_assign(vector& _Right, _Equal_allocators) noexcept { - _Tidy(); - _Pocma(_Getal(), _Right._Getal()); - _Mypair._Myval2._Take_contents(_Right._Mypair._Myval2); - } - - _CONSTEXPR20_CONTAINER void _Move_assign(vector& _Right, _Propagate_allocators) noexcept /* terminates */ { - _Tidy(); -#if _ITERATOR_DEBUG_LEVEL != 0 - if (_Getal() != _Right._Getal()) { - // intentionally slams into noexcept on OOM, TRANSITION, VSO-466800 - _Mypair._Myval2._Reload_proxy( - _GET_PROXY_ALLOCATOR(_Alty, _Getal()), _GET_PROXY_ALLOCATOR(_Alty, _Right._Getal())); + _CONSTEXPR20_CONTAINER vector& operator=(vector&& _Right) noexcept( + !is_same_v<_Choose_pocma<_Alty>, _No_propagate_allocators>) { + if (this == _STD addressof(_Right)) { + return *this; } -#endif - _Pocma(_Getal(), _Right._Getal()); - _Mypair._Myval2._Take_contents(_Right._Mypair._Myval2); - } - - _CONSTEXPR20_CONTAINER void _Move_assign(vector& _Right, _No_propagate_allocators) { if (_Getal() == _Right._Getal()) { - _Move_assign(_Right, _Equal_allocators{}); + _Tidy(); + _Pocma(_Getal(), _Right._Getal()); + _Mypair._Myval2._Take_contents(_Right._Mypair._Myval2); } else { - auto& _Right_data = _Right._Mypair._Myval2; - const pointer _First = _Right_data._Myfirst; - const pointer _Last = _Right_data._Mylast; - const auto _Newsize = static_cast(_Last - _First); - - auto& _My_data = _Mypair._Myval2; - pointer& _Myfirst = _My_data._Myfirst; - pointer& _Mylast = _My_data._Mylast; - - _My_data._Orphan_all(); - - const auto _Oldcapacity = static_cast(_My_data._Myend - _Myfirst); - if constexpr (conjunction_v::_Trivially_copyable>, - _Uses_default_construct<_Alty, _Ty*, _Ty>, _Uses_default_destroy<_Alty, _Ty*>>) { - if (_Newsize > _Oldcapacity) { - _Clear_and_reserve_geometric(_Newsize); - } - - _Mylast = _Refancy(_Copy_memmove(_Unfancy(_First), _Unfancy(_Last), _Unfancy(_Myfirst))); - } else { - auto _Oldsize = static_cast(_Mylast - _Myfirst); - - if (_Newsize > _Oldsize) { - if (_Newsize > _Oldcapacity) { // reallocate - _Clear_and_reserve_geometric(_Newsize); - _Oldsize = 0; - } - - const pointer _Mid = _First + _Oldsize; - _Move_unchecked(_First, _Mid, _Myfirst); - _Mylast = _Uninitialized_move(_Mid, _Last, _Mylast, _Getal()); - } else { - const pointer _Newlast = _Myfirst + _Newsize; - _Move_unchecked(_First, _Last, _Myfirst); - _Destroy_range(_Newlast, _Mylast, _Getal()); - _Mylast = _Newlast; - } - } - } - } - -public: - _CONSTEXPR20_CONTAINER vector& operator=(vector&& _Right) noexcept( - noexcept(_Move_assign(_Right, _Choose_pocma<_Alty>{}))) { - if (this != _STD addressof(_Right)) { - _Move_assign(_Right, _Choose_pocma<_Alty>{}); + _Move_assign_unequal_alloc(_Right); } - return *this; } @@ -1728,6 +1668,60 @@ private: _Proxy._Release(); } + _CONSTEXPR20_CONTAINER void _Move_assign_unequal_alloc(vector& _Right) noexcept( + !is_same_v<_Choose_pocma<_Alty>, _No_propagate_allocators>) { + auto& _Al = _Getal(); + if constexpr (is_same_v<_Choose_pocma<_Alty>, _Propagate_allocators>) { + _Tidy(); +#if _ITERATOR_DEBUG_LEVEL != 0 + // intentionally slams into noexcept on OOM, TRANSITION, VSO-466800 + _Mypair._Myval2._Reload_proxy( + _GET_PROXY_ALLOCATOR(_Alty, _Al), _GET_PROXY_ALLOCATOR(_Alty, _Right._Getal())); +#endif + _Pocma(_Al, _Right._Getal()); + _Mypair._Myval2._Take_contents(_Right._Mypair._Myval2); + } else { + auto& _Right_data = _Right._Mypair._Myval2; + const pointer _First = _Right_data._Myfirst; + const pointer _Last = _Right_data._Mylast; + const auto _Newsize = static_cast(_Last - _First); + + auto& _My_data = _Mypair._Myval2; + pointer& _Myfirst = _My_data._Myfirst; + pointer& _Mylast = _My_data._Mylast; + + _My_data._Orphan_all(); + + const auto _Oldcapacity = static_cast(_My_data._Myend - _Myfirst); + if constexpr (conjunction_v::_Trivially_copyable>, + _Uses_default_construct<_Alty, _Ty*, _Ty>, _Uses_default_destroy<_Alty, _Ty*>>) { + if (_Newsize > _Oldcapacity) { + _Clear_and_reserve_geometric(_Newsize); + } + + _Mylast = _Refancy(_Copy_memmove(_Unfancy(_First), _Unfancy(_Last), _Unfancy(_Myfirst))); + } else { + auto _Oldsize = static_cast(_Mylast - _Myfirst); + + if (_Newsize > _Oldsize) { + if (_Newsize > _Oldcapacity) { // reallocate + _Clear_and_reserve_geometric(_Newsize); + _Oldsize = 0; + } + + const pointer _Mid = _First + _Oldsize; + _Move_unchecked(_First, _Mid, _Myfirst); + _Mylast = _Uninitialized_move(_Mid, _Last, _Mylast, _Al); + } else { + const pointer _Newlast = _Myfirst + _Newsize; + _Move_unchecked(_First, _Last, _Myfirst); + _Destroy_range(_Newlast, _Mylast, _Al); + _Mylast = _Newlast; + } + } + } + } + [[noreturn]] static void _Xlength() { _Xlength_error("vector too long"); } From c1204f82c071ba84d2b5f4fe9dcaab69dc18bdc1 Mon Sep 17 00:00:00 2001 From: Michael Schellenberger Costa Date: Wed, 24 Mar 2021 07:46:18 +0100 Subject: [PATCH 10/13] Fix improper tag dispatch --- stl/inc/vector | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stl/inc/vector b/stl/inc/vector index 418c3c1195b..069f43434ad 100644 --- a/stl/inc/vector +++ b/stl/inc/vector @@ -579,7 +579,7 @@ public: _Tidy(); _Pocma(_Getal(), _Right._Getal()); _Mypair._Myval2._Take_contents(_Right._Mypair._Myval2); - } else { + } else if constexpr (!is_same_v<_Choose_pocma<_Alty>, _Equal_allocators>) { _Move_assign_unequal_alloc(_Right); } return *this; From 8f2e82abf17620d16718dd0b5b06aea444121d0f Mon Sep 17 00:00:00 2001 From: Michael Schellenberger Costa Date: Wed, 24 Mar 2021 10:54:04 +0100 Subject: [PATCH 11/13] Fix missing release of guard --- stl/inc/vector | 1 + 1 file changed, 1 insertion(+) diff --git a/stl/inc/vector b/stl/inc/vector index 069f43434ad..f99fa446639 100644 --- a/stl/inc/vector +++ b/stl/inc/vector @@ -561,6 +561,7 @@ public: _Uninitialized_move(_Right_data._Myfirst, _Right_data._Mylast, _My_data._Myfirst, _Al); _Guard._Target = nullptr; } + _Proxy._Release(); return; } } From 536e33ae8557a7f3b9cbb3f09687f0d4dde9a01f Mon Sep 17 00:00:00 2001 From: Michael Schellenberger Costa Date: Mon, 3 May 2021 16:24:29 +0200 Subject: [PATCH 12/13] address review comments --- stl/inc/vector | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/stl/inc/vector b/stl/inc/vector index fabe84126d9..56786f42d18 100644 --- a/stl/inc/vector +++ b/stl/inc/vector @@ -498,7 +498,10 @@ public: _Adl_verify_range(_First, _Last); auto _UFirst = _Get_unwrapped(_First); auto _ULast = _Get_unwrapped(_Last); - if constexpr (is_same_v<_Iter_cat_t<_Iter>, input_iterator_tag>) { + if constexpr (_Is_fwd_iter_v<_Iter>) { + const auto _Count = _Convert_size(static_cast(_STD distance(_UFirst, _ULast))); + _Construct_n(_Count, _STD move(_UFirst), _STD move(_ULast)); + } else { auto&& _Alproxy = _GET_PROXY_ALLOCATOR(_Alty, _Getal()); _Container_proxy_ptr<_Alty> _Proxy(_Alproxy, _Mypair._Myval2); _Tidy_guard _Guard{this}; @@ -509,9 +512,6 @@ public: _Guard._Target = nullptr; _Proxy._Release(); - } else { - const auto _Count = _Convert_size(static_cast(_STD distance(_UFirst, _ULast))); - _Construct_n(_Count, _STD move(_UFirst), _STD move(_ULast)); } } @@ -669,17 +669,17 @@ public: if (_Whereptr == _Mylast) { // at back, provide strong guarantee if constexpr (is_nothrow_move_constructible_v<_Ty> || !is_copy_constructible_v<_Ty>) { - _Uninitialized_move(_Myfirst, _Mylast, _Newvec, _Getal()); + _Uninitialized_move(_Myfirst, _Mylast, _Newvec, _Al); } else { - _Uninitialized_copy(_Myfirst, _Mylast, _Newvec, _Getal()); + _Uninitialized_copy(_Myfirst, _Mylast, _Newvec, _Al); } } else { // provide basic guarantee - _Uninitialized_move(_Myfirst, _Whereptr, _Newvec, _Getal()); + _Uninitialized_move(_Myfirst, _Whereptr, _Newvec, _Al); _Constructed_first = _Newvec; - _Uninitialized_move(_Whereptr, _Mylast, _Newvec + _Whereoff + 1, _Getal()); + _Uninitialized_move(_Whereptr, _Mylast, _Newvec + _Whereoff + 1, _Al); } _CATCH_ALL - _Destroy_range(_Constructed_first, _Constructed_last, _Getal()); + _Destroy_range(_Constructed_first, _Constructed_last, _Al); _Al.deallocate(_Newvec, _Newcapacity); _RERAISE; _CATCH_END @@ -1646,6 +1646,10 @@ private: template _CONSTEXPR20_CONTAINER void _Construct_n(_CRT_GUARDOVERFLOW const size_type _Count, _Valty&&... _Val) { + // Dispatches between the three sized constructions. + // 1-arg -> value-construction, e.g vector(5) + // 2-arg -> fill, e.g. vector(5, "meow") + // 3-arg -> sized range construction e.g. vector{"Hello", "Fluffy", "World"} auto& _Al = _Getal(); auto&& _Alproxy = _GET_PROXY_ALLOCATOR(_Alty, _Al); auto& _My_data = _Mypair._Myval2; From 9751f9d4511037520e96fa42b1867385a6be17a4 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Tue, 15 Jun 2021 20:37:50 -0700 Subject: [PATCH 13/13] Code review feedback. --- stl/inc/vector | 38 ++++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/stl/inc/vector b/stl/inc/vector index 4a31a77d3b9..4ec774e6f75 100644 --- a/stl/inc/vector +++ b/stl/inc/vector @@ -517,7 +517,7 @@ public: _CONSTEXPR20_CONTAINER vector(initializer_list<_Ty> _Ilist, const _Alloc& _Al = _Alloc()) : _Mypair(_One_then_variadic_args_t{}, _Al) { - _Construct_n(static_cast(_Ilist.size()), _Ilist.begin(), _Ilist.end()); + _Construct_n(_Convert_size(_Ilist.size()), _Ilist.begin(), _Ilist.end()); } _CONSTEXPR20_CONTAINER vector(const vector& _Right) @@ -545,18 +545,18 @@ public: _CONSTEXPR20_CONTAINER vector(vector&& _Right, const _Alloc& _Al_) noexcept( _Alty_traits::is_always_equal::value) // strengthened : _Mypair(_One_then_variadic_args_t{}, _Al_) { - _Alty& _Al = _Getal(); - auto&& _Alproxy = _GET_PROXY_ALLOCATOR(_Alty, _Al); - _Container_proxy_ptr<_Alty> _Proxy(_Alproxy, _Mypair._Myval2); + _Alty& _Al = _Getal(); + auto&& _Alproxy = _GET_PROXY_ALLOCATOR(_Alty, _Al); + auto& _My_data = _Mypair._Myval2; + auto& _Right_data = _Right._Mypair._Myval2; + _Container_proxy_ptr<_Alty> _Proxy(_Alproxy, _My_data); if constexpr (!_Alty_traits::is_always_equal::value) { if (_Al != _Right._Getal()) { - const auto& _Right_data = _Right._Mypair._Myval2; - const auto _Count = static_cast(_Right_data._Mylast - _Right_data._Myfirst); + const auto _Count = static_cast(_Right_data._Mylast - _Right_data._Myfirst); if (_Count != 0) { _Buy_raw(_Count); _Tidy_guard _Guard{this}; - auto& _My_data = _Mypair._Myval2; _My_data._Mylast = _Uninitialized_move(_Right_data._Myfirst, _Right_data._Mylast, _My_data._Myfirst, _Al); _Guard._Target = nullptr; @@ -566,7 +566,7 @@ public: } } - _Mypair._Myval2._Take_contents(_Right._Mypair._Myval2); + _My_data._Take_contents(_Right_data); _Proxy._Release(); } @@ -1141,8 +1141,10 @@ private: if constexpr (is_same_v<_Ty2, _Ty>) { _Appended_last = _Uninitialized_fill_n(_Appended_first, _Newsize - _Oldsize, _Val, _Al); } else { + _STL_INTERNAL_STATIC_ASSERT(is_same_v<_Ty2, _Value_init_tag>); _Appended_last = _Uninitialized_value_construct_n(_Appended_first, _Newsize - _Oldsize, _Al); } + if constexpr (is_nothrow_move_constructible_v<_Ty> || !is_copy_constructible_v<_Ty>) { _Uninitialized_move(_Myfirst, _Mylast, _Newvec, _Al); } else { @@ -1184,6 +1186,7 @@ private: if constexpr (is_same_v<_Ty2, _Ty>) { _Mylast = _Uninitialized_fill_n(_Oldlast, _Newsize - _Oldsize, _Val, _Al); } else { + _STL_INTERNAL_STATIC_ASSERT(is_same_v<_Ty2, _Value_init_tag>); _Mylast = _Uninitialized_value_construct_n(_Oldlast, _Newsize - _Oldsize, _Al); } _Orphan_range(_Oldlast, _Oldlast); @@ -1647,9 +1650,9 @@ private: template _CONSTEXPR20_CONTAINER void _Construct_n(_CRT_GUARDOVERFLOW const size_type _Count, _Valty&&... _Val) { // Dispatches between the three sized constructions. - // 1-arg -> value-construction, e.g vector(5) + // 1-arg -> value-construction, e.g. vector(5) // 2-arg -> fill, e.g. vector(5, "meow") - // 3-arg -> sized range construction e.g. vector{"Hello", "Fluffy", "World"} + // 3-arg -> sized range construction, e.g. vector{"Hello", "Fluffy", "World"} auto& _Al = _Getal(); auto&& _Alproxy = _GET_PROXY_ALLOCATOR(_Alty, _Al); auto& _My_data = _Mypair._Myval2; @@ -1660,7 +1663,7 @@ private: if constexpr (sizeof...(_Val) == 0) { _My_data._Mylast = _Uninitialized_value_construct_n(_My_data._Myfirst, _Count, _Al); } else if constexpr (sizeof...(_Val) == 1) { - static_assert(is_same_v<_Valty..., const _Ty&>, "Wrong type passed to _Construct_n"); + _STL_INTERNAL_STATIC_ASSERT(is_same_v<_Valty..., const _Ty&>); _My_data._Mylast = _Uninitialized_fill_n(_My_data._Myfirst, _Count, _Val..., _Al); } else if constexpr (sizeof...(_Val) == 2) { _My_data._Mylast = _Uninitialized_copy(_STD forward<_Valty>(_Val)..., _My_data._Myfirst, _Al); @@ -1675,23 +1678,22 @@ private: _CONSTEXPR20_CONTAINER void _Move_assign_unequal_alloc(vector& _Right) noexcept( !is_same_v<_Choose_pocma<_Alty>, _No_propagate_allocators>) { - auto& _Al = _Getal(); + auto& _Al = _Getal(); + auto& _My_data = _Mypair._Myval2; + auto& _Right_data = _Right._Mypair._Myval2; if constexpr (is_same_v<_Choose_pocma<_Alty>, _Propagate_allocators>) { _Tidy(); #if _ITERATOR_DEBUG_LEVEL != 0 // intentionally slams into noexcept on OOM, TRANSITION, VSO-466800 - _Mypair._Myval2._Reload_proxy( - _GET_PROXY_ALLOCATOR(_Alty, _Al), _GET_PROXY_ALLOCATOR(_Alty, _Right._Getal())); -#endif + _My_data._Reload_proxy(_GET_PROXY_ALLOCATOR(_Alty, _Al), _GET_PROXY_ALLOCATOR(_Alty, _Right._Getal())); +#endif // _ITERATOR_DEBUG_LEVEL != 0 _Pocma(_Al, _Right._Getal()); - _Mypair._Myval2._Take_contents(_Right._Mypair._Myval2); + _My_data._Take_contents(_Right_data); } else { - auto& _Right_data = _Right._Mypair._Myval2; const pointer _First = _Right_data._Myfirst; const pointer _Last = _Right_data._Mylast; const auto _Newsize = static_cast(_Last - _First); - auto& _My_data = _Mypair._Myval2; pointer& _Myfirst = _My_data._Myfirst; pointer& _Mylast = _My_data._Mylast;