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],Adrian Vogelsgesang,|Complete| -| `[vector.syn] `_ (`general `_),| `vector `_,[expos.only.func],Adrian Vogelsgesang,|In Progress| +| `[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> @@ -3182,8 +3185,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) @@ -3192,7 +3196,6 @@ } template -_LIBCPP_CONSTEXPR_SINCE_CXX20 inline _LIBCPP_HIDE_FROM_ABI bool operator< (const vector<_Tp, _Allocator>& __x, const vector<_Tp, _Allocator>& __y) @@ -3201,7 +3204,6 @@ } template -_LIBCPP_CONSTEXPR_SINCE_CXX20 inline _LIBCPP_HIDE_FROM_ABI bool operator> (const vector<_Tp, _Allocator>& __x, const vector<_Tp, _Allocator>& __y) @@ -3210,7 +3212,6 @@ } template -_LIBCPP_CONSTEXPR_SINCE_CXX20 inline _LIBCPP_HIDE_FROM_ABI bool operator>=(const vector<_Tp, _Allocator>& __x, const vector<_Tp, _Allocator>& __y) @@ -3219,7 +3220,6 @@ } template -_LIBCPP_CONSTEXPR_SINCE_CXX20 inline _LIBCPP_HIDE_FROM_ABI bool operator<=(const vector<_Tp, _Allocator>& __x, const vector<_Tp, _Allocator>& __y) @@ -3227,6 +3227,18 @@ return !(__y < __x); } +#else // _LIBCPP_STD_VER <= 17 + +template +inline _LIBCPP_HIDE_FROM_ABI +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,32 @@ { 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); 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 +60,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 +70,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 +80,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 +100,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.three_way.pass.cpp b/libcxx/test/std/containers/sequences/vector/compare.three_way.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/containers/sequences/vector/compare.three_way.pass.cpp @@ -0,0 +1,25 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// UNSUPPORTED: c++03, c++11, c++14, c++17 + +// + +// template constexpr +// synth-three-way-result +// operator<=>(const vector& x, const vector& y); + +#include +#include + +#include "test_container_comparisons.h" + +int main() { + assert(test_ordered_container_spaceship()); + static_assert(test_ordered_container_spaceship()); + return 0; +}