From 2ffcdb66a7306e55dc24c6fac0be777bfa251f94 Mon Sep 17 00:00:00 2001 From: Michael Schellenberger Costa Date: Mon, 15 Feb 2021 22:11:38 +0100 Subject: [PATCH 01/21] Implement operator spaceship for container iterators --- stl/inc/array | 13 +++++ stl/inc/deque | 13 +++++ stl/inc/filesystem | 6 ++ stl/inc/forward_list | 6 ++ stl/inc/list | 4 ++ stl/inc/vector | 15 +++++ stl/inc/xtree | 4 ++ tests/std/tests/P1614R2_spaceship/test.cpp | 66 ++++++++++++++++++++++ 8 files changed, 127 insertions(+) diff --git a/stl/inc/array b/stl/inc/array index 23c892f3a15..3b2187a7987 100644 --- a/stl/inc/array +++ b/stl/inc/array @@ -111,6 +111,11 @@ public: return _Ptr == _Right._Ptr; } +#if _HAS_CXX20 + _NODISCARD constexpr strong_ordering operator<=>(const _Array_const_iterator& _Right) const noexcept { + return _Ptr <=> _Right._Ptr; + } +#else // ^^^ _HAS_CXX20 ^^^ / vvv !_HAS_CXX20 vvv _NODISCARD _CONSTEXPR17 bool operator!=(const _Array_const_iterator& _Right) const noexcept { return !(*this == _Right); } @@ -130,6 +135,7 @@ public: _NODISCARD _CONSTEXPR17 bool operator>=(const _Array_const_iterator& _Right) const noexcept { return !(*this < _Right); } +#endif // !_HAS_CXX20 using _Prevent_inheriting_unwrap = _Array_const_iterator; @@ -235,6 +241,12 @@ private: return _Idx == _Right._Idx; } +#if _HAS_CXX20 + _NODISCARD constexpr strong_ordering operator<=>(const _Array_const_iterator& _Right) const noexcept { + _Compat(_Right); + return _Idx <=> _Right._Idx; + } +#else // ^^^ _HAS_CXX ^^^ / vvv !_HAS_CXX20 vvv _NODISCARD _CONSTEXPR17 bool operator!=(const _Array_const_iterator& _Right) const noexcept { return !(*this == _Right); } @@ -255,6 +267,7 @@ private: _NODISCARD _CONSTEXPR17 bool operator>=(const _Array_const_iterator& _Right) const noexcept { return !(*this < _Right); } +#endif // !_HAS_CXX20 _CONSTEXPR17 void _Compat(const _Array_const_iterator& _Right) const noexcept { // test for compatible iterator pair _STL_VERIFY(_Ptr == _Right._Ptr, "array iterators incompatible"); diff --git a/stl/inc/deque b/stl/inc/deque index fe0b478bda0..334286fedd5 100644 --- a/stl/inc/deque +++ b/stl/inc/deque @@ -107,6 +107,11 @@ public: return _Myoff == _Right._Myoff; } +#if _HAS_CXX20 + _NODISCARD strong_ordering operator<=>(const _Deque_unchecked_const_iterator& _Right) const noexcept { + return _Myoff <=> _Right._Myoff; + } +#else // ^^^ _HAS_CXX20 ^^^ / vvv !_HAS_CXX20 vvv _NODISCARD bool operator!=(const _Deque_unchecked_const_iterator& _Right) const noexcept { return !(*this == _Right); } @@ -126,6 +131,7 @@ public: _NODISCARD bool operator>=(const _Deque_unchecked_const_iterator& _Right) const noexcept { return !(*this < _Right); } +#endif // !_HAS_CXX20 const _Container_base12* _Getcont() const noexcept { // get container pointer return _Mycont; @@ -345,6 +351,12 @@ public: return this->_Myoff == _Right._Myoff; } +#if _HAS_CXX20 + _NODISCARD constexpr strong_ordering operator<=>(const _Deque_const_iterator& _Right) const noexcept { + _Compat(_Right); + return this->_Myoff <=> _Right._Myoff; + } +#else // ^^^ _HAS_CXX20 ^^^ / vvv !_HAS_CXX20 vvv _NODISCARD bool operator!=(const _Deque_const_iterator& _Right) const noexcept { return !(*this == _Right); } @@ -365,6 +377,7 @@ public: _NODISCARD bool operator>=(const _Deque_const_iterator& _Right) const noexcept { return !(*this < _Right); } +#endif // !_HAS_CXX20 void _Compat(const _Deque_const_iterator& _Right) const noexcept { // test for compatible iterator pair #if _ITERATOR_DEBUG_LEVEL == 0 diff --git a/stl/inc/filesystem b/stl/inc/filesystem index 075a08b1587..05341d65c4c 100644 --- a/stl/inc/filesystem +++ b/stl/inc/filesystem @@ -1603,9 +1603,11 @@ namespace filesystem { return _Lhs._Position == _Rhs._Position; } +#if !_HAS_CXX20 _NODISCARD friend bool operator!=(const _Path_iterator& _Lhs, const _Path_iterator& _Rhs) { return _Lhs._Position != _Rhs._Position; } +#endif // !_HAS_CXX20 #if _ITERATOR_DEBUG_LEVEL != 0 friend void _Verify_range(const _Path_iterator& _Lhs, const _Path_iterator& _Rhs) { @@ -2728,9 +2730,11 @@ namespace filesystem { return _Impl == _Rhs._Impl; } +#if !_HAS_CXX20 _NODISCARD bool operator!=(const directory_iterator& _Rhs) const noexcept /* strengthened */ { return _Impl != _Rhs._Impl; } +#endif // !_HAS_CXX20 _Directory_entry_proxy operator++(int) { _Directory_entry_proxy _Proxy(**this); @@ -2977,9 +2981,11 @@ namespace filesystem { return _Impl == _Rhs._Impl; } +#if !_HAS_CXX20 _NODISCARD bool operator!=(const recursive_directory_iterator& _Rhs) const noexcept { return _Impl != _Rhs._Impl; } +#endif // !_HAS_CXX20 _Directory_entry_proxy operator++(int) { _Directory_entry_proxy _Proxy(**this); diff --git a/stl/inc/forward_list b/stl/inc/forward_list index 935574d1004..468f6e9c139 100644 --- a/stl/inc/forward_list +++ b/stl/inc/forward_list @@ -63,17 +63,21 @@ public: return _Ptr == _Right._Ptr; } +#if !_HAS_CXX20 _NODISCARD bool operator!=(const _Flist_unchecked_const_iterator& _Right) const noexcept { return !(*this == _Right); } +#endif // !_HAS_CXX20 _NODISCARD bool operator==(_Default_sentinel) const noexcept { return _Ptr == nullptr; } +#if !_HAS_CXX20 _NODISCARD bool operator!=(_Default_sentinel) const noexcept { return _Ptr != nullptr; } +#endif // !_HAS_CXX20 _Nodeptr _Ptr; // pointer to node }; @@ -161,9 +165,11 @@ public: return this->_Ptr == _Right._Ptr; } +#if !_HAS_CXX20 _NODISCARD bool operator!=(const _Flist_const_iterator& _Right) const noexcept { return !(*this == _Right); } +#endif // !_HAS_CXX20 #if _ITERATOR_DEBUG_LEVEL == 2 friend void _Verify_range(const _Flist_const_iterator& _First, const _Flist_const_iterator& _Last) noexcept { diff --git a/stl/inc/list b/stl/inc/list index c8d81b1897e..812c81f6c61 100644 --- a/stl/inc/list +++ b/stl/inc/list @@ -74,9 +74,11 @@ public: return _Ptr == _Right._Ptr; } +#if !_HAS_CXX20 _NODISCARD bool operator!=(const _List_unchecked_const_iterator& _Right) const noexcept { return !(*this == _Right); } +#endif // !_HAS_CXX20 _Nodeptr _Ptr; // pointer to node }; @@ -199,9 +201,11 @@ public: return this->_Ptr == _Right._Ptr; } +#if !_HAS_CXX20 _NODISCARD bool operator!=(const _List_const_iterator& _Right) const noexcept { return !(*this == _Right); } +#endif // !_HAS_CXX20 #if _ITERATOR_DEBUG_LEVEL == 2 friend void _Verify_range(const _List_const_iterator& _First, const _List_const_iterator& _Last) noexcept { diff --git a/stl/inc/vector b/stl/inc/vector index 252601aae62..a4d8a249991 100644 --- a/stl/inc/vector +++ b/stl/inc/vector @@ -149,6 +149,11 @@ public: return _Ptr == _Right._Ptr; } +#if _HAS_CXX20 + _NODISCARD strong_ordering operator<=>(const _Vector_const_iterator& _Right) const noexcept { + return _Ptr <=> _Right._Ptr; + } +#else // ^^^ _HAS_CXX20 ^^^ / vvv !_HAS_CXX20 vvv _NODISCARD bool operator!=(const _Vector_const_iterator& _Right) const noexcept { return !(*this == _Right); } @@ -169,6 +174,7 @@ public: _NODISCARD bool operator>=(const _Vector_const_iterator& _Right) const noexcept { return !(*this < _Right); } +#endif // !_HAS_CXX20 void _Compat(const _Vector_const_iterator& _Right) const noexcept { // test for compatible iterator pair #if _ITERATOR_DEBUG_LEVEL == 0 @@ -2124,6 +2130,14 @@ public: return this->_Myptr == _Right._Myptr && this->_Myoff == _Right._Myoff; } +#if _HAS_CXX20 + _NODISCARD strong_ordering operator<=>(const _Vb_const_iterator& _Right) const noexcept { + if (const auto _CmpResult = this->_Myptr <=> _Right._Myptr; _CmpResult != 0) { + return _CmpResult; + } + return this->_Myoff <=> _Right._Myoff; + } +#else // ^^^ _HAS_CXX20 ^^^ / vvv !_HAS_CXX20 vvv _NODISCARD bool operator!=(const _Vb_const_iterator& _Right) const noexcept { return !(*this == _Right); } @@ -2144,6 +2158,7 @@ public: _NODISCARD bool operator>=(const _Vb_const_iterator& _Right) const noexcept { return !(*this < _Right); } +#endif // !_HAS_CXX20 void _Compat(const _Vb_const_iterator& _Right) const noexcept { // test for compatible iterator pair #if _ITERATOR_DEBUG_LEVEL == 0 diff --git a/stl/inc/xtree b/stl/inc/xtree index aba7f46baee..48ce80c3967 100644 --- a/stl/inc/xtree +++ b/stl/inc/xtree @@ -98,18 +98,22 @@ public: return _Ptr == _Right._Ptr; } +#if !_HAS_CXX20 _NODISCARD bool operator!=(const _Tree_unchecked_const_iterator& _Right) const noexcept { return !(*this == _Right); } +#endif // !_HAS_CXX20 _NODISCARD bool operator==(_Default_sentinel) const noexcept { return !!_Ptr->_Isnil; // TRANSITION, avoid warning C4800: // "Implicit conversion from 'char' to bool. Possible information loss" (/Wall) } +#if !_HAS_CXX20 _NODISCARD bool operator!=(_Default_sentinel) const noexcept { return !_Ptr->_Isnil; } +#endif // !_HAS_CXX20 _Nodeptr _Ptr; // pointer to node }; diff --git a/tests/std/tests/P1614R2_spaceship/test.cpp b/tests/std/tests/P1614R2_spaceship/test.cpp index 1775d4b97f3..1f8fe56c649 100644 --- a/tests/std/tests/P1614R2_spaceship/test.cpp +++ b/tests/std/tests/P1614R2_spaceship/test.cpp @@ -178,6 +178,27 @@ void unordered_containers_test( assert(something != different); } +template +void ordered_iterator_test(const Iter& smaller, const Iter& smaller_equal, const Iter& larger, + const ConstIter& const_smaller, const ConstIter& const_smaller_equal, const ConstIter& const_larger) { + spaceship_test(smaller, smaller_equal, larger); + spaceship_test(const_smaller, const_smaller_equal, const_larger); + spaceship_test(const_smaller, smaller_equal, larger); +} + +template +void unordered_iterator_test(const Iter& something, const Iter& something_equal, const Iter& different, + const ConstIter& const_something, const ConstIter& const_something_equal, const ConstIter& const_different) { + assert(something == something_equal); + assert(something != different); + + assert(const_something == const_something_equal); + assert(const_something != const_different); + + assert(something == const_something_equal); + assert(something != const_different); +} + template void diagnostics_test() { dummy_diagnostic c_mem[2]; @@ -218,6 +239,15 @@ void ordering_test_cases() { static_assert((a1 <=> a1) == 0); static_assert((a2 <=> a0) < 0); static_assert((a0 <=> a2) > 0); + + constexpr auto b1 = a1.begin(); + constexpr auto b2 = a1.begin(); + constexpr auto e1 = a1.end(); + + static_assert((b1 <=> b1) == 0); + static_assert((b1 <=> b2) == 0); + static_assert((b1 <=> e1) < 0); + static_assert((e1 <=> b1) > 0); } { // constexpr array SynthOrdered constexpr std::array a = {10, 20, 30}; @@ -226,67 +256,87 @@ void ordering_test_cases() { static_assert((a <=> a) == 0); static_assert((a <=> b) < 0); static_assert((b <=> a) > 0); + + constexpr auto b1 = a.begin(); + constexpr auto b2 = a.begin(); + constexpr auto e1 = a.end(); + + static_assert((b1 <=> b1) == 0); + static_assert((b1 <=> b2) == 0); + static_assert((b1 <=> e1) < 0); + static_assert((e1 <=> b1) > 0); } { // array std::array a1 = {100, 100, 100}; std::array a2 = {100, 100, 100}; std::array b1 = {200, 200}; ordered_containers_test(a1, a2, b1); + ordered_iterator_test(a1.begin(), a1.begin(), a1.end(), a1.cbegin(), a1.cbegin(), a1.cend()); } { // array SynthOrdered std::array a = {10, 20, 30}; std::array b = {10, 20, 40}; ordered_containers_test(a, a, b); + ordered_iterator_test(a.begin(), a.begin(), a.end(), a.cbegin(), a.cbegin(), a.cend()); } { // deque std::deque a1(3, 100); std::deque a2(3, 100); std::deque b1(2, 200); ordered_containers_test(a1, a2, b1); + ordered_iterator_test(a1.begin(), a1.begin(), a1.end(), a1.cbegin(), a1.cbegin(), a1.cend()); } { // deque SynthOrdered std::deque a = {10, 20, 30}; std::deque b = {10, 20, 40}; ordered_containers_test(a, a, b); + ordered_iterator_test(a.begin(), a.begin(), a.end(), a.cbegin(), a.cbegin(), a.cend()); } { // list std::list a1(3, 100); std::list a2(3, 100); std::list b1(2, 200); ordered_containers_test(a1, a2, b1); + unordered_iterator_test(a1.begin(), a1.begin(), a1.end(), a1.cbegin(), a1.cbegin(), a1.cend()); } { // list SynthOrdered std::list a = {10, 20, 30}; std::list b = {10, 20, 40}; ordered_containers_test(a, a, b); + unordered_iterator_test(a.begin(), a.begin(), a.end(), a.cbegin(), a.cbegin(), a.cend()); } { // vector std::vector a1(3, 100); std::vector a2(3, 100); std::vector b1(2, 200); ordered_containers_test(a1, a2, b1); + ordered_iterator_test(a1.begin(), a1.begin(), a1.end(), a1.cbegin(), a1.cbegin(), a1.cend()); } { // vector SynthOrdered std::vector a = {10, 20, 30}; std::vector b = {10, 20, 40}; ordered_containers_test(a, a, b); + ordered_iterator_test(a.begin(), a.begin(), a.end(), a.cbegin(), a.cbegin(), a.cend()); } { // vector std::vector c1 = {false, true, false}; std::vector c2 = {false, true, false}; std::vector d1 = {true, false}; ordered_containers_test(c1, c2, d1); + ordered_iterator_test(c1.begin(), c1.begin(), c1.end(), c1.cbegin(), c1.cbegin(), c1.cend()); } { // forward_list std::forward_list a1(3, 100); std::forward_list a2(3, 100); std::forward_list b1(2, 200); ordered_containers_test(a1, a2, b1); + unordered_iterator_test(a1.begin(), a1.begin(), a1.end(), a1.cbegin(), a1.cbegin(), a1.cend()); } { // forward_list SynthOrdered std::forward_list a = {10, 20, 30}; std::forward_list b = {10, 20, 40}; ordered_containers_test(a, a, b); + unordered_iterator_test(a.begin(), a.begin(), a.end(), a.cbegin(), a.cbegin(), a.cend()); } { // map std::map a1; @@ -299,22 +349,26 @@ void ordering_test_cases() { b1["zoe"] = 3; b1["koala"] = 4; ordered_containers_test(a1, a2, b1); + unordered_iterator_test(a1.begin(), a1.begin(), a1.end(), a1.cbegin(), a1.cbegin(), a1.cend()); } { // map SynthOrdered std::map a = {{10, 'z'}, {20, 'z'}, {30, 'z'}}; std::map b = {{10, 'z'}, {20, 'z'}, {40, 'z'}}; ordered_containers_test(a, a, b); + unordered_iterator_test(a.begin(), a.begin(), a.end(), a.cbegin(), a.cbegin(), a.cend()); } { // multimap std::multimap a1 = {{'a', 1}, {'b', 2}, {'a', 3}}; std::multimap a2 = {{'a', 1}, {'a', 3}, {'b', 2}}; std::multimap b1 = {{'z', 4}, {'y', 90}, {'z', 12}}; ordered_containers_test(a1, a2, b1); + unordered_iterator_test(a1.begin(), a1.begin(), a1.end(), a1.cbegin(), a1.cbegin(), a1.cend()); } { // multimap SynthOrdered std::multimap a = {{10, 'z'}, {20, 'z'}, {30, 'z'}}; std::multimap b = {{10, 'z'}, {20, 'z'}, {40, 'z'}}; ordered_containers_test(a, a, b); + unordered_iterator_test(a.begin(), a.begin(), a.end(), a.cbegin(), a.cbegin(), a.cend()); } { // set std::set a1; @@ -329,11 +383,13 @@ void ordering_test_cases() { b1.insert(30); b1.insert(40); ordered_containers_test(a1, a2, b1); + unordered_iterator_test(a1.begin(), a1.begin(), a1.end(), a1.cbegin(), a1.cbegin(), a1.cend()); } { // set SynthOrdered std::set a = {10, 20, 30}; std::set b = {10, 20, 40}; ordered_containers_test(a, a, b); + unordered_iterator_test(a.begin(), a.begin(), a.end(), a.cbegin(), a.cbegin(), a.cend()); } { // multiset std::multiset a1; @@ -351,11 +407,13 @@ void ordering_test_cases() { b1.insert(40); b1.insert(40); ordered_containers_test(a1, a2, b1); + unordered_iterator_test(a1.begin(), a1.begin(), a1.end(), a1.cbegin(), a1.cbegin(), a1.cend()); } { // multiset SynthOrdered std::multiset a = {10, 20, 30}; std::multiset b = {10, 20, 40}; ordered_containers_test(a, a, b); + unordered_iterator_test(a.begin(), a.begin(), a.end(), a.cbegin(), a.cbegin(), a.cend()); } { // unordered_map using stringmap = std::unordered_map; @@ -363,6 +421,7 @@ void ordering_test_cases() { stringmap b = {{"dog", "poodle"}, {"bear", "grizzly"}, {"cat", "tabby"}}; stringmap c = {{"cat", "siamese"}, {"dog", "lab"}, {"bear", "polar"}}; unordered_containers_test(a, b, c); + unordered_iterator_test(a.begin(), a.begin(), a.end(), a.cbegin(), a.cbegin(), a.cend()); } { // unordered_multimap using stringmap = std::unordered_multimap; @@ -370,18 +429,21 @@ void ordering_test_cases() { stringmap b = {{"dog", "poodle"}, {"cat", "siamese"}, {"cat", "tabby"}, {"dog", "poodle"}}; stringmap c = {{"cat", "siamese"}, {"dog", "lab"}, {"bear", "polar"}}; unordered_containers_test(a, b, c); + unordered_iterator_test(a.begin(), a.begin(), a.end(), a.cbegin(), a.cbegin(), a.cend()); } { // unordered_set std::unordered_set a = {"cat", "dog", "bear"}; std::unordered_set b = {"bear", "cat", "dog"}; std::unordered_set c = {"mouse", "cat", "bear", "dog"}; unordered_containers_test(a, b, c); + unordered_iterator_test(a.begin(), a.begin(), a.end(), a.cbegin(), a.cbegin(), a.cend()); } { // unordered_multiset std::unordered_multiset a = {"cat", "dog", "cat"}; std::unordered_multiset b = {"cat", "cat", "dog"}; std::unordered_multiset c = {"mouse", "cat", "bear", "dog"}; unordered_containers_test(a, b, c); + unordered_iterator_test(a.begin(), a.begin(), a.end(), a.cbegin(), a.cbegin(), a.cend()); } { // queue std::deque deq1(3, 100); @@ -390,6 +452,7 @@ void ordering_test_cases() { std::queue b(deq1); std::queue c(deq2); ordered_containers_test(a, b, c); + ordered_iterator_test(deq1.begin(), deq1.begin(), deq1.end(), deq1.cbegin(), deq1.cbegin(), deq1.cend()); } { // queue SynthOrdered std::queue a{std::deque{10, 20, 30}}; @@ -518,6 +581,9 @@ void ordering_test_cases() { const std::filesystem::path p3{R"(a/b/d)"}; spaceship_test(p1, p2, p3); + spaceship_test(p1, p2, p3); + spaceship_test(p1, p2, p3); + unordered_containers_test(p1.begin(), p1.begin(), p1.end()); } { // filesystem::file_status std::filesystem::file_status s1; From 99999c6623f808e75da012482d9bf57b3552a370 Mon Sep 17 00:00:00 2001 From: Michael Schellenberger Costa Date: Tue, 16 Feb 2021 09:06:39 +0100 Subject: [PATCH 02/21] Fancy that --- stl/inc/vector | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stl/inc/vector b/stl/inc/vector index a4d8a249991..9c22af93832 100644 --- a/stl/inc/vector +++ b/stl/inc/vector @@ -151,7 +151,7 @@ public: #if _HAS_CXX20 _NODISCARD strong_ordering operator<=>(const _Vector_const_iterator& _Right) const noexcept { - return _Ptr <=> _Right._Ptr; + return _Unwrapped() <=> _Right._Unwrapped(); } #else // ^^^ _HAS_CXX20 ^^^ / vvv !_HAS_CXX20 vvv _NODISCARD bool operator!=(const _Vector_const_iterator& _Right) const noexcept { From fe09d088b9657c15480051388ba58ba7d2ae872d Mon Sep 17 00:00:00 2001 From: Michael Schellenberger Costa Date: Tue, 16 Feb 2021 20:13:17 +0100 Subject: [PATCH 03/21] No address of local variables --- tests/std/tests/P1614R2_spaceship/test.cpp | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/tests/std/tests/P1614R2_spaceship/test.cpp b/tests/std/tests/P1614R2_spaceship/test.cpp index 1f8fe56c649..f7bb5cc2b45 100644 --- a/tests/std/tests/P1614R2_spaceship/test.cpp +++ b/tests/std/tests/P1614R2_spaceship/test.cpp @@ -239,15 +239,6 @@ void ordering_test_cases() { static_assert((a1 <=> a1) == 0); static_assert((a2 <=> a0) < 0); static_assert((a0 <=> a2) > 0); - - constexpr auto b1 = a1.begin(); - constexpr auto b2 = a1.begin(); - constexpr auto e1 = a1.end(); - - static_assert((b1 <=> b1) == 0); - static_assert((b1 <=> b2) == 0); - static_assert((b1 <=> e1) < 0); - static_assert((e1 <=> b1) > 0); } { // constexpr array SynthOrdered constexpr std::array a = {10, 20, 30}; @@ -256,15 +247,6 @@ void ordering_test_cases() { static_assert((a <=> a) == 0); static_assert((a <=> b) < 0); static_assert((b <=> a) > 0); - - constexpr auto b1 = a.begin(); - constexpr auto b2 = a.begin(); - constexpr auto e1 = a.end(); - - static_assert((b1 <=> b1) == 0); - static_assert((b1 <=> b2) == 0); - static_assert((b1 <=> e1) < 0); - static_assert((e1 <=> b1) > 0); } { // array std::array a1 = {100, 100, 100}; @@ -580,8 +562,6 @@ void ordering_test_cases() { const std::filesystem::path p2{LR"(a\b\c)"}; const std::filesystem::path p3{R"(a/b/d)"}; - spaceship_test(p1, p2, p3); - spaceship_test(p1, p2, p3); spaceship_test(p1, p2, p3); unordered_containers_test(p1.begin(), p1.begin(), p1.end()); } From 700a941f36cae1ee565c0ed3d29d3abc74df6401 Mon Sep 17 00:00:00 2001 From: Michael Schellenberger Costa Date: Tue, 16 Feb 2021 21:10:55 +0100 Subject: [PATCH 04/21] Forgot to check for compatability --- stl/inc/vector | 2 ++ 1 file changed, 2 insertions(+) diff --git a/stl/inc/vector b/stl/inc/vector index 9c22af93832..58dc3b7d291 100644 --- a/stl/inc/vector +++ b/stl/inc/vector @@ -151,6 +151,7 @@ public: #if _HAS_CXX20 _NODISCARD strong_ordering operator<=>(const _Vector_const_iterator& _Right) const noexcept { + _Compat(_Right); return _Unwrapped() <=> _Right._Unwrapped(); } #else // ^^^ _HAS_CXX20 ^^^ / vvv !_HAS_CXX20 vvv @@ -2132,6 +2133,7 @@ public: #if _HAS_CXX20 _NODISCARD strong_ordering operator<=>(const _Vb_const_iterator& _Right) const noexcept { + _Compat(_Right); if (const auto _CmpResult = this->_Myptr <=> _Right._Myptr; _CmpResult != 0) { return _CmpResult; } From 47235f9c678933b61146f9d3485d8546d89c191a Mon Sep 17 00:00:00 2001 From: Michael Schellenberger Costa Date: Tue, 16 Feb 2021 21:26:49 +0100 Subject: [PATCH 05/21] Debug performance! --- stl/inc/vector | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stl/inc/vector b/stl/inc/vector index 58dc3b7d291..a8d02238276 100644 --- a/stl/inc/vector +++ b/stl/inc/vector @@ -152,7 +152,7 @@ public: #if _HAS_CXX20 _NODISCARD strong_ordering operator<=>(const _Vector_const_iterator& _Right) const noexcept { _Compat(_Right); - return _Unwrapped() <=> _Right._Unwrapped(); + return _Unfancy(_Ptr) <=> _Unfancy(_Right._Ptr); } #else // ^^^ _HAS_CXX20 ^^^ / vvv !_HAS_CXX20 vvv _NODISCARD bool operator!=(const _Vector_const_iterator& _Right) const noexcept { From 7e4687061aeb177fbec635b1125ed0ca9e4f77cc Mon Sep 17 00:00:00 2001 From: Michael Schellenberger Costa Date: Tue, 16 Feb 2021 21:32:31 +0100 Subject: [PATCH 06/21] Add spaceship for string iterators --- stl/inc/xstring | 19 +++++++++++++++++++ tests/std/tests/P1614R2_spaceship/test.cpp | 15 +++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/stl/inc/xstring b/stl/inc/xstring index 80355987c2c..124bef30e17 100644 --- a/stl/inc/xstring +++ b/stl/inc/xstring @@ -1115,6 +1115,17 @@ public: #endif // _ITERATOR_DEBUG_LEVEL } +#if _HAS_CXX20 + _NODISCARD strong_ordering operator<=>(const _String_view_iterator& _Right) const noexcept { +#if _ITERATOR_DEBUG_LEVEL >= 1 + _STL_VERIFY(_Mydata == _Right._Mydata && _Mysize == _Right._Mysize, + "cannot compare incompatible string_view iterators for equality"); + return _Myoff <=> _Right._Myoff; +#else // ^^^ _ITERATOR_DEBUG_LEVEL >= 1 ^^^ // vvv _ITERATOR_DEBUG_LEVEL == 0 vvv + return _Myptr <=> _Right._Myptr; +#endif // _ITERATOR_DEBUG_LEVEL + } +#else // ^^^ _HAS_CXX20 ^^^ / vvv !_HAS_CXX20 vvv _NODISCARD constexpr bool operator!=(const _String_view_iterator& _Right) const noexcept { return !(*this == _Right); } @@ -1140,6 +1151,7 @@ public: _NODISCARD constexpr bool operator>=(const _String_view_iterator& _Right) const noexcept { return !(*this < _Right); } +#endif // !_HAS_CXX20 #if _ITERATOR_DEBUG_LEVEL >= 1 friend constexpr void _Verify_range(const _String_view_iterator& _First, const _String_view_iterator& _Last) { @@ -1968,6 +1980,12 @@ public: return _Ptr == _Right._Ptr; } +#if _HAS_CXX20 + _NODISCARD strong_ordering operator<=>(const _String_const_iterator& _Right) const noexcept { + _Compat(_Right); + return _Unfancy(_Ptr) <=> _Unfancy(_Right._Ptr); + } +#else // ^^^ _HAS_CXX20 ^^^ / vvv !_HAS_CXX20 vvv _NODISCARD bool operator!=(const _String_const_iterator& _Right) const noexcept { return !(*this == _Right); } @@ -1988,6 +2006,7 @@ public: _NODISCARD bool operator>=(const _String_const_iterator& _Right) const noexcept { return !(*this < _Right); } +#endif // !_HAS_CXX20 void _Compat(const _String_const_iterator& _Right) const noexcept { // test for compatible iterator pair #if _ITERATOR_DEBUG_LEVEL >= 1 diff --git a/tests/std/tests/P1614R2_spaceship/test.cpp b/tests/std/tests/P1614R2_spaceship/test.cpp index f7bb5cc2b45..0b411b8c325 100644 --- a/tests/std/tests/P1614R2_spaceship/test.cpp +++ b/tests/std/tests/P1614R2_spaceship/test.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -294,6 +295,20 @@ void ordering_test_cases() { ordered_containers_test(a1, a2, b1); ordered_iterator_test(a1.begin(), a1.begin(), a1.end(), a1.cbegin(), a1.cbegin(), a1.cend()); } + { // string + std::string a1 = "aaa"; + std::string a2 = "aaa"; + std::string b1 = "bb"; + // ordered_containers_test(a1, a2, b1); + ordered_iterator_test(a1.begin(), a1.begin(), a1.end(), a1.cbegin(), a1.cbegin(), a1.cend()); + } + { // string_view + std::string_view a1 = "aaa"; + std::string_view a2 = "aaa"; + std::string_view b1 = "bb"; + // ordered_containers_test(a1, a2, b1); + ordered_iterator_test(a1.begin(), a1.begin(), a1.end(), a1.cbegin(), a1.cbegin(), a1.cend()); + } { // vector SynthOrdered std::vector a = {10, 20, 30}; std::vector b = {10, 20, 40}; From 0c55524bb49658db3b1b2c53491fa7819e15c4d5 Mon Sep 17 00:00:00 2001 From: Casey Carter Date: Tue, 16 Feb 2021 12:52:45 -0800 Subject: [PATCH 07/21] Apply suggestions from code review `TRANSITION` the commented-out code. --- tests/std/tests/P1614R2_spaceship/test.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/std/tests/P1614R2_spaceship/test.cpp b/tests/std/tests/P1614R2_spaceship/test.cpp index 0b411b8c325..f5a8d79edda 100644 --- a/tests/std/tests/P1614R2_spaceship/test.cpp +++ b/tests/std/tests/P1614R2_spaceship/test.cpp @@ -299,14 +299,14 @@ void ordering_test_cases() { std::string a1 = "aaa"; std::string a2 = "aaa"; std::string b1 = "bb"; - // ordered_containers_test(a1, a2, b1); + // ordered_containers_test(a1, a2, b1); // TRANSITION, GH-1635 ordered_iterator_test(a1.begin(), a1.begin(), a1.end(), a1.cbegin(), a1.cbegin(), a1.cend()); } { // string_view std::string_view a1 = "aaa"; std::string_view a2 = "aaa"; std::string_view b1 = "bb"; - // ordered_containers_test(a1, a2, b1); + // ordered_containers_test(a1, a2, b1); // TRANSITION, GH-1635 ordered_iterator_test(a1.begin(), a1.begin(), a1.end(), a1.cbegin(), a1.cbegin(), a1.cend()); } { // vector SynthOrdered From 61656124a2521b0ae13c5c63074bf08907304553 Mon Sep 17 00:00:00 2001 From: Michael Schellenberger Costa Date: Tue, 16 Feb 2021 22:36:34 +0100 Subject: [PATCH 08/21] Forgot about constexpr --- stl/inc/xstring | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stl/inc/xstring b/stl/inc/xstring index 124bef30e17..df919b294f0 100644 --- a/stl/inc/xstring +++ b/stl/inc/xstring @@ -1116,7 +1116,7 @@ public: } #if _HAS_CXX20 - _NODISCARD strong_ordering operator<=>(const _String_view_iterator& _Right) const noexcept { + _NODISCARD constexpr strong_ordering operator<=>(const _String_view_iterator& _Right) const noexcept { #if _ITERATOR_DEBUG_LEVEL >= 1 _STL_VERIFY(_Mydata == _Right._Mydata && _Mysize == _Right._Mysize, "cannot compare incompatible string_view iterators for equality"); From cf706cb4ddbeaaf17b4a1457f9720f6fd6266581 Mon Sep 17 00:00:00 2001 From: Casey Carter Date: Tue, 16 Feb 2021 13:44:26 -0800 Subject: [PATCH 09/21] Apply suggestions from code review Cleanup unused variable warnings. --- tests/std/tests/P1614R2_spaceship/test.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tests/std/tests/P1614R2_spaceship/test.cpp b/tests/std/tests/P1614R2_spaceship/test.cpp index f5a8d79edda..4e5bf7958b0 100644 --- a/tests/std/tests/P1614R2_spaceship/test.cpp +++ b/tests/std/tests/P1614R2_spaceship/test.cpp @@ -297,16 +297,20 @@ void ordering_test_cases() { } { // string std::string a1 = "aaa"; +#if 0 // TRANSITION, GH-1635 std::string a2 = "aaa"; std::string b1 = "bb"; - // ordered_containers_test(a1, a2, b1); // TRANSITION, GH-1635 + ordered_containers_test(a1, a2, b1); +#endif // TRANSITION, GH-1635 ordered_iterator_test(a1.begin(), a1.begin(), a1.end(), a1.cbegin(), a1.cbegin(), a1.cend()); } { // string_view std::string_view a1 = "aaa"; +#if 0 // TRANSITION, GH-1635 std::string_view a2 = "aaa"; std::string_view b1 = "bb"; - // ordered_containers_test(a1, a2, b1); // TRANSITION, GH-1635 + ordered_containers_test(a1, a2, b1); +#endif // TRANSITION, GH-1635 ordered_iterator_test(a1.begin(), a1.begin(), a1.end(), a1.cbegin(), a1.cbegin(), a1.cend()); } { // vector SynthOrdered From a34a99c109921bae68bcc791566e3727a4529b7a Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Thu, 18 Feb 2021 18:27:02 -0800 Subject: [PATCH 10/21] Fix typo. --- stl/inc/array | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stl/inc/array b/stl/inc/array index 3b2187a7987..e0bcf371800 100644 --- a/stl/inc/array +++ b/stl/inc/array @@ -246,7 +246,7 @@ private: _Compat(_Right); return _Idx <=> _Right._Idx; } -#else // ^^^ _HAS_CXX ^^^ / vvv !_HAS_CXX20 vvv +#else // ^^^ _HAS_CXX20 ^^^ / vvv !_HAS_CXX20 vvv _NODISCARD _CONSTEXPR17 bool operator!=(const _Array_const_iterator& _Right) const noexcept { return !(*this == _Right); } From d0849f94084f1f93747cf3460eb1db1afb663dd9 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Thu, 18 Feb 2021 18:30:50 -0800 Subject: [PATCH 11/21] deque isn't constexpr. --- stl/inc/deque | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stl/inc/deque b/stl/inc/deque index 334286fedd5..f1580180c88 100644 --- a/stl/inc/deque +++ b/stl/inc/deque @@ -352,7 +352,7 @@ public: } #if _HAS_CXX20 - _NODISCARD constexpr strong_ordering operator<=>(const _Deque_const_iterator& _Right) const noexcept { + _NODISCARD strong_ordering operator<=>(const _Deque_const_iterator& _Right) const noexcept { _Compat(_Right); return this->_Myoff <=> _Right._Myoff; } From d25040b74f97ef5de197406c1ef68d305c80df58 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Thu, 18 Feb 2021 18:36:01 -0800 Subject: [PATCH 12/21] Mark vector/vector iterator spaceships as _CONSTEXPR20_CONTAINER. --- stl/inc/vector | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/stl/inc/vector b/stl/inc/vector index 879e714ed6b..8d3cad3ba39 100644 --- a/stl/inc/vector +++ b/stl/inc/vector @@ -153,7 +153,7 @@ public: } #if _HAS_CXX20 - _NODISCARD strong_ordering operator<=>(const _Vector_const_iterator& _Right) const noexcept { + _NODISCARD _CONSTEXPR20_CONTAINER strong_ordering operator<=>(const _Vector_const_iterator& _Right) const noexcept { _Compat(_Right); return _Unfancy(_Ptr) <=> _Unfancy(_Right._Ptr); } @@ -2212,7 +2212,7 @@ public: } #if _HAS_CXX20 - _NODISCARD strong_ordering operator<=>(const _Vb_const_iterator& _Right) const noexcept { + _NODISCARD _CONSTEXPR20_CONTAINER strong_ordering operator<=>(const _Vb_const_iterator& _Right) const noexcept { _Compat(_Right); if (const auto _CmpResult = this->_Myptr <=> _Right._Myptr; _CmpResult != 0) { return _CmpResult; From 1a51bd7866f3b8f9ca5ade17adc9e3f83a772c65 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Thu, 18 Feb 2021 18:43:49 -0800 Subject: [PATCH 13/21] Fix _STL_VERIFY message: spaceship isn't equality. --- stl/inc/xstring | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stl/inc/xstring b/stl/inc/xstring index a14b81049b3..8551a274080 100644 --- a/stl/inc/xstring +++ b/stl/inc/xstring @@ -1128,7 +1128,7 @@ public: _NODISCARD constexpr strong_ordering operator<=>(const _String_view_iterator& _Right) const noexcept { #if _ITERATOR_DEBUG_LEVEL >= 1 _STL_VERIFY(_Mydata == _Right._Mydata && _Mysize == _Right._Mysize, - "cannot compare incompatible string_view iterators for equality"); + "cannot compare incompatible string_view iterators"); return _Myoff <=> _Right._Myoff; #else // ^^^ _ITERATOR_DEBUG_LEVEL >= 1 ^^^ // vvv _ITERATOR_DEBUG_LEVEL == 0 vvv return _Myptr <=> _Right._Myptr; From 04960621bf20455090651ced35d7a7e441c98b8c Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Thu, 18 Feb 2021 18:48:14 -0800 Subject: [PATCH 14/21] Skip _Tree_const_iterator operator!= for C++20. --- stl/inc/xtree | 2 ++ 1 file changed, 2 insertions(+) diff --git a/stl/inc/xtree b/stl/inc/xtree index 48ce80c3967..3d9e6786ee0 100644 --- a/stl/inc/xtree +++ b/stl/inc/xtree @@ -236,9 +236,11 @@ public: return this->_Ptr == _Right._Ptr; } +#if !_HAS_CXX20 _NODISCARD bool operator!=(const _Tree_const_iterator& _Right) const noexcept { return !(*this == _Right); } +#endif // !_HAS_CXX20 #if _ITERATOR_DEBUG_LEVEL == 2 friend void _Verify_range(const _Tree_const_iterator& _First, const _Tree_const_iterator& _Last) noexcept { From 16c7ce55deee69fef64e6fec63de12d129f93a47 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Thu, 18 Feb 2021 19:01:23 -0800 Subject: [PATCH 15/21] Spaceships for checked_array_iterator and unchecked_array_iterator. --- stl/inc/iterator | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/stl/inc/iterator b/stl/inc/iterator index 94210f0eeb7..6fd2233e372 100644 --- a/stl/inc/iterator +++ b/stl/inc/iterator @@ -1496,6 +1496,13 @@ public: return _Myindex == _Right._Myindex; } +#if _HAS_CXX20 + _NODISCARD constexpr _STD strong_ordering operator<=>(const checked_array_iterator& _Right) const noexcept { + _STL_VERIFY(_Myarray == _Right._Myarray && _Mysize == _Right._Mysize, + "cannot compare incompatible checked_array_iterators"); + return _Myindex <=> _Right._Myindex; + } +#else // ^^^ _HAS_CXX20 ^^^ / vvv !_HAS_CXX20 vvv _NODISCARD constexpr bool operator!=(const checked_array_iterator& _Right) const noexcept { return !(*this == _Right); } @@ -1517,6 +1524,7 @@ public: _NODISCARD constexpr bool operator>=(const checked_array_iterator& _Right) const noexcept { return !(*this < _Right); } +#endif // !_HAS_CXX20 friend constexpr void _Verify_range( const checked_array_iterator& _First, const checked_array_iterator& _Last) noexcept { @@ -1650,6 +1658,11 @@ public: return _Myptr == _Right._Myptr; } +#if _HAS_CXX20 + _NODISCARD constexpr _STD strong_ordering operator<=>(const unchecked_array_iterator& _Right) const noexcept { + return _Myptr <=> _Right._Myptr; + } +#else // ^^^ _HAS_CXX20 ^^^ / vvv !_HAS_CXX20 vvv _NODISCARD constexpr bool operator!=(const unchecked_array_iterator& _Right) const noexcept { return !(*this == _Right); } @@ -1669,6 +1682,7 @@ public: _NODISCARD constexpr bool operator>=(const unchecked_array_iterator& _Right) const noexcept { return !(*this < _Right); } +#endif // !_HAS_CXX20 #if _ITERATOR_DEBUG_LEVEL != 0 friend constexpr void _Verify_range( From 4382c5283cbace19fd1d0a3a88938eef8c8b816d Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Thu, 18 Feb 2021 19:03:23 -0800 Subject: [PATCH 16/21] Skip _Reinterpret_move_iter operator!= for C++20. --- stl/inc/xhash | 2 ++ 1 file changed, 2 insertions(+) diff --git a/stl/inc/xhash b/stl/inc/xhash index 3c8a7bbaba2..a7fc07566a0 100644 --- a/stl/inc/xhash +++ b/stl/inc/xhash @@ -196,12 +196,14 @@ struct _Reinterpret_move_iter { return _Lhs._Base == _Rhs._Base; } +#if !_HAS_CXX20 #ifndef __CUDACC__ // TRANSITION, VSO-568006 _NODISCARD #endif // TRANSITION, VSO-568006 friend bool operator!=(const _Reinterpret_move_iter& _Lhs, const _Reinterpret_move_iter& _Rhs) { return _Lhs._Base != _Rhs._Base; } +#endif // !_HAS_CXX20 }; // STRUCT TEMPLATE _List_head_construct_ptr From c57087e4f8df5697cce40d6fe9e4d648c62d948c Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Thu, 18 Feb 2021 19:24:56 -0800 Subject: [PATCH 17/21] Activate string tests. --- tests/std/tests/P1614R2_spaceship/test.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/tests/std/tests/P1614R2_spaceship/test.cpp b/tests/std/tests/P1614R2_spaceship/test.cpp index 9296675d75a..9425e7e6db6 100644 --- a/tests/std/tests/P1614R2_spaceship/test.cpp +++ b/tests/std/tests/P1614R2_spaceship/test.cpp @@ -297,20 +297,16 @@ void ordering_test_cases() { } { // string std::string a1 = "aaa"; -#if 0 // TRANSITION, GH-1635 std::string a2 = "aaa"; std::string b1 = "bb"; ordered_containers_test(a1, a2, b1); -#endif // TRANSITION, GH-1635 ordered_iterator_test(a1.begin(), a1.begin(), a1.end(), a1.cbegin(), a1.cbegin(), a1.cend()); } { // string_view std::string_view a1 = "aaa"; -#if 0 // TRANSITION, GH-1635 std::string_view a2 = "aaa"; std::string_view b1 = "bb"; ordered_containers_test(a1, a2, b1); -#endif // TRANSITION, GH-1635 ordered_iterator_test(a1.begin(), a1.begin(), a1.end(), a1.cbegin(), a1.cbegin(), a1.cend()); } { // vector SynthOrdered From 98f6f009272830f902e3bba9ca08b4fc342b021f Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Thu, 18 Feb 2021 19:25:14 -0800 Subject: [PATCH 18/21] deque iterators were tested above. --- tests/std/tests/P1614R2_spaceship/test.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/std/tests/P1614R2_spaceship/test.cpp b/tests/std/tests/P1614R2_spaceship/test.cpp index 9425e7e6db6..ed6e6234e2d 100644 --- a/tests/std/tests/P1614R2_spaceship/test.cpp +++ b/tests/std/tests/P1614R2_spaceship/test.cpp @@ -449,7 +449,6 @@ void ordering_test_cases() { std::queue b(deq1); std::queue c(deq2); ordered_containers_test(a, b, c); - ordered_iterator_test(deq1.begin(), deq1.begin(), deq1.end(), deq1.cbegin(), deq1.cbegin(), deq1.cend()); } { // queue SynthOrdered std::queue a{std::deque{10, 20, 30}}; From a1721c064ccf07e7458ece19f99d2d668ce053af Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Thu, 18 Feb 2021 19:27:26 -0800 Subject: [PATCH 19/21] Reorder and comment "string iterators", "string_view iterators" tests. --- tests/std/tests/P1614R2_spaceship/test.cpp | 28 +++++++++++----------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/tests/std/tests/P1614R2_spaceship/test.cpp b/tests/std/tests/P1614R2_spaceship/test.cpp index ed6e6234e2d..763365f7b4a 100644 --- a/tests/std/tests/P1614R2_spaceship/test.cpp +++ b/tests/std/tests/P1614R2_spaceship/test.cpp @@ -295,20 +295,6 @@ void ordering_test_cases() { ordered_containers_test(a1, a2, b1); ordered_iterator_test(a1.begin(), a1.begin(), a1.end(), a1.cbegin(), a1.cbegin(), a1.cend()); } - { // string - std::string a1 = "aaa"; - std::string a2 = "aaa"; - std::string b1 = "bb"; - ordered_containers_test(a1, a2, b1); - ordered_iterator_test(a1.begin(), a1.begin(), a1.end(), a1.cbegin(), a1.cbegin(), a1.cend()); - } - { // string_view - std::string_view a1 = "aaa"; - std::string_view a2 = "aaa"; - std::string_view b1 = "bb"; - ordered_containers_test(a1, a2, b1); - ordered_iterator_test(a1.begin(), a1.begin(), a1.end(), a1.cbegin(), a1.cbegin(), a1.cend()); - } { // vector SynthOrdered std::vector a = {10, 20, 30}; std::vector b = {10, 20, 40}; @@ -559,6 +545,13 @@ void ordering_test_cases() { assert(("abcdef" <=> a1) == std::strong_ordering::equivalent); assert(("zebra" <=> a1) == std::strong_ordering::greater); } + { // string iterators + std::string a1 = "aaa"; + std::string a2 = "aaa"; + std::string b1 = "bb"; + ordered_containers_test(a1, a2, b1); + ordered_iterator_test(a1.begin(), a1.begin(), a1.end(), a1.cbegin(), a1.cbegin(), a1.cend()); + } { // string_view const std::string_view a1 = "abcdef"; const std::string_view a2 = "abcdef"; @@ -635,6 +628,13 @@ void ordering_test_cases() { static_assert(("abcdef" <=> a1) == std::strong_ordering::equivalent); static_assert(("zebra" <=> a1) == std::strong_ordering::greater); } + { // string_view iterators + std::string_view a1 = "aaa"; + std::string_view a2 = "aaa"; + std::string_view b1 = "bb"; + ordered_containers_test(a1, a2, b1); + ordered_iterator_test(a1.begin(), a1.begin(), a1.end(), a1.cbegin(), a1.cbegin(), a1.cend()); + } { // Diagnostics Library diagnostics_test(); diagnostics_test(); From f65f20fbaf5838ad3530f4539ac5e6ba2784a60d Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Thu, 18 Feb 2021 19:44:59 -0800 Subject: [PATCH 20/21] Test checked_array_iterator, unchecked_array_iterator. --- tests/std/tests/P1614R2_spaceship/test.cpp | 31 ++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/tests/std/tests/P1614R2_spaceship/test.cpp b/tests/std/tests/P1614R2_spaceship/test.cpp index 763365f7b4a..2bd59ee057b 100644 --- a/tests/std/tests/P1614R2_spaceship/test.cpp +++ b/tests/std/tests/P1614R2_spaceship/test.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -458,6 +459,36 @@ void ordering_test_cases() { std::stack b{std::deque{10, 20, 40}}; ordered_containers_test(a, a, b); } + { // checked_array_iterator + int arr[] = {11, 22, 33}; + constexpr auto N = std::size(arr); + + using I = stdext::checked_array_iterator; + using CI = stdext::checked_array_iterator; // TRANSITION, GH-943, should be + + I first{arr, N}; + I last{arr, N, N}; + + CI cfirst{arr, N}; + CI clast{arr, N, N}; + + ordered_iterator_test(first, first, last, cfirst, cfirst, clast); + } + { // unchecked_array_iterator + int arr[] = {11, 22, 33}; + constexpr auto N = std::size(arr); + + using I = stdext::unchecked_array_iterator; + using CI = stdext::unchecked_array_iterator; // TRANSITION, GH-943, should be + + I first{arr}; + I last{arr + N}; + + CI cfirst{arr}; + CI clast{arr + N}; + + ordered_iterator_test(first, first, last, cfirst, cfirst, clast); + } { // sub_match const std::string s1{"cats"}; const std::string s2{"meow"}; From 6b92a989c0d60acf72ddd268bb15940dddacbc95 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Thu, 18 Feb 2021 20:17:47 -0800 Subject: [PATCH 21/21] In !_HAS_CXX20 mode, drop _CONSTEXPR20 and _CONSTEXPR20_CONTAINER. --- stl/inc/array | 2 +- stl/inc/vector | 22 +++++++++++----------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/stl/inc/array b/stl/inc/array index e0bcf371800..f8dae919a60 100644 --- a/stl/inc/array +++ b/stl/inc/array @@ -797,7 +797,7 @@ _NODISCARD _CONSTEXPR20 bool operator==(const array<_Ty, _Size>& _Left, const ar #if !_HAS_CXX20 template -_NODISCARD _CONSTEXPR20 bool operator!=(const array<_Ty, _Size>& _Left, const array<_Ty, _Size>& _Right) { +_NODISCARD bool operator!=(const array<_Ty, _Size>& _Left, const array<_Ty, _Size>& _Right) { return !(_Left == _Right); } #endif // !_HAS_CXX20 diff --git a/stl/inc/vector b/stl/inc/vector index 8d3cad3ba39..a5b750af657 100644 --- a/stl/inc/vector +++ b/stl/inc/vector @@ -158,24 +158,24 @@ public: return _Unfancy(_Ptr) <=> _Unfancy(_Right._Ptr); } #else // ^^^ _HAS_CXX20 ^^^ / vvv !_HAS_CXX20 vvv - _NODISCARD _CONSTEXPR20_CONTAINER bool operator!=(const _Vector_const_iterator& _Right) const noexcept { + _NODISCARD bool operator!=(const _Vector_const_iterator& _Right) const noexcept { return !(*this == _Right); } - _NODISCARD _CONSTEXPR20_CONTAINER bool operator<(const _Vector_const_iterator& _Right) const noexcept { + _NODISCARD bool operator<(const _Vector_const_iterator& _Right) const noexcept { _Compat(_Right); return _Ptr < _Right._Ptr; } - _NODISCARD _CONSTEXPR20_CONTAINER bool operator>(const _Vector_const_iterator& _Right) const noexcept { + _NODISCARD bool operator>(const _Vector_const_iterator& _Right) const noexcept { return _Right < *this; } - _NODISCARD _CONSTEXPR20_CONTAINER bool operator<=(const _Vector_const_iterator& _Right) const noexcept { + _NODISCARD bool operator<=(const _Vector_const_iterator& _Right) const noexcept { return !(_Right < *this); } - _NODISCARD _CONSTEXPR20_CONTAINER bool operator>=(const _Vector_const_iterator& _Right) const noexcept { + _NODISCARD bool operator>=(const _Vector_const_iterator& _Right) const noexcept { return !(*this < _Right); } #endif // !_HAS_CXX20 @@ -1858,7 +1858,7 @@ _NODISCARD _CONSTEXPR20_CONTAINER bool operator==(const vector<_Ty, _Alloc>& _Le #if !_HAS_CXX20 template -_NODISCARD _CONSTEXPR20_CONTAINER bool operator!=(const vector<_Ty, _Alloc>& _Left, const vector<_Ty, _Alloc>& _Right) { +_NODISCARD bool operator!=(const vector<_Ty, _Alloc>& _Left, const vector<_Ty, _Alloc>& _Right) { return !(_Left == _Right); } #endif // !_HAS_CXX20 @@ -2220,24 +2220,24 @@ public: return this->_Myoff <=> _Right._Myoff; } #else // ^^^ _HAS_CXX20 ^^^ / vvv !_HAS_CXX20 vvv - _NODISCARD _CONSTEXPR20_CONTAINER bool operator!=(const _Vb_const_iterator& _Right) const noexcept { + _NODISCARD bool operator!=(const _Vb_const_iterator& _Right) const noexcept { return !(*this == _Right); } - _NODISCARD _CONSTEXPR20_CONTAINER bool operator<(const _Vb_const_iterator& _Right) const noexcept { + _NODISCARD bool operator<(const _Vb_const_iterator& _Right) const noexcept { _Compat(_Right); return this->_Myptr < _Right._Myptr || (this->_Myptr == _Right._Myptr && this->_Myoff < _Right._Myoff); } - _NODISCARD _CONSTEXPR20_CONTAINER bool operator>(const _Vb_const_iterator& _Right) const noexcept { + _NODISCARD bool operator>(const _Vb_const_iterator& _Right) const noexcept { return _Right < *this; } - _NODISCARD _CONSTEXPR20_CONTAINER bool operator<=(const _Vb_const_iterator& _Right) const noexcept { + _NODISCARD bool operator<=(const _Vb_const_iterator& _Right) const noexcept { return !(_Right < *this); } - _NODISCARD _CONSTEXPR20_CONTAINER bool operator>=(const _Vb_const_iterator& _Right) const noexcept { + _NODISCARD bool operator>=(const _Vb_const_iterator& _Right) const noexcept { return !(*this < _Right); } #endif // !_HAS_CXX20