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 @@ -15,7 +15,7 @@ | `[type.info] `_,| `typeinfo `_,None,Adrian Vogelsgesang,|Complete| | `[coroutine.handle.compare] `_,| `coroutine_handle `_,[comparisons.three.way],Chuanqi Xu,|Complete| | `[pairs.spec] `_,| `pair `_,[expos.only.func],Kent Ross,|Complete| -| `[syserr.errcat.nonvirtuals] `_,| error_category,[comparisons.three.way],Unassigned,|Not Started| +| `[syserr.errcat.nonvirtuals] `_,| `error_category `_,[comparisons.three.way],Adrian Vogelsgesang,|Complete| | `[syserr.compare] `_,"| error_code | error_condition",None,Unassigned,|Not Started| | `[tuple.rel] `_,| `tuple `_,[expos.only.func],Kent Ross,|Complete| diff --git a/libcxx/include/system_error b/libcxx/include/system_error --- a/libcxx/include/system_error +++ b/libcxx/include/system_error @@ -32,8 +32,9 @@ virtual string message(int ev) const = 0; bool operator==(const error_category& rhs) const noexcept; - bool operator!=(const error_category& rhs) const noexcept; - bool operator<(const error_category& rhs) const noexcept; + bool operator!=(const error_category& rhs) const noexcept; // removed in C++20 + bool operator<(const error_category& rhs) const noexcept; // removed in C++20 + strong_ordering operator<=>(const error_category& rhs) const noexcept; // C++20 }; const error_category& generic_category() noexcept; @@ -223,12 +224,21 @@ _LIBCPP_INLINE_VISIBILITY bool operator==(const error_category& __rhs) const _NOEXCEPT {return this == &__rhs;} +#if _LIBCPP_STD_VER <= 17 + _LIBCPP_INLINE_VISIBILITY bool operator!=(const error_category& __rhs) const _NOEXCEPT {return !(*this == __rhs);} _LIBCPP_INLINE_VISIBILITY bool operator< (const error_category& __rhs) const _NOEXCEPT {return this < &__rhs;} +#else // _LIBCPP_STD_VER <= 17 + + _LIBCPP_INLINE_VISIBILITY + strong_ordering operator<=>(const error_category& __rhs) const noexcept {return compare_three_way()(this, &__rhs);} + +#endif // _LIBCPP_STD_VER <= 17 + friend class _LIBCPP_HIDDEN __do_message; }; diff --git a/libcxx/test/std/diagnostics/syserr/syserr.errcat/syserr.errcat.nonvirtuals/cmp.pass.cpp b/libcxx/test/std/diagnostics/syserr/syserr.errcat/syserr.errcat.nonvirtuals/cmp.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/diagnostics/syserr/syserr.errcat/syserr.errcat.nonvirtuals/cmp.pass.cpp @@ -0,0 +1,36 @@ +//===----------------------------------------------------------------------===// +// +// 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 error_category + +// strong_ordering operator<=>(const error_category& rhs) const noexcept; + +#include +#include + +#include "test_macros.h" +#include "test_comparisons.h" + +int main(int, char**) { + AssertOrderAreNoexcept(); + AssertOrderReturn(); + + const std::error_category& e_cat1 = std::generic_category(); + const std::error_category& e_cat2 = std::generic_category(); + const std::error_category& e_cat3 = std::system_category(); + + assert(testOrder(e_cat1, e_cat2, std::strong_ordering::equal)); + + bool isLess = e_cat1 < e_cat3; + assert(testOrder(e_cat1, e_cat3, isLess ? std::strong_ordering::less : std::strong_ordering::greater)); + + return 0; +}