diff --git a/libcxx/docs/Status/SpaceshipProjects.csv b/libcxx/docs/Status/SpaceshipProjects.csv --- a/libcxx/docs/Status/SpaceshipProjects.csv +++ b/libcxx/docs/Status/SpaceshipProjects.csv @@ -39,7 +39,7 @@ | `[deque.syn] `_ (`general `_),| deque,[expos.only.func],Unassigned,|Not Started| | `[forward.list.syn] `_ (`general `_),| forward_list,[expos.only.func],Unassigned,|Not Started| | `[list.syn] `_ (`general `_),| list,[expos.only.func],Unassigned,|Not Started| -| `[vector.syn] `_ (`general `_),| vector,[expos.only.func],Unassigned,|Not Started| +| `[vector.syn] `_ (`general `_),| `vector `_,[expos.only.func],Adrian Vogelsgesang,|Complete| | `[associative.map.syn] `_ (`general `_),"| map | multimap",[expos.only.func],Unassigned,|Not Started| | `[associative.set.syn] `_ (`general `_),"| multiset diff --git a/libcxx/include/vector b/libcxx/include/vector --- a/libcxx/include/vector +++ b/libcxx/include/vector @@ -249,12 +249,14 @@ template struct hash>; -template bool operator==(const vector& x, const vector& y); -template bool operator< (const vector& x, const vector& y); -template bool operator!=(const vector& x, const vector& y); -template bool operator> (const vector& x, const vector& y); -template bool operator>=(const vector& x, const vector& y); -template bool operator<=(const vector& x, const vector& y); +template bool operator==(const vector& x, const vector& y); // constexpr since C++20 +template bool operator!=(const vector& x, const vector& y); // removed in C++20 +template bool operator< (const vector& x, const vector& y); // removed in C++20 +template bool operator> (const vector& x, const vector& y); // removed in C++20 +template bool operator>=(const vector& x, const vector& y); // removed in C++20 +template bool operator<=(const vector& x, const vector& y); // removed in C++20 +template constexpr + synth-three-way-result operator<=>(const vector& x, const vector& y); // since C++20 template void swap(vector& x, vector& y) @@ -262,10 +264,10 @@ template typename vector::size_type -erase(vector& c, const U& value); // C++20 +erase(vector& c, const U& value); // since C++20 template typename vector::size_type -erase_if(vector& c, Predicate pred); // C++20 +erase_if(vector& c, Predicate pred); // since C++20 } // std @@ -275,6 +277,7 @@ #include <__algorithm/equal.h> #include <__algorithm/fill_n.h> #include <__algorithm/lexicographical_compare.h> +#include <__algorithm/lexicographical_compare_three_way.h> #include <__algorithm/remove.h> #include <__algorithm/remove_if.h> #include <__algorithm/rotate.h> @@ -3237,8 +3240,9 @@ return __sz == __y.size() && std::equal(__x.begin(), __x.end(), __y.begin()); } +#if _LIBCPP_STD_VER <= 17 + template -_LIBCPP_CONSTEXPR_SINCE_CXX20 inline _LIBCPP_HIDE_FROM_ABI bool operator!=(const vector<_Tp, _Allocator>& __x, const vector<_Tp, _Allocator>& __y) @@ -3247,7 +3251,6 @@ } template -_LIBCPP_CONSTEXPR_SINCE_CXX20 inline _LIBCPP_HIDE_FROM_ABI bool operator< (const vector<_Tp, _Allocator>& __x, const vector<_Tp, _Allocator>& __y) @@ -3256,7 +3259,6 @@ } template -_LIBCPP_CONSTEXPR_SINCE_CXX20 inline _LIBCPP_HIDE_FROM_ABI bool operator> (const vector<_Tp, _Allocator>& __x, const vector<_Tp, _Allocator>& __y) @@ -3265,7 +3267,6 @@ } template -_LIBCPP_CONSTEXPR_SINCE_CXX20 inline _LIBCPP_HIDE_FROM_ABI bool operator>=(const vector<_Tp, _Allocator>& __x, const vector<_Tp, _Allocator>& __y) @@ -3274,7 +3275,6 @@ } template -_LIBCPP_CONSTEXPR_SINCE_CXX20 inline _LIBCPP_HIDE_FROM_ABI bool operator<=(const vector<_Tp, _Allocator>& __x, const vector<_Tp, _Allocator>& __y) @@ -3282,6 +3282,17 @@ return !(__y < __x); } +#else // _LIBCPP_STD_VER <= 17 + +template +constexpr __synth_three_way_result<_Tp> +operator<=>(const vector<_Tp, _Allocator>& __x, const vector<_Tp, _Allocator>& __y) +{ + return lexicographical_compare_three_way(__x.begin(), __x.end(), __y.begin(), __y.end(), __synth_three_way); +} + +#endif // _LIBCPP_STD_VER <= 17 + template _LIBCPP_CONSTEXPR_SINCE_CXX20 inline _LIBCPP_HIDE_FROM_ABI diff --git a/libcxx/test/std/containers/sequences/vector.bool/compare.pass.cpp b/libcxx/test/std/containers/sequences/vector.bool/compare.pass.cpp --- a/libcxx/test/std/containers/sequences/vector.bool/compare.pass.cpp +++ b/libcxx/test/std/containers/sequences/vector.bool/compare.pass.cpp @@ -14,6 +14,8 @@ // bool operator<=( const vector& lhs, const vector& rhs ); // bool operator> ( const vector& lhs, const vector& rhs ); // bool operator>=( const vector& lhs, const vector& rhs ); +// template constexpr +// synth-three-way-result operator<=>(const vector& x, const vector& y) #include #include @@ -25,20 +27,33 @@ { const VB v1, v2; assert(testComparisons(v1, v2, true, false)); +#if TEST_STD_VER >= 20 + assert(testOrder(v1, v2, std::strong_ordering::equal)); +#endif } { const VB v1(1, true); const VB v2(1, true); assert(testComparisons(v1, v2, true, false)); +#if TEST_STD_VER >= 20 + assert(testOrder(v1, v2, std::strong_ordering::equal)); +#endif } { const VB v1(1, false); const VB v2(1, true); assert(testComparisons(v1, v2, false, true)); +#if TEST_STD_VER >= 20 + assert(testOrder(v1, v2, std::strong_ordering::less)); +#endif } { - const VB v1, v2(1, true); + const VB v1; + const VB v2(1, true); assert(testComparisons(v1, v2, false, true)); +#if TEST_STD_VER >= 20 + assert(testOrder(v1, v2, std::strong_ordering::less)); +#endif } { bool items1[3] = {false, true, false}; @@ -46,6 +61,9 @@ const VB v1(items1, items1 + 3); const VB v2(items2, items2 + 3); assert(testComparisons(v1, v2, false, true)); +#if TEST_STD_VER >= 20 + assert(testOrder(v1, v2, std::strong_ordering::less)); +#endif } { bool items1[3] = {false, false, false}; @@ -53,6 +71,9 @@ const VB v1(items1, items1 + 3); const VB v2(items2, items2 + 3); assert(testComparisons(v1, v2, false, true)); +#if TEST_STD_VER >= 20 + assert(testOrder(v1, v2, std::strong_ordering::less)); +#endif } { bool items1[2] = {false, true}; @@ -60,12 +81,18 @@ const VB v1(items1, items1 + 2); const VB v2(items2, items2 + 3); assert(testComparisons(v1, v2, false, true)); +#if TEST_STD_VER >= 20 + assert(testOrder(v1, v2, std::strong_ordering::less)); +#endif } { bool items[3] = {false, true, false}; const VB v1(items, items + 3); const VB v2(1, true); assert(testComparisons(v1, v2, false, true)); +#if TEST_STD_VER >= 20 + assert(testOrder(v1, v2, std::strong_ordering::less)); +#endif } { assert( (std::vector() == std::vector())); @@ -74,6 +101,9 @@ assert( (std::vector() <= std::vector())); assert(!(std::vector() > std::vector())); assert( (std::vector() >= std::vector())); +#if TEST_STD_VER >= 20 + assert((std::vector() <=> std::vector()) == std::strong_ordering::equal); +#endif } return true; diff --git a/libcxx/test/std/containers/sequences/vector/compare.pass.cpp b/libcxx/test/std/containers/sequences/vector/compare.pass.cpp --- a/libcxx/test/std/containers/sequences/vector/compare.pass.cpp +++ b/libcxx/test/std/containers/sequences/vector/compare.pass.cpp @@ -14,109 +14,107 @@ // bool operator<=(const vector& lhs, const vector& rhs); // bool operator> (const vector& lhs, const vector& rhs); // bool operator>=(const vector& lhs, const vector& rhs); +// template constexpr +// synth-three-way-result operator<=>(const vector& x, const vector& y) #include #include #include "test_comparisons.h" +template +TEST_CONSTEXPR_CXX20 void test_with_type() { + AssertComparisonsReturnBool >(); +#if TEST_STD_VER >= 20 + AssertOrderReturn>(); +#endif + { + const std::vector c1, c2; + assert(testComparisons(c1, c2, true, false)); +#if TEST_STD_VER >= 20 + assert(testOrder(c1, c2, std::strong_ordering::equal)); +#endif + } + { + const std::vector c1(1, 1), c2(1, 2); + assert(testComparisons(c1, c2, false, true)); +#if TEST_STD_VER >= 20 + assert(testOrder(c1, c2, std::strong_ordering::less)); +#endif + } + { + const std::vector c1; + const std::vector c2(1, 2); + assert(testComparisons(c1, c2, false, true)); +#if TEST_STD_VER >= 20 + assert(testOrder(c1, c2, std::strong_ordering::less)); +#endif + } + { + int items1[3] = {1, 2, 1}; + int items2[3] = {1, 2, 2}; + const std::vector c1(items1, items1 + 3); + const std::vector c2(items2, items2 + 3); + assert(testComparisons(c1, c2, false, true)); +#if TEST_STD_VER >= 20 + assert(testOrder(c1, c2, std::strong_ordering::less)); +#endif + } + { + int items1[3] = {3, 2, 3}; + int items2[3] = {3, 1, 3}; + const std::vector c1(items1, items1 + 3); + const std::vector c2(items2, items2 + 3); + assert(testComparisons(c1, c2, false, false)); +#if TEST_STD_VER >= 20 + assert(testOrder(c1, c2, std::strong_ordering::greater)); +#endif + } + { + int items1[2] = {1, 2}; + int items2[3] = {1, 2, 0}; + const std::vector c1(items1, items1 + 2); + const std::vector c2(items2, items2 + 3); + assert(testComparisons(c1, c2, false, true)); +#if TEST_STD_VER >= 20 + assert(testOrder(c1, c2, std::strong_ordering::less)); +#endif + } + { + int items1[3] = {1, 2, 0}; + const std::vector c1(items1, items1 + 3); + const std::vector c2(1, 3); + assert(testComparisons(c1, c2, false, true)); +#if TEST_STD_VER >= 20 + assert(testOrder(c1, c2, std::strong_ordering::less)); +#endif + } +} + TEST_CONSTEXPR_CXX20 bool test() { - { - const std::vector c1, c2; - assert(testComparisons(c1, c2, true, false)); - } - { - const std::vector c1(1, 1), c2(1, 2); - assert(testComparisons(c1, c2, false, true)); - } - { - const std::vector c1, c2(1, 2); - assert(testComparisons(c1, c2, false, true)); - } - { - int items1[3] = {1, 2, 1}; - int items2[3] = {1, 2, 2}; - const std::vector c1(items1, items1 + 3); - const std::vector c2(items2, items2 + 3); - assert(testComparisons(c1, c2, false, true)); - } - { - int items1[3] = {3, 2, 3}; - int items2[3] = {3, 1, 3}; - const std::vector c1(items1, items1 + 3); - const std::vector c2(items2, items2 + 3); +#if TEST_STD_VER >= 20 + using strong_ordering_since_cxx20 = std::strong_ordering; + using weak_ordering_since_cxx20 = std::weak_ordering; +#else + typedef void strong_ordering_since_cxx20; + typedef void weak_ordering_since_cxx20; +#endif + test_with_type(); + test_with_type(); +#if TEST_STD_VER >= 20 + test_with_type(); + test_with_type(); +#endif + { + assert((std::vector() == std::vector())); + assert(!(std::vector() != std::vector())); + assert(!(std::vector() < std::vector())); + assert((std::vector() <= std::vector())); + assert(!(std::vector() > std::vector())); + assert((std::vector() >= std::vector())); + } - assert(testComparisons(c1, c2, false, false)); - } - { - int items1[2] = {1, 2}; - int items2[3] = {1, 2, 0}; - const std::vector c1(items1, items1 + 2); - const std::vector c2(items2, items2 + 3); - assert(testComparisons(c1, c2, false, true)); - } - { - int items1[3] = {1, 2, 0}; - const std::vector c1(items1, items1 + 3); - const std::vector c2(1, 3); - assert(testComparisons(c1, c2, false, true)); - } - { - const std::vector c1, c2; - assert(testComparisons(c1, c2, true, false)); - } - { - const std::vector c1(1, LessAndEqComp(1)); - const std::vector c2(1, LessAndEqComp(1)); - assert(testComparisons(c1, c2, true, false)); - } - { - const std::vector c1(1, LessAndEqComp(1)); - const std::vector c2(1, LessAndEqComp(2)); - assert(testComparisons(c1, c2, false, true)); - } - { - const std::vector c1; - const std::vector c2(1, LessAndEqComp(2)); - assert(testComparisons(c1, c2, false, true)); - } - { - LessAndEqComp items1[3] = {LessAndEqComp(1), LessAndEqComp(2), LessAndEqComp(2)}; - LessAndEqComp items2[3] = {LessAndEqComp(1), LessAndEqComp(2), LessAndEqComp(1)}; - const std::vector c1(items1, items1 + 3); - const std::vector c2(items2, items2 + 3); - assert(testComparisons(c1, c2, false, false)); - } - { - LessAndEqComp items1[3] = {LessAndEqComp(3), LessAndEqComp(3), LessAndEqComp(3)}; - LessAndEqComp items2[3] = {LessAndEqComp(3), LessAndEqComp(2), LessAndEqComp(3)}; - const std::vector c1(items1, items1 + 3); - const std::vector c2(items2, items2 + 3); - assert(testComparisons(c1, c2, false, false)); - } - { - LessAndEqComp items1[2] = {LessAndEqComp(1), LessAndEqComp(2)}; - LessAndEqComp items2[3] = {LessAndEqComp(1), LessAndEqComp(2), LessAndEqComp(0)}; - const std::vector c1(items1, items1 + 2); - const std::vector c2(items2, items2 + 3); - assert(testComparisons(c1, c2, false, true)); - } - { - LessAndEqComp items1[3] = {LessAndEqComp(1), LessAndEqComp(2), LessAndEqComp(0)}; - const std::vector c1(items1, items1 + 3); - const std::vector c2(1, LessAndEqComp(3)); - assert(testComparisons(c1, c2, false, true)); - } - { - assert((std::vector() == std::vector())); - assert(!(std::vector() != std::vector())); - assert(!(std::vector() < std::vector())); - assert((std::vector() <= std::vector())); - assert(!(std::vector() > std::vector())); - assert((std::vector() >= std::vector())); - } - - return true; + return true; } int main(int, char**) {