[libcxx-commits] [libcxx] 877620b - [libc++] Implement `operator<=>` for `error_{code, condition}`
Adrian Vogelsgesang via libcxx-commits
libcxx-commits at lists.llvm.org
Mon Aug 15 16:06:42 PDT 2022
Author: Adrian Vogelsgesang
Date: 2022-08-15T16:05:53-07:00
New Revision: 877620bd961851d1ce6891db591b193b85796027
URL: https://github.com/llvm/llvm-project/commit/877620bd961851d1ce6891db591b193b85796027
DIFF: https://github.com/llvm/llvm-project/commit/877620bd961851d1ce6891db591b193b85796027.diff
LOG: [libc++] Implement `operator<=>` for `error_{code,condition}`
Implements part of P1614R2 "The Mothership has Landed"
Differential Revision: https://reviews.llvm.org/D131371
Added:
libcxx/test/std/diagnostics/syserr/syserr.compare/cmp_error_code.pass.cpp
libcxx/test/std/diagnostics/syserr/syserr.compare/cmp_error_condition.pass.cpp
Modified:
libcxx/docs/Status/SpaceshipProjects.csv
libcxx/include/system_error
Removed:
################################################################################
diff --git a/libcxx/docs/Status/SpaceshipProjects.csv b/libcxx/docs/Status/SpaceshipProjects.csv
index 41dc7329675d3..d41dc0dcb6192 100644
--- a/libcxx/docs/Status/SpaceshipProjects.csv
+++ b/libcxx/docs/Status/SpaceshipProjects.csv
@@ -17,7 +17,7 @@ Section,Description,Dependencies,Assignee,Complete
| `[pairs.spec] <https://wg21.link/pairs.spec>`_,| `pair <https://reviews.llvm.org/D107721>`_,[expos.only.func],Kent Ross,|Complete|
| `[syserr.errcat.nonvirtuals] <https://wg21.link/syserr.errcat.nonvirtuals>`_,| `error_category <https://reviews.llvm.org/D131363>`_,[comparisons.three.way],Adrian Vogelsgesang,|Complete|
| `[syserr.compare] <https://wg21.link/syserr.compare>`_,"| `error_code <https://reviews.llvm.org/D131371>`_
-| `error_condition <https://reviews.llvm.org/D131371>`_",None,Adrian Vogelsgesang,|In Progress|
+| `error_condition <https://reviews.llvm.org/D131371>`_",None,Adrian Vogelsgesang,|Complete|
| `[tuple.rel] <https://wg21.link/tuple.rel>`_,| `tuple <https://reviews.llvm.org/D108250>`_,[expos.only.func],Kent Ross,|Complete|
"| `[optional.relops] <https://wg21.link/optional.relops>`_
| `[optional.nullops] <https://wg21.link/optional.nullops>`_
diff --git a/libcxx/include/system_error b/libcxx/include/system_error
index ba36f940f780d..d3732184ff46c 100644
--- a/libcxx/include/system_error
+++ b/libcxx/include/system_error
@@ -76,7 +76,6 @@ public:
};
// non-member functions:
-bool operator<(const error_code& lhs, const error_code& rhs) noexcept;
template <class charT, class traits>
basic_ostream<charT,traits>&
operator<<(basic_ostream<charT,traits>& os, const error_code& ec);
@@ -103,8 +102,6 @@ public:
explicit operator bool() const noexcept;
};
-bool operator<(const error_condition& lhs, const error_condition& rhs) noexcept;
-
class system_error
: public runtime_error
{
@@ -129,12 +126,16 @@ error_condition make_error_condition(errc e) noexcept;
// Comparison operators:
bool operator==(const error_code& lhs, const error_code& rhs) noexcept;
bool operator==(const error_code& lhs, const error_condition& rhs) noexcept;
-bool operator==(const error_condition& lhs, const error_code& rhs) noexcept;
+bool operator==(const error_condition& lhs, const error_code& rhs) noexcept; // removed in C++20
bool operator==(const error_condition& lhs, const error_condition& rhs) noexcept;
-bool operator!=(const error_code& lhs, const error_code& rhs) noexcept;
-bool operator!=(const error_code& lhs, const error_condition& rhs) noexcept;
-bool operator!=(const error_condition& lhs, const error_code& rhs) noexcept;
-bool operator!=(const error_condition& lhs, const error_condition& rhs) noexcept;
+bool operator!=(const error_code& lhs, const error_code& rhs) noexcept; // removed in C++20
+bool operator!=(const error_code& lhs, const error_condition& rhs) noexcept; // removed in C++20
+bool operator!=(const error_condition& lhs, const error_code& rhs) noexcept; // removed in C++20
+bool operator!=(const error_condition& lhs, const error_condition& rhs) noexcept; // removed in C++20
+bool operator<(const error_condition& lhs, const error_condition& rhs) noexcept; // removed in C++20
+bool operator<(const error_code& lhs, const error_code& rhs) noexcept; // removed in C++20
+strong_ordering operator<=>(const error_code& lhs, const error_code& rhs) noexcept; // C++20
+strong_ordering operator<=>(const error_condition& lhs, const error_condition& rhs) noexcept; // C++20
template <> struct hash<std::error_code>;
template <> struct hash<std::error_condition>;
@@ -314,14 +315,6 @@ make_error_condition(errc __e) _NOEXCEPT
return error_condition(static_cast<int>(__e), generic_category());
}
-inline _LIBCPP_INLINE_VISIBILITY
-bool
-operator<(const error_condition& __x, const error_condition& __y) _NOEXCEPT
-{
- return __x.category() < __y.category()
- || (__x.category() == __y.category() && __x.value() < __y.value());
-}
-
// error_code
class _LIBCPP_TYPE_VIS error_code
@@ -390,14 +383,6 @@ make_error_code(errc __e) _NOEXCEPT
return error_code(static_cast<int>(__e), generic_category());
}
-inline _LIBCPP_INLINE_VISIBILITY
-bool
-operator<(const error_code& __x, const error_code& __y) _NOEXCEPT
-{
- return __x.category() < __y.category()
- || (__x.category() == __y.category() && __x.value() < __y.value());
-}
-
inline _LIBCPP_INLINE_VISIBILITY
bool
operator==(const error_code& __x, const error_code& __y) _NOEXCEPT
@@ -413,12 +398,14 @@ operator==(const error_code& __x, const error_condition& __y) _NOEXCEPT
|| __y.category().equivalent(__x, __y.value());
}
+#if _LIBCPP_STD_VER <= 17
inline _LIBCPP_INLINE_VISIBILITY
bool
operator==(const error_condition& __x, const error_code& __y) _NOEXCEPT
{
return __y == __x;
}
+#endif
inline _LIBCPP_INLINE_VISIBILITY
bool
@@ -427,6 +414,8 @@ operator==(const error_condition& __x, const error_condition& __y) _NOEXCEPT
return __x.category() == __y.category() && __x.value() == __y.value();
}
+#if _LIBCPP_STD_VER <= 17
+
inline _LIBCPP_INLINE_VISIBILITY
bool
operator!=(const error_code& __x, const error_code& __y) _NOEXCEPT
@@ -447,6 +436,42 @@ bool
operator!=(const error_condition& __x, const error_condition& __y) _NOEXCEPT
{return !(__x == __y);}
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator<(const error_condition& __x, const error_condition& __y) _NOEXCEPT
+{
+ return __x.category() < __y.category()
+ || (__x.category() == __y.category() && __x.value() < __y.value());
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator<(const error_code& __x, const error_code& __y) _NOEXCEPT
+{
+ return __x.category() < __y.category()
+ || (__x.category() == __y.category() && __x.value() < __y.value());
+}
+
+#else // _LIBCPP_STD_VER <= 17
+
+inline _LIBCPP_HIDE_FROM_ABI strong_ordering
+operator<=>(const error_code& __x, const error_code& __y) noexcept
+{
+ if (auto __c = __x.category() <=> __y.category(); __c != 0)
+ return __c;
+ return __x.value() <=> __y.value();
+}
+
+inline _LIBCPP_HIDE_FROM_ABI strong_ordering
+operator<=>(const error_condition& __x, const error_condition& __y) noexcept
+{
+ if (auto __c = __x.category() <=> __y.category(); __c != 0)
+ return __c;
+ return __x.value() <=> __y.value();
+}
+
+#endif // _LIBCPP_STD_VER <= 17
+
template <>
struct _LIBCPP_TEMPLATE_VIS hash<error_code>
: public __unary_function<error_code, size_t>
diff --git a/libcxx/test/std/diagnostics/syserr/syserr.compare/cmp_error_code.pass.cpp b/libcxx/test/std/diagnostics/syserr/syserr.compare/cmp_error_code.pass.cpp
new file mode 100644
index 0000000000000..1fac9d547fb15
--- /dev/null
+++ b/libcxx/test/std/diagnostics/syserr/syserr.compare/cmp_error_code.pass.cpp
@@ -0,0 +1,41 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <system_error>
+
+// class error_code
+
+// strong_ordering operator<=>(const error_code& lhs, const error_code& rhs) noexcept
+
+#include <system_error>
+#include <cassert>
+
+#include "test_macros.h"
+#include "test_comparisons.h"
+
+int main(int, char**) {
+ AssertOrderAreNoexcept<std::error_code>();
+ AssertOrderReturn<std::strong_ordering, std::error_code>();
+
+ // Same error category
+ std::error_code ec1a = std::error_code(1, std::generic_category());
+ std::error_code ec1b = std::error_code(1, std::generic_category());
+ std::error_code ec2 = std::error_code(2, std::generic_category());
+
+ assert(testOrder(ec1a, ec1b, std::strong_ordering::equal));
+ assert(testOrder(ec1a, ec2, std::strong_ordering::less));
+
+ // Different error category
+ const std::error_code& ec3 = std::error_code(2, std::system_category());
+
+ bool isLess = ec2 < ec3;
+ assert(testOrder(ec2, ec3, isLess ? std::strong_ordering::less : std::strong_ordering::greater));
+
+ return 0;
+}
diff --git a/libcxx/test/std/diagnostics/syserr/syserr.compare/cmp_error_condition.pass.cpp b/libcxx/test/std/diagnostics/syserr/syserr.compare/cmp_error_condition.pass.cpp
new file mode 100644
index 0000000000000..cb84550ddc4db
--- /dev/null
+++ b/libcxx/test/std/diagnostics/syserr/syserr.compare/cmp_error_condition.pass.cpp
@@ -0,0 +1,41 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <system_error>
+
+// class error_condition
+
+// strong_ordering operator<=>(const error_condition& lhs, const error_condition& rhs) noexcept
+
+#include <system_error>
+#include <cassert>
+
+#include "test_macros.h"
+#include "test_comparisons.h"
+
+int main(int, char**) {
+ AssertOrderAreNoexcept<std::error_condition>();
+ AssertOrderReturn<std::strong_ordering, std::error_condition>();
+
+ // Same error category
+ std::error_condition ec1a = std::error_condition(1, std::generic_category());
+ std::error_condition ec1b = std::error_condition(1, std::generic_category());
+ std::error_condition ec2 = std::error_condition(2, std::generic_category());
+
+ assert(testOrder(ec1a, ec1b, std::strong_ordering::equal));
+ assert(testOrder(ec1a, ec2, std::strong_ordering::less));
+
+ // Different error category
+ const std::error_condition& ec3 = std::error_condition(2, std::system_category());
+
+ bool isLess = ec2 < ec3;
+ assert(testOrder(ec2, ec3, isLess ? std::strong_ordering::less : std::strong_ordering::greater));
+
+ return 0;
+}
More information about the libcxx-commits
mailing list