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 @@ -40,7 +40,8 @@ | `[deque.syn] `_ (`general `_),| `deque `_,[expos.only.func],Hristo Hristov,|Complete| | `[forward.list.syn] `_ (`general `_),| `forward_list `_,[expos.only.func],Hristo Hristov,|Complete| | `[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 +| Hristo Hristov",|Complete| | `[associative.map.syn] `_ (`general `_),"| `map `_ | `multimap `_",[expos.only.func],Hristo Hristov,|Complete| | `[associative.set.syn] `_ (`general `_),"| multiset diff --git a/libcxx/include/vector b/libcxx/include/vector --- a/libcxx/include/vector +++ b/libcxx/include/vector @@ -269,12 +269,15 @@ 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 + constexpr synth-three-way-result operator<=>(const vector& x, + const vector& y); // since C++20 template void swap(vector& x, vector& y) @@ -282,10 +285,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 template @@ -303,6 +306,7 @@ #include <__algorithm/fill_n.h> #include <__algorithm/iterator_operations.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> @@ -3441,8 +3445,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) @@ -3451,7 +3456,6 @@ } template -_LIBCPP_CONSTEXPR_SINCE_CXX20 inline _LIBCPP_HIDE_FROM_ABI bool operator< (const vector<_Tp, _Allocator>& __x, const vector<_Tp, _Allocator>& __y) @@ -3460,7 +3464,6 @@ } template -_LIBCPP_CONSTEXPR_SINCE_CXX20 inline _LIBCPP_HIDE_FROM_ABI bool operator> (const vector<_Tp, _Allocator>& __x, const vector<_Tp, _Allocator>& __y) @@ -3469,7 +3472,6 @@ } template -_LIBCPP_CONSTEXPR_SINCE_CXX20 inline _LIBCPP_HIDE_FROM_ABI bool operator>=(const vector<_Tp, _Allocator>& __x, const vector<_Tp, _Allocator>& __y) @@ -3478,7 +3480,6 @@ } template -_LIBCPP_CONSTEXPR_SINCE_CXX20 inline _LIBCPP_HIDE_FROM_ABI bool operator<=(const vector<_Tp, _Allocator>& __x, const vector<_Tp, _Allocator>& __y) @@ -3486,6 +3487,17 @@ return !(__y < __x); } +#else // _LIBCPP_STD_VER <= 17 + +template +_LIBCPP_HIDE_FROM_ABI constexpr __synth_three_way_result<_Tp> +operator<=>(const vector<_Tp, _Allocator>& __x, const vector<_Tp, _Allocator>& __y) { + return std::lexicographical_compare_three_way( + __x.begin(), __x.end(), __y.begin(), __y.end(), std::__synth_three_way<_Tp, _Tp>); +} + +#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.three_way.pass.cpp b/libcxx/test/std/containers/sequences/vector.bool/compare.three_way.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/containers/sequences/vector.bool/compare.three_way.pass.cpp @@ -0,0 +1,96 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// + +// class vector + +// template +// constexpr synth-three-way-result operator<=>(const vector& x, +// const vector& y); + +#include +#include + +#include "test_comparisons.h" + +constexpr bool test_sequence_container_spaceship_vectorbool() { + // Empty containers + { + std::vector l1; + std::vector l2; + assert(testOrder(l1, l2, std::strong_ordering::equivalent)); + } + // Identical contents + { + std::vector t1{true, true}; + std::vector t2{true, true}; + assert(testOrder(t1, t2, std::strong_ordering::equivalent)); + + std::vector f1{false, false}; + std::vector f2{false, false}; + assert(testOrder(f1, f2, std::strong_ordering::equivalent)); + } + // Less, due to contained values + { + std::vector l1{true, false}; + std::vector l2{true, true}; + assert(testOrder(l1, l2, std::strong_ordering::less)); + } + // Greater, due to contained values + { + std::vector l1{true, true}; + std::vector l2{true, false}; + assert(testOrder(l1, l2, std::strong_ordering::greater)); + } + // Shorter list + { + std::vector l1{true}; + std::vector l2{true, false}; + assert(testOrder(l1, l2, std::strong_ordering::less)); + + std::vector t1{true}; + std::vector t2{true, true}; + assert(testOrder(t1, t2, std::strong_ordering::less)); + + std::vector f1{false}; + std::vector f2{false, false}; + assert(testOrder(f1, f2, std::strong_ordering::less)); + + std::vector e; + assert(testOrder(e, t1, std::strong_ordering::less)); + assert(testOrder(e, f1, std::strong_ordering::less)); + } + // Longer list + { + std::vector l1{true, false}; + std::vector l2{true}; + assert(testOrder(l1, l2, std::strong_ordering::greater)); + + std::vector t1{true, true}; + std::vector t2{true}; + assert(testOrder(t1, t2, std::strong_ordering::greater)); + + std::vector f1{false, false}; + std::vector f2{false}; + assert(testOrder(f1, f2, std::strong_ordering::greater)); + + std::vector e; + assert(testOrder(t2, e, std::strong_ordering::greater)); + assert(testOrder(f2, e, std::strong_ordering::greater)); + } + + return true; +} + +int main(int, char**) { + assert(test_sequence_container_spaceship_vectorbool()); + static_assert(test_sequence_container_spaceship_vectorbool()); + return 0; +} 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,27 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// + +// class vector + +// template +// constexpr synth-three-way-result operator<=>(const vector& x, +// const vector& y); + +#include +#include + +#include "test_container_comparisons.h" + +int main(int, char**) { + assert(test_sequence_container_spaceship()); + static_assert(test_sequence_container_spaceship()); + return 0; +}