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 @@ -37,7 +37,7 @@ | `[string.view.comparison] `_,| `basic_string_view `_,None,Mark de Wever,|Complete| | `[array.syn] `_ (`general `_),| `array `_,[expos.only.func],Adrian Vogelsgesang,|In Progress| | `[deque.syn] `_ (`general `_),| deque,[expos.only.func],Unassigned,|Not Started| -| `[forward.list.syn] `_ (`general `_),| forward_list,[expos.only.func],Unassigned,|Not Started| +| `[forward.list.syn] `_ (`general `_),| forward_list,[expos.only.func],Hristo Hristov,|Completed| | `[list.syn] `_ (`general `_),| `list `_,[expos.only.func],Adrian Vogelsgesang,|Complete| | `[vector.syn] `_ (`general `_),| `vector `_,[expos.only.func],Adrian Vogelsgesang,|In Progress| | `[associative.map.syn] `_ (`general `_),"| map diff --git a/libcxx/include/forward_list b/libcxx/include/forward_list --- a/libcxx/include/forward_list +++ b/libcxx/include/forward_list @@ -146,23 +146,27 @@ template bool operator< (const forward_list& x, - const forward_list& y); + const forward_list& y); // removed in C++20 template bool operator!=(const forward_list& x, - const forward_list& y); + const forward_list& y); // removed in C++20 template bool operator> (const forward_list& x, - const forward_list& y); + const forward_list& y); // removed in C++20 template bool operator>=(const forward_list& x, - const forward_list& y); + const forward_list& y); // removed in C++20 template bool operator<=(const forward_list& x, - const forward_list& y); + const forward_list& y); // removed in C++20 + +template + synth-three-way-result operator<=>(const forward_list& x, + const forward_list& y); // since C++20 template void swap(forward_list& x, forward_list& y) @@ -181,6 +185,7 @@ #include <__algorithm/comp.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> @@ -1711,6 +1716,8 @@ return (__ix == __ex) == (__iy == __ey); } +#if _LIBCPP_STD_VER <= 17 + template inline _LIBCPP_INLINE_VISIBILITY bool operator!=(const forward_list<_Tp, _Alloc>& __x, @@ -1752,6 +1759,18 @@ return !(__y < __x); } +#else // #if _LIBCPP_STD_VER <= 17 + +template +__synth_three_way_result<_Tp> operator<=>(const forward_list<_Tp, _Allocator>& __x, + const forward_list<_Tp, _Allocator>& __y) +{ + return std::lexicographical_compare_three_way( + __x.begin(), __x.end(), __y.begin(), __y.end(), __synth_three_way); +} + +#endif // #if _LIBCPP_STD_VER <= 17 + template inline _LIBCPP_INLINE_VISIBILITY void diff --git a/libcxx/test/libcxx/containers/sequences/forwardlist/compare.three_way.pass.cpp b/libcxx/test/libcxx/containers/sequences/forwardlist/compare.three_way.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/libcxx/containers/sequences/forwardlist/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 +// synth-three-way-result operator<=>(const forward_list& x, +// const forward_list& y); + +#include +#include + +#include "test_container_comparisons.h" + +int main(int, char**) { + assert(test_ordered_container_spaceship()); + // `std::forward_list` is not constexpr, so no `static_assert` test here. + return 0; +}