From d5657ff68e21fbb2d12af62252fc6176494bd010 Mon Sep 17 00:00:00 2001 From: Michael Schellenberger Costa Date: Tue, 25 Aug 2020 21:49:51 +0200 Subject: [PATCH 01/10] Strengthen reverse_iterator noexcept --- stl/inc/xutility | 89 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 60 insertions(+), 29 deletions(-) diff --git a/stl/inc/xutility b/stl/inc/xutility index 65d7fa0ea10..231489ffbcf 100644 --- a/stl/inc/xutility +++ b/stl/inc/xutility @@ -1245,24 +1245,28 @@ public: requires (!is_same_v<_Other, _BidIt>) && convertible_to && assignable_from<_BidIt&, const _Other&> #endif // __cpp_lib_concepts - _CONSTEXPR17 reverse_iterator& operator=(const reverse_iterator<_Other>& _Right) { + _CONSTEXPR17 reverse_iterator& operator=(const reverse_iterator<_Other>& _Right) noexcept( + is_nothrow_constructible_v<_BidIt, const _Other&>) /* strengthened */ { current = _Right.current; return *this; } // clang-format on - _NODISCARD _CONSTEXPR17 _BidIt base() const { + _NODISCARD _CONSTEXPR17 _BidIt base() const noexcept(is_nothrow_copy_constructible_v<_BidIt>) /* strengthened */ { return current; } - _NODISCARD _CONSTEXPR17 reference operator*() const { + _NODISCARD _CONSTEXPR17 reference operator*() const noexcept(is_nothrow_copy_constructible_v<_BidIt>&& noexcept( + _Implicitly_convert_to(*--(_STD declval<_BidIt&>())))) /* strengthened */ { _BidIt _Tmp = current; return *--_Tmp; } #ifdef __cpp_lib_concepts // clang-format off - _NODISCARD constexpr pointer operator->() const + _NODISCARD constexpr pointer operator->() const noexcept(is_nothrow_copy_constructible_v<_BidIt> + && noexcept(--(_STD declval<_BidIt&>())) && noexcept(_Implicitly_convert_to( + _Operator_arrow(_STD declval<_BidIt&>(), is_pointer<_BidIt>())))) /* strengthened */ requires (is_pointer_v<_BidIt> || requires(const _BidIt __i) { __i.operator->(); }) { _BidIt _Tmp = current; --_Tmp; @@ -1274,7 +1278,10 @@ public: } // clang-format on #else // ^^^ __cpp_lib_concepts / !__cpp_lib_concepts vvv - _NODISCARD _CONSTEXPR17 pointer operator->() const { + _NODISCARD _CONSTEXPR17 pointer operator->() const + noexcept(is_nothrow_copy_constructible_v<_BidIt>&& noexcept(--(_STD declval<_BidIt&>())) && noexcept( + _Implicitly_convert_to( + _Operator_arrow(_STD declval<_BidIt&>(), is_pointer<_BidIt>())))) /* strengthened */ { _BidIt _Tmp = current; --_Tmp; if constexpr (is_pointer_v<_BidIt>) { @@ -1285,47 +1292,54 @@ public: } #endif // __cpp_lib_concepts - _CONSTEXPR17 reverse_iterator& operator++() { + _CONSTEXPR17 reverse_iterator& operator++() noexcept(noexcept(--current)) /* strengthened */ { --current; return *this; } - _CONSTEXPR17 reverse_iterator operator++(int) { + _CONSTEXPR17 reverse_iterator operator++(int) noexcept( + is_nothrow_copy_constructible_v<_BidIt>&& noexcept(--current)) /* strengthened */ { reverse_iterator _Tmp = *this; --current; return _Tmp; } - _CONSTEXPR17 reverse_iterator& operator--() { + _CONSTEXPR17 reverse_iterator& operator--() noexcept(noexcept(++current)) /* strengthened */ { ++current; return *this; } - _CONSTEXPR17 reverse_iterator operator--(int) { + _CONSTEXPR17 reverse_iterator operator--(int) noexcept( + is_nothrow_copy_constructible_v<_BidIt>&& noexcept(++current)) /* strengthened */ { reverse_iterator _Tmp = *this; ++current; return _Tmp; } - _NODISCARD _CONSTEXPR17 reverse_iterator operator+(const difference_type _Off) const { + _NODISCARD _CONSTEXPR17 reverse_iterator operator+(const difference_type _Off) const + noexcept(is_nothrow_copy_constructible_v<_BidIt>&& noexcept(current - _Off)) /* strengthened */ { return reverse_iterator(current - _Off); } - _CONSTEXPR17 reverse_iterator& operator+=(const difference_type _Off) { + _CONSTEXPR17 reverse_iterator& operator+=(const difference_type _Off) noexcept( + noexcept(current -= _Off)) /* strengthened */ { current -= _Off; return *this; } - _NODISCARD _CONSTEXPR17 reverse_iterator operator-(const difference_type _Off) const { + _NODISCARD _CONSTEXPR17 reverse_iterator operator-(const difference_type _Off) const + noexcept(is_nothrow_copy_constructible_v<_BidIt>&& noexcept(current + _Off)) /* strengthened */ { return reverse_iterator(current + _Off); } - _CONSTEXPR17 reverse_iterator& operator-=(const difference_type _Off) { + _CONSTEXPR17 reverse_iterator& operator-=(const difference_type _Off) noexcept( + noexcept(current += _Off)) /* strengthened */ { current += _Off; return *this; } - _NODISCARD _CONSTEXPR17 reference operator[](const difference_type _Off) const { + _NODISCARD _CONSTEXPR17 reference operator[](const difference_type _Off) const + noexcept(noexcept(current[difference_type{}])) /* strengthened */ { return current[static_cast(-_Off - 1)]; } @@ -1352,25 +1366,27 @@ public: using _Prevent_inheriting_unwrap = reverse_iterator; template , int> = 0> - friend constexpr void _Verify_range(const reverse_iterator& _First, const reverse_iterator<_BidIt2>& _Last) { + friend constexpr void _Verify_range(const reverse_iterator& _First, + const reverse_iterator<_BidIt2>& _Last) noexcept(noexcept(_Verify_range(_Last.base(), _First.base()))) { _Verify_range(_Last._Get_current(), _First.current); // note reversed parameters } template , int> = 0> - constexpr void _Verify_offset(const difference_type _Off) const { + constexpr void _Verify_offset(const difference_type _Off) const noexcept(noexcept(current._Verify_offset(-_Off))) { _STL_VERIFY(_Off != _Min_possible_v, "integer overflow"); current._Verify_offset(-_Off); } template , int> = 0> - _NODISCARD constexpr reverse_iterator<_Unwrapped_t> _Unwrapped() const { + _NODISCARD constexpr reverse_iterator<_Unwrapped_t> _Unwrapped() const + noexcept(noexcept(static_cast>>(current._Unwrapped()))) { return static_cast>>(current._Unwrapped()); } static constexpr bool _Unwrap_when_unverified = _Do_unwrap_when_unverified_v<_BidIt>; template , int> = 0> - constexpr void _Seek_to(const reverse_iterator<_Src>& _It) { + constexpr void _Seek_to(const reverse_iterator<_Src>& _It) noexcept(noexcept(current._Seek_to(_It.base()))) { current._Seek_to(_It.current); } @@ -1383,7 +1399,9 @@ protected: }; template -_NODISCARD _CONSTEXPR17 bool operator==(const reverse_iterator<_BidIt1>& _Left, const reverse_iterator<_BidIt2>& _Right) +_NODISCARD _CONSTEXPR17 bool + operator==(const reverse_iterator<_BidIt1>& _Left, const reverse_iterator<_BidIt2>& _Right) noexcept( + noexcept(_Left._Get_current() == _Right._Get_current())) /* strengthened */ #ifdef __cpp_lib_concepts // clang-format off requires requires { @@ -1394,7 +1412,9 @@ _NODISCARD _CONSTEXPR17 bool operator==(const reverse_iterator<_BidIt1>& _Left, { return _Left._Get_current() == _Right._Get_current(); } template -_NODISCARD _CONSTEXPR17 bool operator!=(const reverse_iterator<_BidIt1>& _Left, const reverse_iterator<_BidIt2>& _Right) +_NODISCARD _CONSTEXPR17 bool + operator!=(const reverse_iterator<_BidIt1>& _Left, const reverse_iterator<_BidIt2>& _Right) noexcept( + noexcept(_Left._Get_current() != _Right._Get_current())) /* strengthened */ #ifdef __cpp_lib_concepts // clang-format off requires requires { @@ -1405,7 +1425,9 @@ _NODISCARD _CONSTEXPR17 bool operator!=(const reverse_iterator<_BidIt1>& _Left, { return _Left._Get_current() != _Right._Get_current(); } template -_NODISCARD _CONSTEXPR17 bool operator<(const reverse_iterator<_BidIt1>& _Left, const reverse_iterator<_BidIt2>& _Right) +_NODISCARD _CONSTEXPR17 bool + operator<(const reverse_iterator<_BidIt1>& _Left, const reverse_iterator<_BidIt2>& _Right) noexcept( + noexcept(_Left._Get_current() > _Right._Get_current())) /* strengthened */ #ifdef __cpp_lib_concepts // clang-format off requires requires { @@ -1416,7 +1438,9 @@ _NODISCARD _CONSTEXPR17 bool operator<(const reverse_iterator<_BidIt1>& _Left, c { return _Left._Get_current() > _Right._Get_current(); } template -_NODISCARD _CONSTEXPR17 bool operator>(const reverse_iterator<_BidIt1>& _Left, const reverse_iterator<_BidIt2>& _Right) +_NODISCARD _CONSTEXPR17 bool + operator>(const reverse_iterator<_BidIt1>& _Left, const reverse_iterator<_BidIt2>& _Right) noexcept( + noexcept(_Left._Get_current() < _Right._Get_current())) /* strengthened */ #ifdef __cpp_lib_concepts // clang-format off requires requires { @@ -1427,7 +1451,9 @@ _NODISCARD _CONSTEXPR17 bool operator>(const reverse_iterator<_BidIt1>& _Left, c { return _Left._Get_current() < _Right._Get_current(); } template -_NODISCARD _CONSTEXPR17 bool operator<=(const reverse_iterator<_BidIt1>& _Left, const reverse_iterator<_BidIt2>& _Right) +_NODISCARD _CONSTEXPR17 bool + operator<=(const reverse_iterator<_BidIt1>& _Left, const reverse_iterator<_BidIt2>& _Right) noexcept( + noexcept(_Left._Get_current() >= _Right._Get_current())) /* strengthened */ #ifdef __cpp_lib_concepts // clang-format off requires requires { @@ -1438,7 +1464,9 @@ _NODISCARD _CONSTEXPR17 bool operator<=(const reverse_iterator<_BidIt1>& _Left, { return _Left._Get_current() >= _Right._Get_current(); } template -_NODISCARD _CONSTEXPR17 bool operator>=(const reverse_iterator<_BidIt1>& _Left, const reverse_iterator<_BidIt2>& _Right) +_NODISCARD _CONSTEXPR17 bool + operator>=(const reverse_iterator<_BidIt1>& _Left, const reverse_iterator<_BidIt2>& _Right) noexcept( + noexcept(_Left._Get_current() <= _Right._Get_current())) /* strengthened */ #ifdef __cpp_lib_concepts // clang-format off requires requires { @@ -1450,21 +1478,24 @@ _NODISCARD _CONSTEXPR17 bool operator>=(const reverse_iterator<_BidIt1>& _Left, #ifdef __cpp_lib_concepts template _BidIt2> -_NODISCARD constexpr compare_three_way_result_t<_BidIt1, _BidIt2> operator<=>( - const reverse_iterator<_BidIt1>& _Left, const reverse_iterator<_BidIt2>& _Right) { +_NODISCARD constexpr compare_three_way_result_t<_BidIt1, _BidIt2> + operator<=>(const reverse_iterator<_BidIt1>& _Left, const reverse_iterator<_BidIt2>& _Right) noexcept( + noexcept(_Right._Get_current() <=> _Left._Get_current())) /* strengthened */ { return _Right._Get_current() <=> _Left._Get_current(); } #endif // __cpp_lib_concepts template -_NODISCARD _CONSTEXPR17 auto operator-(const reverse_iterator<_BidIt1>& _Left, const reverse_iterator<_BidIt2>& _Right) +_NODISCARD _CONSTEXPR17 auto + operator-(const reverse_iterator<_BidIt1>& _Left, const reverse_iterator<_BidIt2>& _Right) noexcept( + noexcept(_Right._Get_current() - _Left._Get_current())) /* strengthened */ -> decltype(_Right._Get_current() - _Left._Get_current()) { return _Right._Get_current() - _Left._Get_current(); } template -_NODISCARD _CONSTEXPR17 reverse_iterator<_BidIt> operator+( - typename reverse_iterator<_BidIt>::difference_type _Off, const reverse_iterator<_BidIt>& _Right) { +_NODISCARD _CONSTEXPR17 reverse_iterator<_BidIt> operator+(typename reverse_iterator<_BidIt>::difference_type _Off, + const reverse_iterator<_BidIt>& _Right) noexcept(noexcept(_Right + _Off)) /* strengthened */ { return _Right + _Off; } From 2701b612c9fd1b1d88f97c491d2ac9a1f82dfb22 Mon Sep 17 00:00:00 2001 From: Michael Schellenberger Costa Date: Wed, 26 Aug 2020 10:39:29 +0200 Subject: [PATCH 02/10] Strengthen noxcept specification for iterator machinery --- stl/inc/xutility | 59 +++++++++++++++++++++++++++++++----------------- 1 file changed, 38 insertions(+), 21 deletions(-) diff --git a/stl/inc/xutility b/stl/inc/xutility index 231489ffbcf..74a87b53ad3 100644 --- a/stl/inc/xutility +++ b/stl/inc/xutility @@ -1514,22 +1514,26 @@ inline constexpr bool disable_sized_sentinel_for, reve #endif // __cpp_lib_concepts template -_NODISCARD _CONSTEXPR17 auto begin(_Container& _Cont) -> decltype(_Cont.begin()) { +_NODISCARD _CONSTEXPR17 auto begin(_Container& _Cont) noexcept(noexcept(_Cont.begin())) /* strengthened */ + -> decltype(_Cont.begin()) { return _Cont.begin(); } template -_NODISCARD _CONSTEXPR17 auto begin(const _Container& _Cont) -> decltype(_Cont.begin()) { +_NODISCARD _CONSTEXPR17 auto begin(const _Container& _Cont) noexcept(noexcept(_Cont.begin())) /* strengthened */ + -> decltype(_Cont.begin()) { return _Cont.begin(); } template -_NODISCARD _CONSTEXPR17 auto end(_Container& _Cont) -> decltype(_Cont.end()) { +_NODISCARD _CONSTEXPR17 auto end(_Container& _Cont) noexcept(noexcept(_Cont.end())) /* strengthened */ + -> decltype(_Cont.end()) { return _Cont.end(); } template -_NODISCARD _CONSTEXPR17 auto end(const _Container& _Cont) -> decltype(_Cont.end()) { +_NODISCARD _CONSTEXPR17 auto end(const _Container& _Cont) noexcept(noexcept(_Cont.end())) /* strengthened */ + -> decltype(_Cont.end()) { return _Cont.end(); } @@ -1544,69 +1548,78 @@ _NODISCARD constexpr _Ty* end(_Ty (&_Array)[_Size]) noexcept { } template -_NODISCARD constexpr auto cbegin(const _Container& _Cont) noexcept(noexcept(_STD begin(_Cont))) +_NODISCARD constexpr auto cbegin(const _Container& _Cont) noexcept(noexcept(_STD begin(_Cont))) /* strengthened */ -> decltype(_STD begin(_Cont)) { return _STD begin(_Cont); } template -_NODISCARD constexpr auto cend(const _Container& _Cont) noexcept(noexcept(_STD end(_Cont))) +_NODISCARD constexpr auto cend(const _Container& _Cont) noexcept(noexcept(_STD end(_Cont))) /* strengthened */ -> decltype(_STD end(_Cont)) { return _STD end(_Cont); } template -_NODISCARD _CONSTEXPR17 auto rbegin(_Container& _Cont) -> decltype(_Cont.rbegin()) { +_NODISCARD _CONSTEXPR17 auto rbegin(_Container& _Cont) noexcept(noexcept(_Cont.rbegin())) /* strengthened */ + -> decltype(_Cont.rbegin()) { return _Cont.rbegin(); } template -_NODISCARD _CONSTEXPR17 auto rbegin(const _Container& _Cont) -> decltype(_Cont.rbegin()) { +_NODISCARD _CONSTEXPR17 auto rbegin(const _Container& _Cont) noexcept(noexcept(_Cont.rbegin())) /* strengthened */ + -> decltype(_Cont.rbegin()) { return _Cont.rbegin(); } template -_NODISCARD _CONSTEXPR17 auto rend(_Container& _Cont) -> decltype(_Cont.rend()) { +_NODISCARD _CONSTEXPR17 auto rend(_Container& _Cont) noexcept(noexcept(_Cont.rend())) /* strengthened */ + -> decltype(_Cont.rend()) { return _Cont.rend(); } template -_NODISCARD _CONSTEXPR17 auto rend(const _Container& _Cont) -> decltype(_Cont.rend()) { +_NODISCARD _CONSTEXPR17 auto rend(const _Container& _Cont) noexcept(noexcept(_Cont.rend())) /* strengthened */ + -> decltype(_Cont.rend()) { return _Cont.rend(); } template -_NODISCARD _CONSTEXPR17 reverse_iterator<_Ty*> rbegin(_Ty (&_Array)[_Size]) { +_NODISCARD _CONSTEXPR17 reverse_iterator<_Ty*> rbegin(_Ty (&_Array)[_Size]) noexcept /* strengthened */ { return reverse_iterator<_Ty*>(_Array + _Size); } template -_NODISCARD _CONSTEXPR17 reverse_iterator<_Ty*> rend(_Ty (&_Array)[_Size]) { +_NODISCARD _CONSTEXPR17 reverse_iterator<_Ty*> rend(_Ty (&_Array)[_Size]) noexcept /* strengthened */ { return reverse_iterator<_Ty*>(_Array); } template -_NODISCARD _CONSTEXPR17 reverse_iterator rbegin(initializer_list<_Elem> _Ilist) { +_NODISCARD _CONSTEXPR17 reverse_iterator rbegin(initializer_list<_Elem> _Ilist) noexcept +/* strengthened */ { return reverse_iterator(_Ilist.end()); } template -_NODISCARD _CONSTEXPR17 reverse_iterator rend(initializer_list<_Elem> _Ilist) { +_NODISCARD _CONSTEXPR17 reverse_iterator rend(initializer_list<_Elem> _Ilist) noexcept +/* strengthened */ { return reverse_iterator(_Ilist.begin()); } template -_NODISCARD _CONSTEXPR17 auto crbegin(const _Container& _Cont) -> decltype(_STD rbegin(_Cont)) { +_NODISCARD _CONSTEXPR17 auto crbegin(const _Container& _Cont) noexcept(noexcept(rbegin(_Cont))) /* strengthened */ + -> decltype(_STD rbegin(_Cont)) { return _STD rbegin(_Cont); } template -_NODISCARD _CONSTEXPR17 auto crend(const _Container& _Cont) -> decltype(_STD rend(_Cont)) { +_NODISCARD _CONSTEXPR17 auto crend(const _Container& _Cont) noexcept(noexcept(rbegin(_Cont))) /* strengthened */ + -> decltype(_STD rend(_Cont)) { return _STD rend(_Cont); } template -_NODISCARD constexpr auto size(const _Container& _Cont) -> decltype(_Cont.size()) { +_NODISCARD constexpr auto size(const _Container& _Cont) noexcept(noexcept(_Cont.size())) /* strengthened */ + -> decltype(_Cont.size()) { return _Cont.size(); } @@ -1617,7 +1630,8 @@ _NODISCARD constexpr size_t size(const _Ty (&)[_Size]) noexcept { #if _HAS_CXX20 template -_NODISCARD constexpr auto ssize(const _Container& _Cont) +_NODISCARD constexpr auto ssize(const _Container& _Cont) noexcept(noexcept( + static_cast>>(_Cont.size()))) /* strengthened */ -> common_type_t> { using _Common = common_type_t>; return static_cast<_Common>(_Cont.size()); @@ -1630,7 +1644,8 @@ _NODISCARD constexpr ptrdiff_t ssize(const _Ty (&)[_Size]) noexcept { #endif // _HAS_CXX20 template -_NODISCARD constexpr auto empty(const _Container& _Cont) -> decltype(_Cont.empty()) { +_NODISCARD constexpr auto empty(const _Container& _Cont) noexcept(noexcept(_Cont.empty())) /* strengthened */ + -> decltype(_Cont.empty()) { return _Cont.empty(); } @@ -1645,12 +1660,14 @@ _NODISCARD constexpr bool empty(initializer_list<_Elem> _Ilist) noexcept { } template -_NODISCARD constexpr auto data(_Container& _Cont) -> decltype(_Cont.data()) { +_NODISCARD constexpr auto data(_Container& _Cont) noexcept(noexcept(_Cont.data())) /* strengthened */ + -> decltype(_Cont.data()) { return _Cont.data(); } template -_NODISCARD constexpr auto data(const _Container& _Cont) -> decltype(_Cont.data()) { +_NODISCARD constexpr auto data(const _Container& _Cont) noexcept(noexcept(_Cont.data())) /* strengthened */ + -> decltype(_Cont.data()) { return _Cont.data(); } From 6c86db87ed554b963aedc3a04010f8b0cd33e3a7 Mon Sep 17 00:00:00 2001 From: Michael Schellenberger Costa Date: Wed, 26 Aug 2020 11:03:24 +0200 Subject: [PATCH 03/10] Strengthen noexcept specification for move_iterator --- stl/inc/xutility | 133 ++++++++++++++++++++++++++++++----------------- 1 file changed, 86 insertions(+), 47 deletions(-) diff --git a/stl/inc/xutility b/stl/inc/xutility index 74a87b53ad3..69f9519afe2 100644 --- a/stl/inc/xutility +++ b/stl/inc/xutility @@ -3337,29 +3337,38 @@ public: return _STD move(_Current); } #else // ^^^ __cpp_lib_concepts / !__cpp_lib_concepts vvv - _NODISCARD _CONSTEXPR17 iterator_type base() const { + _NODISCARD _CONSTEXPR17 iterator_type base() const + noexcept(is_nothrow_copy_constructible_v<_Iter>) /* strengthened */ { return _Current; } #endif // __cpp_lib_concepts - _NODISCARD _CONSTEXPR17 reference operator*() const { + _NODISCARD _CONSTEXPR17 reference operator*() const #ifdef __cpp_lib_concepts +#ifdef __EDG__ // TRANSITION, VSO-1132105 + noexcept(noexcept(_RANGES iter_move(_STD declval()))) /* strengthened */ { +#else // ^^^ workaround / no workaround vvv + noexcept(noexcept(_RANGES iter_move(_Current))) /* strengthened */ { +#endif // TRANSITION, VSO-1132105 return _RANGES iter_move(_Current); #else // ^^^ __cpp_lib_concepts / !__cpp_lib_concepts vvv + noexcept(noexcept(static_cast(*_Current))) /* strengthened */ { return static_cast(*_Current); #endif // __cpp_lib_concepts } - _CXX20_DEPRECATE_MOVE_ITERATOR_ARROW _NODISCARD _CONSTEXPR17 pointer operator->() const { + _NODISCARD _CXX20_DEPRECATE_MOVE_ITERATOR_ARROW _CONSTEXPR17 pointer operator->() const + noexcept(is_nothrow_copy_constructible_v<_Iter>) /* strengthened */ { return _Current; } - _CONSTEXPR17 move_iterator& operator++() { + _CONSTEXPR17 move_iterator& operator++() noexcept(noexcept(++_Current)) /* strengthened */ { ++_Current; return *this; } - _CONSTEXPR17 auto operator++(int) { + _CONSTEXPR17 auto operator++(int) noexcept( + noexcept(++_Current) && is_nothrow_copy_constructible_v<_Iter>) /* strengthened */ { #ifdef __cpp_lib_concepts if constexpr (forward_iterator<_Iter>) { #endif // __cpp_lib_concepts @@ -3373,12 +3382,13 @@ public: #endif // __cpp_lib_concepts } - _CONSTEXPR17 move_iterator& operator--() { + _CONSTEXPR17 move_iterator& operator--() noexcept(noexcept(--_Current)) /* strengthened */ { --_Current; return *this; } - _CONSTEXPR17 move_iterator operator--(int) { + _CONSTEXPR17 move_iterator operator--(int) noexcept( + noexcept(--_Current) && is_nothrow_copy_constructible_v<_Iter>) /* strengthened */ { move_iterator _Tmp = *this; --_Current; return _Tmp; @@ -3396,47 +3406,58 @@ public: return _Current != _Sentinel; } - _NODISCARD _CONSTEXPR17 move_iterator operator+(const difference_type _Off) const { + _NODISCARD _CONSTEXPR17 move_iterator operator+(const difference_type _Off) const + noexcept(is_nothrow_copy_constructible_v<_Iter>&& noexcept(_Current + _Off)) /* strengthened */ { return move_iterator(_Current + _Off); } - _CONSTEXPR17 move_iterator& operator+=(const difference_type _Off) { + _CONSTEXPR17 move_iterator& operator+=(const difference_type _Off) noexcept( + noexcept(_Current += _Off)) /* strengthened */ { _Current += _Off; return *this; } - _NODISCARD _CONSTEXPR17 move_iterator operator-(const difference_type _Off) const { + _NODISCARD _CONSTEXPR17 move_iterator operator-(const difference_type _Off) const + noexcept(is_nothrow_copy_constructible_v<_Iter>&& noexcept(_Current - _Off)) /* strengthened */ { return move_iterator(_Current - _Off); } - _CONSTEXPR17 move_iterator& operator-=(const difference_type _Off) { + _CONSTEXPR17 move_iterator& operator-=(const difference_type _Off) noexcept( + noexcept(_Current -= _Off)) /* strengthened */ { _Current -= _Off; return *this; } - _NODISCARD _CONSTEXPR17 reference operator[](const difference_type _Off) const { + _NODISCARD _CONSTEXPR17 reference operator[](const difference_type _Off) const #ifdef __cpp_lib_concepts +#ifdef __EDG__ // TRANSITION, VSO-1132105 + noexcept(noexcept(_RANGES iter_move(_STD declval() + difference_type{}))) /* strengthened */ { +#else // ^^^ workaround / no workaround vvv + noexcept(noexcept(_RANGES iter_move(_Current + _Off))) /* strengthened */ { +#endif // TRANSITION, VSO-1132105 return _RANGES iter_move(_Current + _Off); #else // ^^^ __cpp_lib_concepts / !__cpp_lib_concepts vvv + noexcept(noexcept(_STD move(_Current[_Off]))) /* strengthened */ { return _STD move(_Current[_Off]); #endif // __cpp_lib_concepts } #ifdef __cpp_lib_concepts template _Sent> - _NODISCARD_FRIEND constexpr bool operator==(const move_iterator& _Left, const move_sentinel<_Sent>& _Right) { + _NODISCARD_FRIEND constexpr bool operator==(const move_iterator& _Left, const move_sentinel<_Sent>& _Right) + noexcept(_Left._Current == _Right._Get_last())) /* strengthened */ { return _Left._Current == _Right._Get_last(); } template _Sent> - _NODISCARD_FRIEND constexpr difference_type operator-( - const move_sentinel<_Sent>& _Left, const move_iterator& _Right) { + _NODISCARD_FRIEND constexpr difference_type operator-(const move_sentinel<_Sent>& _Left, + const move_iterator& _Right) noexcept(noexcept(_Left._Get_last() - _Right._Current)) /* strengthened */ { return _Left._Get_last() - _Right._Current; } template _Sent> - _NODISCARD_FRIEND constexpr difference_type operator-( - const move_iterator& _Left, const move_sentinel<_Sent>& _Right) { + _NODISCARD_FRIEND constexpr difference_type operator-(const move_iterator& _Left, + const move_sentinel<_Sent>& _Right) noexcept(noexcept(_Left._Current - _Right._Get_last())) /* strengthened */ { return _Left._Current - _Right._Get_last(); } @@ -3463,12 +3484,14 @@ public: #endif // __cpp_lib_concepts template , int> = 0> - friend constexpr void _Verify_range(const move_iterator& _First, const move_iterator<_Iter2>& _Last) { + friend constexpr void _Verify_range(const move_iterator& _First, const move_iterator<_Iter2>& _Last) noexcept( + noexcept(_Verify_range(_First._Current, _Last.base()))) { _Verify_range(_First._Current, _Last.base()); } #ifdef __cpp_lib_concepts template _Sent, enable_if_t<_Range_verifiable_v<_Iter, _Sent>, int> = 0> - friend constexpr void _Verify_range(const move_iterator& _First, const move_sentinel<_Sent>& _Last) { + friend constexpr void _Verify_range(const move_iterator& _First, const move_sentinel<_Sent>& _Last) noexcept( + noexcept(_Verify_range(_First._Current, _Last._Get_last()))) { _Verify_range(_First._Current, _Last._Get_last()); } #endif // __cpp_lib_concepts @@ -3476,27 +3499,29 @@ public: using _Prevent_inheriting_unwrap = move_iterator; template , int> = 0> - constexpr void _Verify_offset(const difference_type _Off) const { + constexpr void _Verify_offset(const difference_type _Off) const noexcept(noexcept(_Current._Verify_offset(_Off))) { _Current._Verify_offset(_Off); } template , int> = 0> - _NODISCARD constexpr move_iterator<_Unwrapped_t> _Unwrapped() const& { + _NODISCARD constexpr move_iterator<_Unwrapped_t> _Unwrapped() const& noexcept( + noexcept(static_cast>>(_Current._Unwrapped()))) { return static_cast>>(_Current._Unwrapped()); } template , int> = 0> - _NODISCARD constexpr move_iterator<_Unwrapped_t<_Iter2>> _Unwrapped() && { + _NODISCARD constexpr move_iterator<_Unwrapped_t<_Iter2>> _Unwrapped() && noexcept( + noexcept(static_cast>>(_STD move(_Current)._Unwrapped()))) { return static_cast>>(_STD move(_Current)._Unwrapped()); } static constexpr bool _Unwrap_when_unverified = _Do_unwrap_when_unverified_v; template , int> = 0> - constexpr void _Seek_to(const move_iterator<_Src>& _It) { + constexpr void _Seek_to(const move_iterator<_Src>& _It) noexcept(noexcept(_Current._Seek_to(_It.base()))) { _Current._Seek_to(_It.base()); } template , int> = 0> - constexpr void _Seek_to(move_iterator<_Src>&& _It) { + constexpr void _Seek_to(move_iterator<_Src>&& _It) noexcept(noexcept(_Current._Seek_to(_STD move(_It).base()))) { _Current._Seek_to(_STD move(_It).base()); } @@ -3505,7 +3530,8 @@ private: }; template -_NODISCARD _CONSTEXPR17 bool operator==(const move_iterator<_Iter1>& _Left, const move_iterator<_Iter2>& _Right) +_NODISCARD _CONSTEXPR17 bool operator==(const move_iterator<_Iter1>& _Left, + const move_iterator<_Iter2>& _Right) noexcept(noexcept(_Left.base() == _Right.base())) /* strengthened */ #ifdef __cpp_lib_concepts // clang-format off requires requires { @@ -3517,13 +3543,15 @@ _NODISCARD _CONSTEXPR17 bool operator==(const move_iterator<_Iter1>& _Left, cons #if !_HAS_CXX20 template -_NODISCARD _CONSTEXPR17 bool operator!=(const move_iterator<_Iter1>& _Left, const move_iterator<_Iter2>& _Right) { +_NODISCARD _CONSTEXPR17 bool operator!=(const move_iterator<_Iter1>& _Left, + const move_iterator<_Iter2>& _Right) noexcept(noexcept(!(_Left == _Right))) /* strengthened */ { return !(_Left == _Right); } #endif // !_HAS_CXX20 template -_NODISCARD _CONSTEXPR17 bool operator<(const move_iterator<_Iter1>& _Left, const move_iterator<_Iter2>& _Right) +_NODISCARD _CONSTEXPR17 bool operator<(const move_iterator<_Iter1>& _Left, + const move_iterator<_Iter2>& _Right) noexcept(noexcept(_Left.base() < _Right.base())) /* strengthened */ #ifdef __cpp_lib_concepts // clang-format off requires requires { @@ -3534,7 +3562,8 @@ _NODISCARD _CONSTEXPR17 bool operator<(const move_iterator<_Iter1>& _Left, const { return _Left.base() < _Right.base(); } template -_NODISCARD _CONSTEXPR17 bool operator>(const move_iterator<_Iter1>& _Left, const move_iterator<_Iter2>& _Right) +_NODISCARD _CONSTEXPR17 bool operator>(const move_iterator<_Iter1>& _Left, + const move_iterator<_Iter2>& _Right) noexcept(noexcept(_Right < _Left)) /* strengthened */ #ifdef __cpp_lib_concepts // clang-format off requires requires { _Right < _Left; } @@ -3543,7 +3572,8 @@ _NODISCARD _CONSTEXPR17 bool operator>(const move_iterator<_Iter1>& _Left, const { return _Right < _Left; } template -_NODISCARD _CONSTEXPR17 bool operator<=(const move_iterator<_Iter1>& _Left, const move_iterator<_Iter2>& _Right) +_NODISCARD _CONSTEXPR17 bool operator<=(const move_iterator<_Iter1>& _Left, + const move_iterator<_Iter2>& _Right) noexcept(noexcept(!(_Right < _Left))) /* strengthened */ #ifdef __cpp_lib_concepts // clang-format off requires requires { _Right < _Left; } @@ -3552,7 +3582,8 @@ _NODISCARD _CONSTEXPR17 bool operator<=(const move_iterator<_Iter1>& _Left, cons { return !(_Right < _Left); } template -_NODISCARD _CONSTEXPR17 bool operator>=(const move_iterator<_Iter1>& _Left, const move_iterator<_Iter2>& _Right) +_NODISCARD _CONSTEXPR17 bool operator>=(const move_iterator<_Iter1>& _Left, + const move_iterator<_Iter2>& _Right) noexcept(noexcept(!(_Left < _Right))) /* strengthened */ #ifdef __cpp_lib_concepts // clang-format off requires requires { _Left < _Right; } @@ -3562,21 +3593,23 @@ _NODISCARD _CONSTEXPR17 bool operator>=(const move_iterator<_Iter1>& _Left, cons #ifdef __cpp_lib_concepts template _Iter2> -_NODISCARD constexpr compare_three_way_result_t<_Iter1, _Iter2> operator<=>( - const move_iterator<_Iter1>& _Left, const move_iterator<_Iter2>& _Right) { +_NODISCARD constexpr compare_three_way_result_t<_Iter1, _Iter2> operator<=>(const move_iterator<_Iter1>& _Left, + const move_iterator<_Iter2>& _Right) noexcept(noexcept(_Left.base() <=> _Right.base())) /* strengthened */ { return _Left.base() <=> _Right.base(); } #endif // __cpp_lib_concepts template -_NODISCARD _CONSTEXPR17 auto operator-(const move_iterator<_Iter1>& _Left, const move_iterator<_Iter2>& _Right) - -> decltype(_Left.base() - _Right.base()) { +_NODISCARD _CONSTEXPR17 auto + operator-(const move_iterator<_Iter1>& _Left, const move_iterator<_Iter2>& _Right) noexcept( + noexcept(_Left.base() - _Right.base())) /* strengthened */ -> decltype(_Left.base() - _Right.base()) { return _Left.base() - _Right.base(); } template -_NODISCARD _CONSTEXPR17 move_iterator<_Iter> operator+( - typename move_iterator<_Iter>::difference_type _Off, const move_iterator<_Iter>& _Right) +_NODISCARD _CONSTEXPR17 move_iterator<_Iter> + operator+(typename move_iterator<_Iter>::difference_type _Off, const move_iterator<_Iter>& _Right) noexcept( + is_nothrow_copy_constructible_v<_Iter>&& noexcept(_Right.base() + _Off)) /* strengthened */ #ifdef __cpp_lib_concepts // clang-format off requires requires { @@ -3587,7 +3620,8 @@ _NODISCARD _CONSTEXPR17 move_iterator<_Iter> operator+( { return move_iterator<_Iter>{_Right.base() + _Off}; } template -_NODISCARD _CONSTEXPR17 move_iterator<_Iter> make_move_iterator(_Iter _It) { // make move_iterator from iterator +_NODISCARD _CONSTEXPR17 move_iterator<_Iter> make_move_iterator(_Iter _It) noexcept( + is_nothrow_move_constructible_v<_Iter>) /* strengthened */ { // make move_iterator from iterator return move_iterator<_Iter>(_STD move(_It)); } @@ -3906,6 +3940,7 @@ namespace ranges { } } + #if _HAS_CXX23 template struct out_value_result { @@ -3980,7 +4015,7 @@ namespace ranges { // clang-format on }; - inline constexpr _Copy_fn copy{_Not_quite_object::_Construct_tag{}}; + inline constexpr _Copy_fn copy{_Not_quite_object::_Construct_tag {}}; } // namespace ranges #endif // __cpp_lib_concepts @@ -4261,6 +4296,7 @@ _CONSTEXPR20 void fill(const _FwdIt _First, const _FwdIt _Last, const _Ty& _Val) } } + #if _HAS_CXX17 template = 0> void fill(_ExPo&&, _FwdIt _First, _FwdIt _Last, const _Ty& _Val) noexcept /* terminates */ { @@ -4354,7 +4390,7 @@ namespace ranges { } }; - inline constexpr _Fill_n_fn fill_n{_Not_quite_object::_Construct_tag{}}; + inline constexpr _Fill_n_fn fill_n{_Not_quite_object::_Construct_tag {}}; } // namespace ranges #endif // __cpp_lib_concepts @@ -4539,6 +4575,7 @@ _NODISCARD _CONSTEXPR20 bool equal( } } + #if _HAS_CXX17 template = 0> _NODISCARD bool equal(_ExPo&& _Exec, const _FwdIt1 _First1, const _FwdIt1 _Last1, const _FwdIt2 _First2, @@ -4698,7 +4735,7 @@ namespace ranges { } }; - inline constexpr _Mismatch_fn mismatch{_Not_quite_object::_Construct_tag{}}; + inline constexpr _Mismatch_fn mismatch{_Not_quite_object::_Construct_tag {}}; } // namespace ranges #endif // __cpp_lib_concepts @@ -5142,7 +5179,7 @@ namespace ranges { // clang-format on }; - inline constexpr _Find_fn find{_Not_quite_object::_Construct_tag{}}; + inline constexpr _Find_fn find{_Not_quite_object::_Construct_tag {}}; } // namespace ranges #endif // __cpp_lib_concepts @@ -5184,6 +5221,7 @@ _NODISCARD _CONSTEXPR20 _Iter_diff_t<_InIt> count(const _InIt _First, const _InI } } + #if _HAS_CXX17 template = 0> _NODISCARD _Iter_diff_t<_FwdIt> count( @@ -5392,6 +5430,7 @@ _CONSTEXPR20 void reverse(const _BidIt _First, const _BidIt _Last) { // reverse } } + #if _HAS_CXX17 template = 0> void reverse(_ExPo&&, _BidIt _First, _BidIt _Last) noexcept /* terminates */ { @@ -5561,7 +5600,7 @@ namespace ranges { } }; - inline constexpr _Find_if_fn find_if{_Not_quite_object::_Construct_tag{}}; + inline constexpr _Find_if_fn find_if{_Not_quite_object::_Construct_tag {}}; class _Find_if_not_fn : private _Not_quite_object { public: @@ -5608,7 +5647,7 @@ namespace ranges { } }; - inline constexpr _Find_if_not_fn find_if_not{_Not_quite_object::_Construct_tag{}}; + inline constexpr _Find_if_not_fn find_if_not{_Not_quite_object::_Construct_tag {}}; class _Adjacent_find_fn : private _Not_quite_object { public: @@ -5659,7 +5698,7 @@ namespace ranges { } }; - inline constexpr _Adjacent_find_fn adjacent_find{_Not_quite_object::_Construct_tag{}}; + inline constexpr _Adjacent_find_fn adjacent_find{_Not_quite_object::_Construct_tag {}}; // clang-format off template @@ -5687,14 +5726,14 @@ namespace ranges { _First1 += (_Last2 - _First2); return {true, _STD move(_First1)}; } else { - return {false, _It1{}}; + return {false, _It1 {}}; } } } for (; _First2 != _Last2; ++_First1, (void) ++_First2) { if (!_STD invoke(_Pred, _STD invoke(_Proj1, *_First1), _STD invoke(_Proj2, *_First2))) { - return {false, _It1{}}; + return {false, _It1 {}}; } } @@ -5804,7 +5843,7 @@ namespace ranges { } }; - inline constexpr _Search_fn search{_Not_quite_object::_Construct_tag{}}; + inline constexpr _Search_fn search{_Not_quite_object::_Construct_tag {}}; } // namespace ranges #endif // __cpp_lib_concepts From f54de416577aef25bf9c22f5e30e3fa9349ccb20 Mon Sep 17 00:00:00 2001 From: Michael Schellenberger Costa Date: Wed, 7 Oct 2020 10:27:47 +0200 Subject: [PATCH 04/10] Fix _Operator_arrow --- stl/inc/xutility | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/stl/inc/xutility b/stl/inc/xutility index 69f9519afe2..7156cbd2593 100644 --- a/stl/inc/xutility +++ b/stl/inc/xutility @@ -1204,6 +1204,16 @@ _NODISCARD _CONSTEXPR17 _BidIt prev(_BidIt _First, _Iter_diff_t<_BidIt> _Off = 1 return _First; } +template +_NODISCARD constexpr _Iter _Operator_arrow(true_type, _Iter _Target) { + return _Target; +} + +template +_NODISCARD constexpr decltype(auto) _Operator_arrow(false_type, _Iter& _Target) { + return _Target.operator->(); +} + template class reverse_iterator { public: @@ -1264,10 +1274,11 @@ public: #ifdef __cpp_lib_concepts // clang-format off - _NODISCARD constexpr pointer operator->() const noexcept(is_nothrow_copy_constructible_v<_BidIt> - && noexcept(--(_STD declval<_BidIt&>())) && noexcept(_Implicitly_convert_to( - _Operator_arrow(_STD declval<_BidIt&>(), is_pointer<_BidIt>())))) /* strengthened */ - requires (is_pointer_v<_BidIt> || requires(const _BidIt __i) { __i.operator->(); }) { + _NODISCARD constexpr pointer operator->() const noexcept(is_nothrow_copy_constructible_v<_BidIt>&& noexcept( + --(_STD declval<_BidIt&>())) && noexcept(_Implicitly_convert_to(_Operator_arrow(is_pointer<_BidIt>{}, + _STD declval<_BidIt&>())))) /* strengthened */ + requires (is_pointer_v<_BidIt> || requires(const _BidIt __i) { __i.operator->(); }) + { _BidIt _Tmp = current; --_Tmp; if constexpr (is_pointer_v<_BidIt>) { @@ -1278,10 +1289,9 @@ public: } // clang-format on #else // ^^^ __cpp_lib_concepts / !__cpp_lib_concepts vvv - _NODISCARD _CONSTEXPR17 pointer operator->() const - noexcept(is_nothrow_copy_constructible_v<_BidIt>&& noexcept(--(_STD declval<_BidIt&>())) && noexcept( - _Implicitly_convert_to( - _Operator_arrow(_STD declval<_BidIt&>(), is_pointer<_BidIt>())))) /* strengthened */ { + _NODISCARD _CONSTEXPR17 pointer operator->() const noexcept(is_nothrow_copy_constructible_v<_BidIt>&& noexcept( + --(_STD declval<_BidIt&>())) && noexcept(_Implicitly_convert_to(_Operator_arrow(is_pointer<_BidIt>{}, + _STD declval<_BidIt&>())))) /* strengthened */ { _BidIt _Tmp = current; --_Tmp; if constexpr (is_pointer_v<_BidIt>) { From 5eea6a7a1e114aacabdd24a87e12b3a6302815ce Mon Sep 17 00:00:00 2001 From: Michael Schellenberger Costa Date: Thu, 8 Oct 2020 13:02:29 +0200 Subject: [PATCH 05/10] Try a bit more workarounds :( --- stl/inc/xutility | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/stl/inc/xutility b/stl/inc/xutility index 7156cbd2593..cd402bbaa6e 100644 --- a/stl/inc/xutility +++ b/stl/inc/xutility @@ -3494,14 +3494,24 @@ public: #endif // __cpp_lib_concepts template , int> = 0> - friend constexpr void _Verify_range(const move_iterator& _First, const move_iterator<_Iter2>& _Last) noexcept( - noexcept(_Verify_range(_First._Current, _Last.base()))) { + friend constexpr void _Verify_range(const move_iterator& _First, const move_iterator<_Iter2>& _Last) +#ifdef __EDG__ // TRANSITION, VSO-1222776 + noexcept(noexcept(_Verify_range(_STD declval(), _STD declval()))) +#else // ^^^ workaround / no workaround vvv + noexcept(noexcept(_Verify_range(_First._Current, _Last.base()))) +#endif // TRANSITION, VSO-1222776 + { _Verify_range(_First._Current, _Last.base()); } #ifdef __cpp_lib_concepts template _Sent, enable_if_t<_Range_verifiable_v<_Iter, _Sent>, int> = 0> - friend constexpr void _Verify_range(const move_iterator& _First, const move_sentinel<_Sent>& _Last) noexcept( - noexcept(_Verify_range(_First._Current, _Last._Get_last()))) { + friend constexpr void _Verify_range(const move_iterator& _First, const move_sentinel<_Sent>& _Last) +#ifdef __EDG__ // TRANSITION, VSO-1222776 + noexcept(noexcept(_Verify_range(_STD declval(), _STD declval()))) +#else // ^^^ workaround / no workaround vvv + noexcept(noexcept(_Verify_range(_First._Current, _Last._Get_last()))) +#endif // TRANSITION, VSO-1222776 + { _Verify_range(_First._Current, _Last._Get_last()); } #endif // __cpp_lib_concepts From 48f48c20e0d128066691f7c7598142dbbcf66ad3 Mon Sep 17 00:00:00 2001 From: Nicole Mazzuca Date: Fri, 12 Aug 2022 09:35:23 -0700 Subject: [PATCH 06/10] CRs --- stl/inc/xutility | 140 +++++++++++++++++++++-------------------------- 1 file changed, 62 insertions(+), 78 deletions(-) diff --git a/stl/inc/xutility b/stl/inc/xutility index cd402bbaa6e..95e684c3246 100644 --- a/stl/inc/xutility +++ b/stl/inc/xutility @@ -162,6 +162,14 @@ _NODISCARD _CONSTEXPR_BIT_CAST _To _Bit_cast(const _From& _Val) noexcept { #endif // ^^^ no workaround ^^^ } +template +_NODISCARD _Ty _Fake_decay_copy(_Ty) noexcept; +// _Fake_decay_copy(E): +// (1) has type T [decay_t if T is deduced], +// (2) is well-formed if and only if E is implicitly convertible to T and T is destructible, and +// (3) is non-throwing if and only if both conversion from decltype((E)) to T and destruction of T are non-throwing. + + template struct _Get_first_parameter; @@ -1204,15 +1212,12 @@ _NODISCARD _CONSTEXPR17 _BidIt prev(_BidIt _First, _Iter_diff_t<_BidIt> _Off = 1 return _First; } -template -_NODISCARD constexpr _Iter _Operator_arrow(true_type, _Iter _Target) { - return _Target; -} - -template -_NODISCARD constexpr decltype(auto) _Operator_arrow(false_type, _Iter& _Target) { - return _Target.operator->(); -} +template >> +_INLINE_VAR constexpr bool _Is_nothrow_operator_arrow = noexcept( + _Implicitly_convert_to<_Pointer>(_STD declval<_Iter>())); +template +_INLINE_VAR constexpr bool _Is_nothrow_operator_arrow<_Iter, _Pointer, false> = noexcept( + _Implicitly_convert_to<_Pointer>(_STD declval<_Iter>().operator->())); template class reverse_iterator { @@ -1256,7 +1261,7 @@ public: && assignable_from<_BidIt&, const _Other&> #endif // __cpp_lib_concepts _CONSTEXPR17 reverse_iterator& operator=(const reverse_iterator<_Other>& _Right) noexcept( - is_nothrow_constructible_v<_BidIt, const _Other&>) /* strengthened */ { + is_nothrow_assignable_v<_BidIt&, const _Other&>) /* strengthened */ { current = _Right.current; return *this; } @@ -1275,8 +1280,7 @@ public: #ifdef __cpp_lib_concepts // clang-format off _NODISCARD constexpr pointer operator->() const noexcept(is_nothrow_copy_constructible_v<_BidIt>&& noexcept( - --(_STD declval<_BidIt&>())) && noexcept(_Implicitly_convert_to(_Operator_arrow(is_pointer<_BidIt>{}, - _STD declval<_BidIt&>())))) /* strengthened */ + --(_STD declval<_BidIt&>())) && _Is_nothrow_operator_arrow) /* strengthened */ requires (is_pointer_v<_BidIt> || requires(const _BidIt __i) { __i.operator->(); }) { _BidIt _Tmp = current; @@ -1289,9 +1293,9 @@ public: } // clang-format on #else // ^^^ __cpp_lib_concepts / !__cpp_lib_concepts vvv - _NODISCARD _CONSTEXPR17 pointer operator->() const noexcept(is_nothrow_copy_constructible_v<_BidIt>&& noexcept( - --(_STD declval<_BidIt&>())) && noexcept(_Implicitly_convert_to(_Operator_arrow(is_pointer<_BidIt>{}, - _STD declval<_BidIt&>())))) /* strengthened */ { + _NODISCARD _CONSTEXPR17 pointer operator->() const + noexcept(is_nothrow_copy_constructible_v<_BidIt>&& noexcept(--(_STD declval<_BidIt&>())) + && _Is_nothrow_operator_arrow) /* strengthened */ { _BidIt _Tmp = current; --_Tmp; if constexpr (is_pointer_v<_BidIt>) { @@ -1327,7 +1331,7 @@ public: } _NODISCARD _CONSTEXPR17 reverse_iterator operator+(const difference_type _Off) const - noexcept(is_nothrow_copy_constructible_v<_BidIt>&& noexcept(current - _Off)) /* strengthened */ { + noexcept(noexcept(reverse_iterator(current - _Off))) /* strengthened */ { return reverse_iterator(current - _Off); } @@ -1338,7 +1342,7 @@ public: } _NODISCARD _CONSTEXPR17 reverse_iterator operator-(const difference_type _Off) const - noexcept(is_nothrow_copy_constructible_v<_BidIt>&& noexcept(current + _Off)) /* strengthened */ { + noexcept(noexcept(reverse_iterator(current + _Off))) /* strengthened */ { return reverse_iterator(current + _Off); } @@ -1376,13 +1380,13 @@ public: using _Prevent_inheriting_unwrap = reverse_iterator; template , int> = 0> - friend constexpr void _Verify_range(const reverse_iterator& _First, - const reverse_iterator<_BidIt2>& _Last) noexcept(noexcept(_Verify_range(_Last.base(), _First.base()))) { + friend constexpr void _Verify_range( + const reverse_iterator& _First, const reverse_iterator<_BidIt2>& _Last) noexcept { _Verify_range(_Last._Get_current(), _First.current); // note reversed parameters } template , int> = 0> - constexpr void _Verify_offset(const difference_type _Off) const noexcept(noexcept(current._Verify_offset(-_Off))) { + constexpr void _Verify_offset(const difference_type _Off) const noexcept { _STL_VERIFY(_Off != _Min_possible_v, "integer overflow"); current._Verify_offset(-_Off); } @@ -1411,7 +1415,7 @@ protected: template _NODISCARD _CONSTEXPR17 bool operator==(const reverse_iterator<_BidIt1>& _Left, const reverse_iterator<_BidIt2>& _Right) noexcept( - noexcept(_Left._Get_current() == _Right._Get_current())) /* strengthened */ + noexcept(_Implicitly_convert_to(_Left._Get_current() == _Right._Get_current()))) /* strengthened */ #ifdef __cpp_lib_concepts // clang-format off requires requires { @@ -1424,7 +1428,7 @@ _NODISCARD _CONSTEXPR17 bool template _NODISCARD _CONSTEXPR17 bool operator!=(const reverse_iterator<_BidIt1>& _Left, const reverse_iterator<_BidIt2>& _Right) noexcept( - noexcept(_Left._Get_current() != _Right._Get_current())) /* strengthened */ + noexcept(_Implicitly_convert_to(_Left._Get_current() != _Right._Get_current()))) /* strengthened */ #ifdef __cpp_lib_concepts // clang-format off requires requires { @@ -1437,7 +1441,7 @@ _NODISCARD _CONSTEXPR17 bool template _NODISCARD _CONSTEXPR17 bool operator<(const reverse_iterator<_BidIt1>& _Left, const reverse_iterator<_BidIt2>& _Right) noexcept( - noexcept(_Left._Get_current() > _Right._Get_current())) /* strengthened */ + noexcept(_Implicitly_convert_to(_Left._Get_current() > _Right._Get_current()))) /* strengthened */ #ifdef __cpp_lib_concepts // clang-format off requires requires { @@ -1450,7 +1454,7 @@ _NODISCARD _CONSTEXPR17 bool template _NODISCARD _CONSTEXPR17 bool operator>(const reverse_iterator<_BidIt1>& _Left, const reverse_iterator<_BidIt2>& _Right) noexcept( - noexcept(_Left._Get_current() < _Right._Get_current())) /* strengthened */ + noexcept(_Implicitly_convert_to(_Left._Get_current() < _Right._Get_current()))) /* strengthened */ #ifdef __cpp_lib_concepts // clang-format off requires requires { @@ -1463,7 +1467,7 @@ _NODISCARD _CONSTEXPR17 bool template _NODISCARD _CONSTEXPR17 bool operator<=(const reverse_iterator<_BidIt1>& _Left, const reverse_iterator<_BidIt2>& _Right) noexcept( - noexcept(_Left._Get_current() >= _Right._Get_current())) /* strengthened */ + noexcept(_Implicitly_convert_to(_Left._Get_current() >= _Right._Get_current()))) /* strengthened */ #ifdef __cpp_lib_concepts // clang-format off requires requires { @@ -1476,7 +1480,7 @@ _NODISCARD _CONSTEXPR17 bool template _NODISCARD _CONSTEXPR17 bool operator>=(const reverse_iterator<_BidIt1>& _Left, const reverse_iterator<_BidIt2>& _Right) noexcept( - noexcept(_Left._Get_current() <= _Right._Get_current())) /* strengthened */ + noexcept(_Implicitly_convert_to(_Left._Get_current() <= _Right._Get_current()))) /* strengthened */ #ifdef __cpp_lib_concepts // clang-format off requires requires { @@ -1616,13 +1620,13 @@ _NODISCARD _CONSTEXPR17 reverse_iterator rend(initializer_list<_El } template -_NODISCARD _CONSTEXPR17 auto crbegin(const _Container& _Cont) noexcept(noexcept(rbegin(_Cont))) /* strengthened */ +_NODISCARD _CONSTEXPR17 auto crbegin(const _Container& _Cont) noexcept(noexcept(_STD rbegin(_Cont))) /* strengthened */ -> decltype(_STD rbegin(_Cont)) { return _STD rbegin(_Cont); } template -_NODISCARD _CONSTEXPR17 auto crend(const _Container& _Cont) noexcept(noexcept(rbegin(_Cont))) /* strengthened */ +_NODISCARD _CONSTEXPR17 auto crend(const _Container& _Cont) noexcept(noexcept(_STD rend(_Cont))) /* strengthened */ -> decltype(_STD rend(_Cont)) { return _STD rend(_Cont); } @@ -1654,7 +1658,8 @@ _NODISCARD constexpr ptrdiff_t ssize(const _Ty (&)[_Size]) noexcept { #endif // _HAS_CXX20 template -_NODISCARD constexpr auto empty(const _Container& _Cont) noexcept(noexcept(_Cont.empty())) /* strengthened */ +_NODISCARD constexpr auto empty(const _Container& _Cont) noexcept( + noexcept(_Fake_decay_copy(_Cont.empty()))) /* strengthened */ -> decltype(_Cont.empty()) { return _Cont.empty(); } @@ -1670,13 +1675,14 @@ _NODISCARD constexpr bool empty(initializer_list<_Elem> _Ilist) noexcept { } template -_NODISCARD constexpr auto data(_Container& _Cont) noexcept(noexcept(_Cont.data())) /* strengthened */ +_NODISCARD constexpr auto data(_Container& _Cont) noexcept(noexcept(_Fake_decay_copy(_Cont.data()))) /* strengthened */ -> decltype(_Cont.data()) { return _Cont.data(); } template -_NODISCARD constexpr auto data(const _Container& _Cont) noexcept(noexcept(_Cont.data())) /* strengthened */ +_NODISCARD constexpr auto data(const _Container& _Cont) noexcept( + noexcept(_Fake_decay_copy(_Cont.data()))) /* strengthened */ -> decltype(_Cont.data()) { return _Cont.data(); } @@ -1692,13 +1698,6 @@ _NODISCARD constexpr const _Elem* data(initializer_list<_Elem> _Ilist) noexcept } #ifdef __cpp_lib_concepts -template -_NODISCARD _Ty _Fake_decay_copy(_Ty) noexcept; -// _Fake_decay_copy(E): -// (1) has type T [decay_t if T is deduced], -// (2) is well-formed if and only if E is implicitly convertible to T and T is destructible, and -// (3) is non-throwing if and only if both conversion from decltype((E)) to T and destruction of T are non-throwing. - template concept _Not_same_as = !same_as, remove_cvref_t<_Ty2>>; @@ -3355,11 +3354,7 @@ public: _NODISCARD _CONSTEXPR17 reference operator*() const #ifdef __cpp_lib_concepts -#ifdef __EDG__ // TRANSITION, VSO-1132105 - noexcept(noexcept(_RANGES iter_move(_STD declval()))) /* strengthened */ { -#else // ^^^ workaround / no workaround vvv noexcept(noexcept(_RANGES iter_move(_Current))) /* strengthened */ { -#endif // TRANSITION, VSO-1132105 return _RANGES iter_move(_Current); #else // ^^^ __cpp_lib_concepts / !__cpp_lib_concepts vvv noexcept(noexcept(static_cast(*_Current))) /* strengthened */ { @@ -3367,7 +3362,7 @@ public: #endif // __cpp_lib_concepts } - _NODISCARD _CXX20_DEPRECATE_MOVE_ITERATOR_ARROW _CONSTEXPR17 pointer operator->() const + _CXX20_DEPRECATE_MOVE_ITERATOR_ARROW _NODISCARD _CONSTEXPR17 pointer operator->() const noexcept(is_nothrow_copy_constructible_v<_Iter>) /* strengthened */ { return _Current; } @@ -3417,7 +3412,7 @@ public: } _NODISCARD _CONSTEXPR17 move_iterator operator+(const difference_type _Off) const - noexcept(is_nothrow_copy_constructible_v<_Iter>&& noexcept(_Current + _Off)) /* strengthened */ { + noexcept(noexcept(move_iterator(_Current + _Off))) /* strengthened */ { return move_iterator(_Current + _Off); } @@ -3428,7 +3423,7 @@ public: } _NODISCARD _CONSTEXPR17 move_iterator operator-(const difference_type _Off) const - noexcept(is_nothrow_copy_constructible_v<_Iter>&& noexcept(_Current - _Off)) /* strengthened */ { + noexcept(noexcept(move_iterator(_Current - _Off))) /* strengthened */ { return move_iterator(_Current - _Off); } @@ -3440,11 +3435,7 @@ public: _NODISCARD _CONSTEXPR17 reference operator[](const difference_type _Off) const #ifdef __cpp_lib_concepts -#ifdef __EDG__ // TRANSITION, VSO-1132105 - noexcept(noexcept(_RANGES iter_move(_STD declval() + difference_type{}))) /* strengthened */ { -#else // ^^^ workaround / no workaround vvv noexcept(noexcept(_RANGES iter_move(_Current + _Off))) /* strengthened */ { -#endif // TRANSITION, VSO-1132105 return _RANGES iter_move(_Current + _Off); #else // ^^^ __cpp_lib_concepts / !__cpp_lib_concepts vvv noexcept(noexcept(_STD move(_Current[_Off]))) /* strengthened */ { @@ -3454,8 +3445,9 @@ public: #ifdef __cpp_lib_concepts template _Sent> - _NODISCARD_FRIEND constexpr bool operator==(const move_iterator& _Left, const move_sentinel<_Sent>& _Right) - noexcept(_Left._Current == _Right._Get_last())) /* strengthened */ { + _NODISCARD_FRIEND constexpr bool + operator==(const move_iterator& _Left, const move_sentinel<_Sent>& _Right) noexcept( + noexcept(_Implicitly_convert_to(_Left._Current == _Right._Get_last()))) /* strengthened */ { return _Left._Current == _Right._Get_last(); } @@ -3494,24 +3486,12 @@ public: #endif // __cpp_lib_concepts template , int> = 0> - friend constexpr void _Verify_range(const move_iterator& _First, const move_iterator<_Iter2>& _Last) -#ifdef __EDG__ // TRANSITION, VSO-1222776 - noexcept(noexcept(_Verify_range(_STD declval(), _STD declval()))) -#else // ^^^ workaround / no workaround vvv - noexcept(noexcept(_Verify_range(_First._Current, _Last.base()))) -#endif // TRANSITION, VSO-1222776 - { - _Verify_range(_First._Current, _Last.base()); + friend constexpr void _Verify_range(const move_iterator& _First, const move_iterator<_Iter2>& _Last) noexcept { + _Verify_range(_First._Current, _Last._Get_current()); } #ifdef __cpp_lib_concepts template _Sent, enable_if_t<_Range_verifiable_v<_Iter, _Sent>, int> = 0> - friend constexpr void _Verify_range(const move_iterator& _First, const move_sentinel<_Sent>& _Last) -#ifdef __EDG__ // TRANSITION, VSO-1222776 - noexcept(noexcept(_Verify_range(_STD declval(), _STD declval()))) -#else // ^^^ workaround / no workaround vvv - noexcept(noexcept(_Verify_range(_First._Current, _Last._Get_last()))) -#endif // TRANSITION, VSO-1222776 - { + friend constexpr void _Verify_range(const move_iterator& _First, const move_sentinel<_Sent>& _Last) noexcept { _Verify_range(_First._Current, _Last._Get_last()); } #endif // __cpp_lib_concepts @@ -3519,7 +3499,7 @@ public: using _Prevent_inheriting_unwrap = move_iterator; template , int> = 0> - constexpr void _Verify_offset(const difference_type _Off) const noexcept(noexcept(_Current._Verify_offset(_Off))) { + constexpr void _Verify_offset(const difference_type _Off) const noexcept { _Current._Verify_offset(_Off); } @@ -3537,12 +3517,20 @@ public: static constexpr bool _Unwrap_when_unverified = _Do_unwrap_when_unverified_v; template , int> = 0> - constexpr void _Seek_to(const move_iterator<_Src>& _It) noexcept(noexcept(_Current._Seek_to(_It.base()))) { + constexpr void _Seek_to(const move_iterator<_Src>& _It) noexcept(noexcept(_Current._Seek_to(_It._Get_current()))) { _Current._Seek_to(_It.base()); } template , int> = 0> - constexpr void _Seek_to(move_iterator<_Src>&& _It) noexcept(noexcept(_Current._Seek_to(_STD move(_It).base()))) { - _Current._Seek_to(_STD move(_It).base()); + constexpr void _Seek_to(move_iterator<_Src>&& _It) noexcept( + noexcept(_Current._Seek_to(_STD move(_It)._Get_current()))) { + _Current._Seek_to(_STD move(_It)._Get_current()); + } + + constexpr const iterator_type& _Get_current() const& noexcept { + return _Current; + } + constexpr iterator_type&& _Get_current() && noexcept { + return static_cast(_Current); } private: @@ -3570,8 +3558,9 @@ _NODISCARD _CONSTEXPR17 bool operator!=(const move_iterator<_Iter1>& _Left, #endif // !_HAS_CXX20 template -_NODISCARD _CONSTEXPR17 bool operator<(const move_iterator<_Iter1>& _Left, - const move_iterator<_Iter2>& _Right) noexcept(noexcept(_Left.base() < _Right.base())) /* strengthened */ +_NODISCARD _CONSTEXPR17 bool + operator<(const move_iterator<_Iter1>& _Left, const move_iterator<_Iter2>& _Right) noexcept( + noexcept(_Implicitly_convert_to(_Left.base() < _Right.base()))) /* strengthened */ #ifdef __cpp_lib_concepts // clang-format off requires requires { @@ -3629,7 +3618,7 @@ _NODISCARD _CONSTEXPR17 auto template _NODISCARD _CONSTEXPR17 move_iterator<_Iter> operator+(typename move_iterator<_Iter>::difference_type _Off, const move_iterator<_Iter>& _Right) noexcept( - is_nothrow_copy_constructible_v<_Iter>&& noexcept(_Right.base() + _Off)) /* strengthened */ + noexcept(move_iterator<_Iter>(_Right.base() + _Off))) /* strengthened */ #ifdef __cpp_lib_concepts // clang-format off requires requires { @@ -3960,7 +3949,6 @@ namespace ranges { } } - #if _HAS_CXX23 template struct out_value_result { @@ -4316,7 +4304,6 @@ _CONSTEXPR20 void fill(const _FwdIt _First, const _FwdIt _Last, const _Ty& _Val) } } - #if _HAS_CXX17 template = 0> void fill(_ExPo&&, _FwdIt _First, _FwdIt _Last, const _Ty& _Val) noexcept /* terminates */ { @@ -4595,7 +4582,6 @@ _NODISCARD _CONSTEXPR20 bool equal( } } - #if _HAS_CXX17 template = 0> _NODISCARD bool equal(_ExPo&& _Exec, const _FwdIt1 _First1, const _FwdIt1 _Last1, const _FwdIt2 _First2, @@ -5241,7 +5227,6 @@ _NODISCARD _CONSTEXPR20 _Iter_diff_t<_InIt> count(const _InIt _First, const _InI } } - #if _HAS_CXX17 template = 0> _NODISCARD _Iter_diff_t<_FwdIt> count( @@ -5450,7 +5435,6 @@ _CONSTEXPR20 void reverse(const _BidIt _First, const _BidIt _Last) { // reverse } } - #if _HAS_CXX17 template = 0> void reverse(_ExPo&&, _BidIt _First, _BidIt _Last) noexcept /* terminates */ { From 561cd62536030ac25def523ccb7131b2b5087323 Mon Sep 17 00:00:00 2001 From: Nicole Mazzuca Date: Fri, 12 Aug 2022 09:41:11 -0700 Subject: [PATCH 07/10] make clean merge with #2991 --- stl/inc/xutility | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/stl/inc/xutility b/stl/inc/xutility index 95e684c3246..f57e4648252 100644 --- a/stl/inc/xutility +++ b/stl/inc/xutility @@ -1392,8 +1392,7 @@ public: } template , int> = 0> - _NODISCARD constexpr reverse_iterator<_Unwrapped_t> _Unwrapped() const - noexcept(noexcept(static_cast>>(current._Unwrapped()))) { + _NODISCARD constexpr reverse_iterator<_Unwrapped_t> _Unwrapped() const { return static_cast>>(current._Unwrapped()); } @@ -3504,13 +3503,11 @@ public: } template , int> = 0> - _NODISCARD constexpr move_iterator<_Unwrapped_t> _Unwrapped() const& noexcept( - noexcept(static_cast>>(_Current._Unwrapped()))) { + _NODISCARD constexpr move_iterator<_Unwrapped_t> _Unwrapped() const& { return static_cast>>(_Current._Unwrapped()); } template , int> = 0> - _NODISCARD constexpr move_iterator<_Unwrapped_t<_Iter2>> _Unwrapped() && noexcept( - noexcept(static_cast>>(_STD move(_Current)._Unwrapped()))) { + _NODISCARD constexpr move_iterator<_Unwrapped_t<_Iter2>> _Unwrapped() && { return static_cast>>(_STD move(_Current)._Unwrapped()); } From aa763dce94c5321c83e387c515e99ff4266b4568 Mon Sep 17 00:00:00 2001 From: Nicole Mazzuca Date: Fri, 12 Aug 2022 13:24:01 -0700 Subject: [PATCH 08/10] Casey CRs (hopefully) --- stl/inc/xutility | 63 +++++++++++++++++++----------------------------- 1 file changed, 25 insertions(+), 38 deletions(-) diff --git a/stl/inc/xutility b/stl/inc/xutility index f57e4648252..729834bf5ce 100644 --- a/stl/inc/xutility +++ b/stl/inc/xutility @@ -1213,10 +1213,10 @@ _NODISCARD _CONSTEXPR17 _BidIt prev(_BidIt _First, _Iter_diff_t<_BidIt> _Off = 1 } template >> -_INLINE_VAR constexpr bool _Is_nothrow_operator_arrow = noexcept( +_INLINE_VAR constexpr bool _Has_nothrow_operator_arrow = noexcept( _Implicitly_convert_to<_Pointer>(_STD declval<_Iter>())); template -_INLINE_VAR constexpr bool _Is_nothrow_operator_arrow<_Iter, _Pointer, false> = noexcept( +_INLINE_VAR constexpr bool _Has_nothrow_operator_arrow<_Iter, _Pointer, false> = noexcept( _Implicitly_convert_to<_Pointer>(_STD declval<_Iter>().operator->())); template @@ -1271,31 +1271,19 @@ public: return current; } - _NODISCARD _CONSTEXPR17 reference operator*() const noexcept(is_nothrow_copy_constructible_v<_BidIt>&& noexcept( - _Implicitly_convert_to(*--(_STD declval<_BidIt&>())))) /* strengthened */ { + _NODISCARD _CONSTEXPR17 reference operator*() const + noexcept(is_nothrow_copy_constructible_v<_BidIt>&& noexcept(*--(_STD declval<_BidIt&>()))) /* strengthened */ { _BidIt _Tmp = current; return *--_Tmp; } -#ifdef __cpp_lib_concepts - // clang-format off - _NODISCARD constexpr pointer operator->() const noexcept(is_nothrow_copy_constructible_v<_BidIt>&& noexcept( - --(_STD declval<_BidIt&>())) && _Is_nothrow_operator_arrow) /* strengthened */ - requires (is_pointer_v<_BidIt> || requires(const _BidIt __i) { __i.operator->(); }) - { - _BidIt _Tmp = current; - --_Tmp; - if constexpr (is_pointer_v<_BidIt>) { - return _Tmp; - } else { - return _Tmp.operator->(); - } - } - // clang-format on -#else // ^^^ __cpp_lib_concepts / !__cpp_lib_concepts vvv _NODISCARD _CONSTEXPR17 pointer operator->() const noexcept(is_nothrow_copy_constructible_v<_BidIt>&& noexcept(--(_STD declval<_BidIt&>())) - && _Is_nothrow_operator_arrow) /* strengthened */ { + && _Has_nothrow_operator_arrow) /* strengthened */ +#ifdef __cpp_lib_concepts + requires(is_pointer_v<_BidIt> || requires(const _BidIt __i) { __i.operator->(); }) +#endif + { _BidIt _Tmp = current; --_Tmp; if constexpr (is_pointer_v<_BidIt>) { @@ -1304,7 +1292,6 @@ public: return _Tmp.operator->(); } } -#endif // __cpp_lib_concepts _CONSTEXPR17 reverse_iterator& operator++() noexcept(noexcept(--current)) /* strengthened */ { --current; @@ -1353,7 +1340,7 @@ public: } _NODISCARD _CONSTEXPR17 reference operator[](const difference_type _Off) const - noexcept(noexcept(current[difference_type{}])) /* strengthened */ { + noexcept(noexcept(_Implicitly_convert_to(current[_Off]))) /* strengthened */ { return current[static_cast(-_Off - 1)]; } @@ -1657,8 +1644,7 @@ _NODISCARD constexpr ptrdiff_t ssize(const _Ty (&)[_Size]) noexcept { #endif // _HAS_CXX20 template -_NODISCARD constexpr auto empty(const _Container& _Cont) noexcept( - noexcept(_Fake_decay_copy(_Cont.empty()))) /* strengthened */ +_NODISCARD constexpr auto empty(const _Container& _Cont) noexcept(noexcept(_Cont.empty())) /* strengthened */ -> decltype(_Cont.empty()) { return _Cont.empty(); } @@ -1674,14 +1660,13 @@ _NODISCARD constexpr bool empty(initializer_list<_Elem> _Ilist) noexcept { } template -_NODISCARD constexpr auto data(_Container& _Cont) noexcept(noexcept(_Fake_decay_copy(_Cont.data()))) /* strengthened */ +_NODISCARD constexpr auto data(_Container& _Cont) noexcept(noexcept(_Cont.data())) /* strengthened */ -> decltype(_Cont.data()) { return _Cont.data(); } template -_NODISCARD constexpr auto data(const _Container& _Cont) noexcept( - noexcept(_Fake_decay_copy(_Cont.data()))) /* strengthened */ +_NODISCARD constexpr auto data(const _Container& _Cont) noexcept(noexcept(_Cont.data())) /* strengthened */ -> decltype(_Cont.data()) { return _Cont.data(); } @@ -3355,11 +3340,12 @@ public: #ifdef __cpp_lib_concepts noexcept(noexcept(_RANGES iter_move(_Current))) /* strengthened */ { return _RANGES iter_move(_Current); + } #else // ^^^ __cpp_lib_concepts / !__cpp_lib_concepts vvv noexcept(noexcept(static_cast(*_Current))) /* strengthened */ { return static_cast(*_Current); -#endif // __cpp_lib_concepts } +#endif // __cpp_lib_concepts _CXX20_DEPRECATE_MOVE_ITERATOR_ARROW _NODISCARD _CONSTEXPR17 pointer operator->() const noexcept(is_nothrow_copy_constructible_v<_Iter>) /* strengthened */ { @@ -3372,7 +3358,7 @@ public: } _CONSTEXPR17 auto operator++(int) noexcept( - noexcept(++_Current) && is_nothrow_copy_constructible_v<_Iter>) /* strengthened */ { + is_nothrow_copy_constructible_v<_Iter>&& noexcept(++_Current)) /* strengthened */ { #ifdef __cpp_lib_concepts if constexpr (forward_iterator<_Iter>) { #endif // __cpp_lib_concepts @@ -3392,7 +3378,7 @@ public: } _CONSTEXPR17 move_iterator operator--(int) noexcept( - noexcept(--_Current) && is_nothrow_copy_constructible_v<_Iter>) /* strengthened */ { + is_nothrow_copy_constructible_v<_Iter>&& noexcept(--_Current)) /* strengthened */ { move_iterator _Tmp = *this; --_Current; return _Tmp; @@ -3515,7 +3501,7 @@ public: template , int> = 0> constexpr void _Seek_to(const move_iterator<_Src>& _It) noexcept(noexcept(_Current._Seek_to(_It._Get_current()))) { - _Current._Seek_to(_It.base()); + _Current._Seek_to(_It._Get_current()); } template , int> = 0> constexpr void _Seek_to(move_iterator<_Src>&& _It) noexcept( @@ -3527,7 +3513,7 @@ public: return _Current; } constexpr iterator_type&& _Get_current() && noexcept { - return static_cast(_Current); + return _STD move(_Current); } private: @@ -3535,8 +3521,9 @@ private: }; template -_NODISCARD _CONSTEXPR17 bool operator==(const move_iterator<_Iter1>& _Left, - const move_iterator<_Iter2>& _Right) noexcept(noexcept(_Left.base() == _Right.base())) /* strengthened */ +_NODISCARD _CONSTEXPR17 bool + operator==(const move_iterator<_Iter1>& _Left, const move_iterator<_Iter2>& _Right) noexcept( + noexcept(_Implicitly_convert_to(_Left.base() == _Right.base()))) /* strengthened */ #ifdef __cpp_lib_concepts // clang-format off requires requires { @@ -3579,7 +3566,7 @@ _NODISCARD _CONSTEXPR17 bool operator>(const move_iterator<_Iter1>& _Left, template _NODISCARD _CONSTEXPR17 bool operator<=(const move_iterator<_Iter1>& _Left, - const move_iterator<_Iter2>& _Right) noexcept(noexcept(!(_Right < _Left))) /* strengthened */ + const move_iterator<_Iter2>& _Right) noexcept(noexcept(_Right < _Left)) /* strengthened */ #ifdef __cpp_lib_concepts // clang-format off requires requires { _Right < _Left; } @@ -3589,7 +3576,7 @@ _NODISCARD _CONSTEXPR17 bool operator<=(const move_iterator<_Iter1>& _Left, template _NODISCARD _CONSTEXPR17 bool operator>=(const move_iterator<_Iter1>& _Left, - const move_iterator<_Iter2>& _Right) noexcept(noexcept(!(_Left < _Right))) /* strengthened */ + const move_iterator<_Iter2>& _Right) noexcept(noexcept(_Left < _Right)) /* strengthened */ #ifdef __cpp_lib_concepts // clang-format off requires requires { _Left < _Right; } @@ -3627,7 +3614,7 @@ _NODISCARD _CONSTEXPR17 move_iterator<_Iter> template _NODISCARD _CONSTEXPR17 move_iterator<_Iter> make_move_iterator(_Iter _It) noexcept( - is_nothrow_move_constructible_v<_Iter>) /* strengthened */ { // make move_iterator from iterator + is_nothrow_move_constructible_v<_Iter>) /* strengthened */ { return move_iterator<_Iter>(_STD move(_It)); } From 1da506c038b7e8999a5f1142e4734a14dabc7f2e Mon Sep 17 00:00:00 2001 From: Casey Carter Date: Fri, 12 Aug 2022 16:56:02 -0700 Subject: [PATCH 09/10] Casey's final nits --- stl/inc/xutility | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/stl/inc/xutility b/stl/inc/xutility index 729834bf5ce..294c29a42d3 100644 --- a/stl/inc/xutility +++ b/stl/inc/xutility @@ -169,7 +169,6 @@ _NODISCARD _Ty _Fake_decay_copy(_Ty) noexcept; // (2) is well-formed if and only if E is implicitly convertible to T and T is destructible, and // (3) is non-throwing if and only if both conversion from decltype((E)) to T and destruction of T are non-throwing. - template struct _Get_first_parameter; @@ -1213,8 +1212,8 @@ _NODISCARD _CONSTEXPR17 _BidIt prev(_BidIt _First, _Iter_diff_t<_BidIt> _Off = 1 } template >> -_INLINE_VAR constexpr bool _Has_nothrow_operator_arrow = noexcept( - _Implicitly_convert_to<_Pointer>(_STD declval<_Iter>())); +_INLINE_VAR constexpr bool _Has_nothrow_operator_arrow = _Is_nothrow_convertible_v<_Iter, _Pointer>; + template _INLINE_VAR constexpr bool _Has_nothrow_operator_arrow<_Iter, _Pointer, false> = noexcept( _Implicitly_convert_to<_Pointer>(_STD declval<_Iter>().operator->())); @@ -1548,13 +1547,13 @@ _NODISCARD constexpr _Ty* end(_Ty (&_Array)[_Size]) noexcept { } template -_NODISCARD constexpr auto cbegin(const _Container& _Cont) noexcept(noexcept(_STD begin(_Cont))) /* strengthened */ +_NODISCARD constexpr auto cbegin(const _Container& _Cont) noexcept(noexcept(_STD begin(_Cont))) -> decltype(_STD begin(_Cont)) { return _STD begin(_Cont); } template -_NODISCARD constexpr auto cend(const _Container& _Cont) noexcept(noexcept(_STD end(_Cont))) /* strengthened */ +_NODISCARD constexpr auto cend(const _Container& _Cont) noexcept(noexcept(_STD end(_Cont))) -> decltype(_STD end(_Cont)) { return _STD end(_Cont); } @@ -3536,7 +3535,7 @@ _NODISCARD _CONSTEXPR17 bool #if !_HAS_CXX20 template _NODISCARD _CONSTEXPR17 bool operator!=(const move_iterator<_Iter1>& _Left, - const move_iterator<_Iter2>& _Right) noexcept(noexcept(!(_Left == _Right))) /* strengthened */ { + const move_iterator<_Iter2>& _Right) noexcept(noexcept(_Left == _Right)) /* strengthened */ { return !(_Left == _Right); } #endif // !_HAS_CXX20 From 62531a35cae70f0a179a501c73b1aa21907eff33 Mon Sep 17 00:00:00 2001 From: Nicole Mazzuca Date: Mon, 15 Aug 2022 08:35:12 -0700 Subject: [PATCH 10/10] Stephan CRs --- stl/inc/xutility | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/stl/inc/xutility b/stl/inc/xutility index 294c29a42d3..4d4372020e8 100644 --- a/stl/inc/xutility +++ b/stl/inc/xutility @@ -162,13 +162,6 @@ _NODISCARD _CONSTEXPR_BIT_CAST _To _Bit_cast(const _From& _Val) noexcept { #endif // ^^^ no workaround ^^^ } -template -_NODISCARD _Ty _Fake_decay_copy(_Ty) noexcept; -// _Fake_decay_copy(E): -// (1) has type T [decay_t if T is deduced], -// (2) is well-formed if and only if E is implicitly convertible to T and T is destructible, and -// (3) is non-throwing if and only if both conversion from decltype((E)) to T and destruction of T are non-throwing. - template struct _Get_first_parameter; @@ -1278,7 +1271,7 @@ public: _NODISCARD _CONSTEXPR17 pointer operator->() const noexcept(is_nothrow_copy_constructible_v<_BidIt>&& noexcept(--(_STD declval<_BidIt&>())) - && _Has_nothrow_operator_arrow) /* strengthened */ + && _Has_nothrow_operator_arrow<_BidIt&, pointer>) /* strengthened */ #ifdef __cpp_lib_concepts requires(is_pointer_v<_BidIt> || requires(const _BidIt __i) { __i.operator->(); }) #endif @@ -1385,7 +1378,7 @@ public: static constexpr bool _Unwrap_when_unverified = _Do_unwrap_when_unverified_v<_BidIt>; template , int> = 0> - constexpr void _Seek_to(const reverse_iterator<_Src>& _It) noexcept(noexcept(current._Seek_to(_It.base()))) { + constexpr void _Seek_to(const reverse_iterator<_Src>& _It) noexcept(noexcept(current._Seek_to(_It.current))) { current._Seek_to(_It.current); } @@ -1681,6 +1674,13 @@ _NODISCARD constexpr const _Elem* data(initializer_list<_Elem> _Ilist) noexcept } #ifdef __cpp_lib_concepts +template +_NODISCARD _Ty _Fake_decay_copy(_Ty) noexcept; +// _Fake_decay_copy(E): +// (1) has type T [decay_t if T is deduced], +// (2) is well-formed if and only if E is implicitly convertible to T and T is destructible, and +// (3) is non-throwing if and only if both conversion from decltype((E)) to T and destruction of T are non-throwing. + template concept _Not_same_as = !same_as, remove_cvref_t<_Ty2>>; @@ -3508,10 +3508,10 @@ public: _Current._Seek_to(_STD move(_It)._Get_current()); } - constexpr const iterator_type& _Get_current() const& noexcept { + _NODISCARD constexpr const iterator_type& _Get_current() const& noexcept { return _Current; } - constexpr iterator_type&& _Get_current() && noexcept { + _NODISCARD constexpr iterator_type&& _Get_current() && noexcept { return _STD move(_Current); }