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 @@ -38,7 +38,7 @@ | `[array.syn] `_ (`general `_),| array,[expos.only.func],Unassigned,|Not Started| | `[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| +| `[list.syn] `_ (`general `_),| `list `_,[expos.only.func],Adrian Vogelsgesang,|Complete| | `[vector.syn] `_ (`general `_),| vector,[expos.only.func],Unassigned,|Not Started| | `[associative.map.syn] `_ (`general `_),"| map | multimap",[expos.only.func],Unassigned,|Not Started| diff --git a/libcxx/include/list b/libcxx/include/list --- a/libcxx/include/list +++ b/libcxx/include/list @@ -155,15 +155,18 @@ template bool operator==(const list& x, const list& y); template - bool operator< (const list& x, const list& y); + bool operator< (const list& x, const list& y); // removed in C++20 template - bool operator!=(const list& x, const list& y); + bool operator!=(const list& x, const list& y); // removed in C++20 template - bool operator> (const list& x, const list& y); + bool operator> (const list& x, const list& y); // removed in C++20 template - bool operator>=(const list& x, const list& y); + bool operator>=(const list& x, const list& y); // removed in C++20 template - bool operator<=(const list& x, const list& y); + bool operator<=(const list& x, const list& y); // removed in C++20 +template + synth-three-way-result operator<=>(const list& x, + const list& y); // since C++20 template void swap(list& x, list& y) @@ -171,10 +174,10 @@ template typename list::size_type - erase(list& c, const U& value); // C++20 + erase(list& c, const U& value); // since C++20 template typename list::size_type - erase_if(list& c, Predicate pred); // C++20 + erase_if(list& c, Predicate pred); // since C++20 } // std @@ -183,6 +186,7 @@ #include <__algorithm/comp.h> #include <__algorithm/equal.h> #include <__algorithm/lexicographical_compare.h> +#include <__algorithm/lexicographical_compare_three_way.h> #include <__algorithm/min.h> #include <__assert> // all public C++ headers provide the assertion handler #include <__config> @@ -2289,6 +2293,8 @@ return __x.size() == __y.size() && _VSTD::equal(__x.begin(), __x.end(), __y.begin()); } +#if _LIBCPP_STD_VER <= 17 + template inline _LIBCPP_INLINE_VISIBILITY bool @@ -2329,6 +2335,18 @@ return !(__y < __x); } +#else // _LIBCPP_STD_VER <= 17 + +template +__synth_three_way_result<_Tp> +operator<=>(const list<_Tp, _Allocator>& __x, const list<_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 inline _LIBCPP_INLINE_VISIBILITY void diff --git a/libcxx/test/std/containers/sequences/list/compare.pass.cpp b/libcxx/test/std/containers/sequences/list/compare.pass.cpp --- a/libcxx/test/std/containers/sequences/list/compare.pass.cpp +++ b/libcxx/test/std/containers/sequences/list/compare.pass.cpp @@ -32,86 +32,94 @@ // bool operator>=( const std::list& lhs, // const std::list& rhs ); +// template constexpr +// synth-three-way-result +// operator<=>(const vector& x, const vector& y); + #include #include #include "test_comparisons.h" -int main(int, char**) { - { - const std::list l1, l2; - assert(testComparisons(l1, l2, true, false)); - } - { - const std::list l1(1, 1), l2(1, 1); - assert(testComparisons(l1, l2, true, false)); - } - { - int items[3] = {1, 2, 3}; - const std::list l1(items, items + 3); - const std::list l2(items, items + 3); - assert(testComparisons(l1, l2, true, false)); - } - { - const std::list l1(1, 1), l2; - assert(testComparisons(l1, l2, false, false)); - } - { - const std::list l1(1, 1), l2(1, 2); - assert(testComparisons(l1, l2, false, true)); - } - { - int items1[2] = {1, 2}; - int items2[2] = {1, 3}; - const std::list l1(items1, items1 + 2); - const std::list l2(items2, items2 + 2); - assert(testComparisons(l1, l2, false, true)); - } - { - int items1[2] = {2, 2}; - int items2[2] = {1, 3}; - const std::list l1(items1, items1 + 2); - const std::list l2(items2, items2 + 2); - assert(testComparisons(l1, l2, false, false)); - } - { - const std::list l1, l2; - assert(testComparisons(l1, l2, true, false)); - } - { - const std::list l1(1, LessAndEqComp(1)); - const std::list l2(1, LessAndEqComp(1)); - assert(testComparisons(l1, l2, true, false)); - } - { - LessAndEqComp items[3] = {LessAndEqComp(1), LessAndEqComp(2), LessAndEqComp(3)}; - const std::list l1(items, items + 3); - const std::list l2(items, items + 3); - assert(testComparisons(l1, l2, true, false)); - } - { - const std::list l1(1, LessAndEqComp(1)); - const std::list l2; - assert(testComparisons(l1, l2, false, false)); - } - { - const std::list l1(1, LessAndEqComp(1)); - const std::list l2(1, LessAndEqComp(2)); - assert(testComparisons(l1, l2, false, true)); - } - { - LessAndEqComp items1[2] = {LessAndEqComp(1), LessAndEqComp(2)}; - LessAndEqComp items2[2] = {LessAndEqComp(1), LessAndEqComp(3)}; - const std::list l1(items1, items1 + 2); - const std::list l2(items2, items2 + 2); - assert(testComparisons(l1, l2, false, true)); - } - { - LessAndEqComp items1[2] = {LessAndEqComp(2), LessAndEqComp(2)}; - LessAndEqComp items2[2] = {LessAndEqComp(1), LessAndEqComp(3)}; - const std::list l1(items1, items1 + 2); - const std::list l2(items2, items2 + 2); - assert(testComparisons(l1, l2, false, false)); - } - return 0; +template +void test_with_type() { + AssertComparisonsReturnBool >(); +#if TEST_STD_VER >= 20 + AssertOrderReturn>(); +#endif + { + const std::list l1, l2; + assert(testComparisons(l1, l2, true, false)); +#if TEST_STD_VER >= 20 + assert(testOrder(l1, l2, Order::equal)); +#endif + } + { + const std::list l1(1, 1), l2(1, 1); + assert(testComparisons(l1, l2, true, false)); +#if TEST_STD_VER >= 20 + assert(testOrder(l1, l2, Order::equal)); +#endif + } + { + ElemT items[3] = {1, 2, 3}; + const std::list l1(items, items + 3); + const std::list l2(items, items + 3); + assert(testComparisons(l1, l2, true, false)); +#if TEST_STD_VER >= 20 + assert(testOrder(l1, l2, Order::equal)); +#endif + } + { + const std::list l1(1, 1), l2; + assert(testComparisons(l1, l2, false, false)); +#if TEST_STD_VER >= 20 + assert(testOrder(l1, l2, Order::greater)); +#endif + } + { + const std::list l1(1, 1), l2(1, 2); + assert(testComparisons(l1, l2, false, true)); +#if TEST_STD_VER >= 20 + assert(testOrder(l1, l2, Order::less)); +#endif + } + { + ElemT items1[2] = {1, 2}; + ElemT items2[2] = {1, 3}; + const std::list l1(items1, items1 + 2); + const std::list l2(items2, items2 + 2); + assert(testComparisons(l1, l2, false, true)); +#if TEST_STD_VER >= 20 + assert(testOrder(l1, l2, Order::less)); +#endif + } + { + ElemT items1[2] = {2, 2}; + ElemT items2[2] = {1, 3}; + const std::list l1(items1, items1 + 2); + const std::list l2(items2, items2 + 2); + assert(testComparisons(l1, l2, false, false)); +#if TEST_STD_VER >= 20 + assert(testOrder(l1, l2, Order::greater)); +#endif + } +} + +int main(int, char**) { +#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 + + return 0; }