[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