[libcxx-commits] [libcxx] [libc++][test] Test SFINAE for `optional`'s operators in C++17 (PR #221643)
A. Jiang via libcxx-commits
libcxx-commits at lists.llvm.org
Mon Sep 7 00:40:08 PDT 2026
https://github.com/frederick-vs-ja updated https://github.com/llvm/llvm-project/pull/221643
>From 51a3bdc0087094200ae046a71a624375b28d1bc9 Mon Sep 17 00:00:00 2001
From: "A. Jiang" <de34 at live.cn>
Date: Mon, 7 Sep 2026 13:52:43 +0800
Subject: [PATCH] [libc++][test] Test SFINAE for `optional`'s operators in
C++17
We have been intentionally constraining `optional`'s comparison
operators since C++17, so it is probably better to test the constraints
in C++17 mode. Given the constraints are standardized only since C++26
(via P2944R3), `LIBCPP_STATIC_ASSERT` is used in old modes.
In order to do this, `test_comparisons.h` is reworked to expose
`NonComparable` and `EqualityComparable` in pre-C++20 modes, and a new
type `TotallyOrdered` is invented as a replacement of
`ThreeWayComparable` in old modes.
As drive-by, also switches to use `// REQUIRES: std-at-least-c++17` in
touched test files, and adds previously missed includes of
`<type_traits>`.
---
.../optional.comp_with_t/equal.pass.cpp | 35 ++--
.../optional.comp_with_t/greater.pass.cpp | 35 ++--
.../greater_equal.pass.cpp | 35 ++--
.../optional.comp_with_t/less_equal.pass.cpp | 35 ++--
.../optional.comp_with_t/less_than.pass.cpp | 35 ++--
.../optional.comp_with_t/not_equal.pass.cpp | 35 ++--
.../optional/optional.relops/equal.pass.cpp | 20 ++-
.../optional.relops/greater_equal.pass.cpp | 18 +-
.../optional.relops/greater_than.pass.cpp | 19 ++-
.../optional.relops/less_equal.pass.cpp | 18 +-
.../optional.relops/less_than.pass.cpp | 18 +-
.../optional.relops/not_equal.pass.cpp | 20 ++-
libcxx/test/support/test_comparisons.h | 156 +++++++++++++++---
13 files changed, 310 insertions(+), 169 deletions(-)
diff --git a/libcxx/test/std/utilities/optional/optional.comp_with_t/equal.pass.cpp b/libcxx/test/std/utilities/optional/optional.comp_with_t/equal.pass.cpp
index 99813dae89031..d33caab090b3b 100644
--- a/libcxx/test/std/utilities/optional/optional.comp_with_t/equal.pass.cpp
+++ b/libcxx/test/std/utilities/optional/optional.comp_with_t/equal.pass.cpp
@@ -6,18 +6,23 @@
//
//===----------------------------------------------------------------------===//
-// UNSUPPORTED: c++03, c++11, c++14
+// REQUIRES: std-at-least-c++17
// <optional>
// template <class T, class U> constexpr bool operator==(const optional<T>& x, const U& v);
// template <class T, class U> constexpr bool operator==(const U& v, const optional<T>& x);
#include <optional>
+#include <type_traits>
#include "test_comparisons.h"
#include "test_macros.h"
#if TEST_STD_VER >= 26
+# define STATIC_ASSERT_OPTIONAL_CMP static_assert
+#else
+# define STATIC_ASSERT_OPTIONAL_CMP LIBCPP_STATIC_ASSERT
+#endif
struct tester {};
@@ -32,7 +37,7 @@ constexpr bool operator==(const T& t, const tester& a) {
template <class T, class U>
constexpr std::optional<bool> try_cmp_eq(const T& t, const U& u) {
- if constexpr (requires { t == u; })
+ if constexpr (HasOperatorEqual<const T, const U>)
return t == u;
else
return {};
@@ -40,25 +45,23 @@ constexpr std::optional<bool> try_cmp_eq(const T& t, const U& u) {
// Test SFINAE.
-static_assert(HasOperatorEqual<int, std::optional<int>>);
-static_assert(HasOperatorEqual<int, std::optional<EqualityComparable>>);
-static_assert(HasOperatorEqual<EqualityComparable, std::optional<EqualityComparable>>);
+STATIC_ASSERT_OPTIONAL_CMP(HasOperatorEqual<int, std::optional<int>>);
+STATIC_ASSERT_OPTIONAL_CMP(HasOperatorEqual<int, std::optional<EqualityComparable>>);
+STATIC_ASSERT_OPTIONAL_CMP(HasOperatorEqual<EqualityComparable, std::optional<EqualityComparable>>);
-static_assert(!HasOperatorEqual<NonComparable, std::optional<NonComparable>>);
-static_assert(!HasOperatorEqual<NonComparable, std::optional<EqualityComparable>>);
+STATIC_ASSERT_OPTIONAL_CMP(!HasOperatorEqual<NonComparable, std::optional<NonComparable>>);
+STATIC_ASSERT_OPTIONAL_CMP(!HasOperatorEqual<NonComparable, std::optional<EqualityComparable>>);
-static_assert(HasOperatorEqual<std::optional<int>, int>);
-static_assert(HasOperatorEqual<std::optional<EqualityComparable>, int>);
-static_assert(HasOperatorEqual<std::optional<EqualityComparable>, EqualityComparable>);
+STATIC_ASSERT_OPTIONAL_CMP(HasOperatorEqual<std::optional<int>, int>);
+STATIC_ASSERT_OPTIONAL_CMP(HasOperatorEqual<std::optional<EqualityComparable>, int>);
+STATIC_ASSERT_OPTIONAL_CMP(HasOperatorEqual<std::optional<EqualityComparable>, EqualityComparable>);
-static_assert(!HasOperatorEqual<std::optional<NonComparable>, NonComparable>);
-static_assert(!HasOperatorEqual<std::optional<EqualityComparable>, NonComparable>);
+STATIC_ASSERT_OPTIONAL_CMP(!HasOperatorEqual<std::optional<NonComparable>, NonComparable>);
+STATIC_ASSERT_OPTIONAL_CMP(!HasOperatorEqual<std::optional<EqualityComparable>, NonComparable>);
// LWG4072: avoid ambiguity with optional's own comparison operators
-static_assert(try_cmp_eq(std::optional<int>{}, std::optional<tester>{}) == std::optional<bool>{});
-static_assert(try_cmp_eq(std::optional<int>{}, std::optional<int>{}) == std::optional<bool>{true});
-
-#endif
+STATIC_ASSERT_OPTIONAL_CMP(try_cmp_eq(std::optional<int>{}, std::optional<tester>{}) == std::optional<bool>{});
+STATIC_ASSERT_OPTIONAL_CMP(try_cmp_eq(std::optional<int>{}, std::optional<int>{}) == std::optional<bool>{true});
using std::optional;
diff --git a/libcxx/test/std/utilities/optional/optional.comp_with_t/greater.pass.cpp b/libcxx/test/std/utilities/optional/optional.comp_with_t/greater.pass.cpp
index a945cf4b54002..a4a3f0922b8b6 100644
--- a/libcxx/test/std/utilities/optional/optional.comp_with_t/greater.pass.cpp
+++ b/libcxx/test/std/utilities/optional/optional.comp_with_t/greater.pass.cpp
@@ -6,18 +6,23 @@
//
//===----------------------------------------------------------------------===//
-// UNSUPPORTED: c++03, c++11, c++14
+// REQUIRES: std-at-least-c++17
// <optional>
// template <class T, class U> constexpr bool operator>(const optional<T>& x, const U& v);
// template <class T, class U> constexpr bool operator>(const U& v, const optional<T>& x);
#include <optional>
+#include <type_traits>
#include "test_comparisons.h"
#include "test_macros.h"
#if TEST_STD_VER >= 26
+# define STATIC_ASSERT_OPTIONAL_CMP static_assert
+#else
+# define STATIC_ASSERT_OPTIONAL_CMP LIBCPP_STATIC_ASSERT
+#endif
struct tester {};
@@ -32,32 +37,30 @@ constexpr bool operator>(const T& t, const tester& a) {
template <class T, class U>
constexpr std::optional<bool> try_cmp_gt(const T& t, const U& u) {
- if constexpr (requires { t > u; })
+ if constexpr (HasOperatorGreaterThan<const T, const U>)
return t > u;
else
return {};
}
// Test SFINAE.
-static_assert(HasOperatorGreaterThan<std::optional<ThreeWayComparable>, int>);
-static_assert(HasOperatorGreaterThan<std::optional<ThreeWayComparable>, ThreeWayComparable>);
+STATIC_ASSERT_OPTIONAL_CMP(HasOperatorGreaterThan<std::optional<TotallyOrdered>, int>);
+STATIC_ASSERT_OPTIONAL_CMP(HasOperatorGreaterThan<std::optional<TotallyOrdered>, TotallyOrdered>);
-static_assert(!HasOperatorGreaterThan<std::optional<NonComparable>, NonComparable>);
-static_assert(!HasOperatorGreaterThan<std::optional<ThreeWayComparable>, NonComparable>);
-static_assert(!HasOperatorGreaterThan<std::optional<NonComparable>, ThreeWayComparable>);
+STATIC_ASSERT_OPTIONAL_CMP(!HasOperatorGreaterThan<std::optional<NonComparable>, NonComparable>);
+STATIC_ASSERT_OPTIONAL_CMP(!HasOperatorGreaterThan<std::optional<TotallyOrdered>, NonComparable>);
+STATIC_ASSERT_OPTIONAL_CMP(!HasOperatorGreaterThan<std::optional<NonComparable>, TotallyOrdered>);
-static_assert(HasOperatorGreaterThan<int, std::optional<ThreeWayComparable>>);
-static_assert(HasOperatorGreaterThan<ThreeWayComparable, std::optional<ThreeWayComparable>>);
+STATIC_ASSERT_OPTIONAL_CMP(HasOperatorGreaterThan<int, std::optional<TotallyOrdered>>);
+STATIC_ASSERT_OPTIONAL_CMP(HasOperatorGreaterThan<TotallyOrdered, std::optional<TotallyOrdered>>);
-static_assert(!HasOperatorGreaterThan<NonComparable, std::optional<NonComparable>>);
-static_assert(!HasOperatorGreaterThan<NonComparable, std::optional<ThreeWayComparable>>);
-static_assert(!HasOperatorGreaterThan<ThreeWayComparable, std::optional<NonComparable>>);
+STATIC_ASSERT_OPTIONAL_CMP(!HasOperatorGreaterThan<NonComparable, std::optional<NonComparable>>);
+STATIC_ASSERT_OPTIONAL_CMP(!HasOperatorGreaterThan<NonComparable, std::optional<TotallyOrdered>>);
+STATIC_ASSERT_OPTIONAL_CMP(!HasOperatorGreaterThan<TotallyOrdered, std::optional<NonComparable>>);
// LWG4072: avoid ambiguity with optional's own comparison operators
-static_assert(try_cmp_gt(std::optional<int>{}, std::optional<tester>{}) == std::optional<bool>{});
-static_assert(try_cmp_gt(std::optional<int>{}, std::optional<int>{}) == std::optional<bool>{false});
-
-#endif
+STATIC_ASSERT_OPTIONAL_CMP(try_cmp_gt(std::optional<int>{}, std::optional<tester>{}) == std::optional<bool>{});
+STATIC_ASSERT_OPTIONAL_CMP(try_cmp_gt(std::optional<int>{}, std::optional<int>{}) == std::optional<bool>{false});
using std::optional;
diff --git a/libcxx/test/std/utilities/optional/optional.comp_with_t/greater_equal.pass.cpp b/libcxx/test/std/utilities/optional/optional.comp_with_t/greater_equal.pass.cpp
index 8e18568bfe6d7..4cb4fb6092376 100644
--- a/libcxx/test/std/utilities/optional/optional.comp_with_t/greater_equal.pass.cpp
+++ b/libcxx/test/std/utilities/optional/optional.comp_with_t/greater_equal.pass.cpp
@@ -6,18 +6,23 @@
//
//===----------------------------------------------------------------------===//
-// UNSUPPORTED: c++03, c++11, c++14
+// REQUIRES: std-at-least-c++17
// <optional>
// template <class T, class U> constexpr bool operator>=(const optional<T>& x, const U& v);
// template <class T, class U> constexpr bool operator>=(const U& v, const optional<T>& x);
#include <optional>
+#include <type_traits>
#include "test_comparisons.h"
#include "test_macros.h"
#if TEST_STD_VER >= 26
+# define STATIC_ASSERT_OPTIONAL_CMP static_assert
+#else
+# define STATIC_ASSERT_OPTIONAL_CMP LIBCPP_STATIC_ASSERT
+#endif
struct tester {};
@@ -32,32 +37,30 @@ constexpr bool operator>=(const T& t, const tester& a) {
template <class T, class U>
constexpr std::optional<bool> try_cmp_gteq(const T& t, const U& u) {
- if constexpr (requires { t >= u; })
+ if constexpr (HasOperatorGreaterThanEqual<const T, const U>)
return t >= u;
else
return {};
}
// Test SFINAE.
-static_assert(HasOperatorGreaterThanEqual<std::optional<ThreeWayComparable>, int>);
-static_assert(HasOperatorGreaterThanEqual<std::optional<ThreeWayComparable>, ThreeWayComparable>);
+STATIC_ASSERT_OPTIONAL_CMP(HasOperatorGreaterThanEqual<std::optional<TotallyOrdered>, int>);
+STATIC_ASSERT_OPTIONAL_CMP(HasOperatorGreaterThanEqual<std::optional<TotallyOrdered>, TotallyOrdered>);
-static_assert(!HasOperatorGreaterThanEqual<std::optional<NonComparable>, NonComparable>);
-static_assert(!HasOperatorGreaterThanEqual<std::optional<ThreeWayComparable>, NonComparable>);
-static_assert(!HasOperatorGreaterThanEqual<std::optional<NonComparable>, ThreeWayComparable>);
+STATIC_ASSERT_OPTIONAL_CMP(!HasOperatorGreaterThanEqual<std::optional<NonComparable>, NonComparable>);
+STATIC_ASSERT_OPTIONAL_CMP(!HasOperatorGreaterThanEqual<std::optional<TotallyOrdered>, NonComparable>);
+STATIC_ASSERT_OPTIONAL_CMP(!HasOperatorGreaterThanEqual<std::optional<NonComparable>, TotallyOrdered>);
-static_assert(HasOperatorGreaterThanEqual<int, std::optional<ThreeWayComparable>>);
-static_assert(HasOperatorGreaterThanEqual<ThreeWayComparable, std::optional<ThreeWayComparable>>);
+STATIC_ASSERT_OPTIONAL_CMP(HasOperatorGreaterThanEqual<int, std::optional<TotallyOrdered>>);
+STATIC_ASSERT_OPTIONAL_CMP(HasOperatorGreaterThanEqual<TotallyOrdered, std::optional<TotallyOrdered>>);
-static_assert(!HasOperatorGreaterThanEqual<NonComparable, std::optional<NonComparable>>);
-static_assert(!HasOperatorGreaterThanEqual<NonComparable, std::optional<ThreeWayComparable>>);
-static_assert(!HasOperatorGreaterThanEqual<ThreeWayComparable, std::optional<NonComparable>>);
+STATIC_ASSERT_OPTIONAL_CMP(!HasOperatorGreaterThanEqual<NonComparable, std::optional<NonComparable>>);
+STATIC_ASSERT_OPTIONAL_CMP(!HasOperatorGreaterThanEqual<NonComparable, std::optional<TotallyOrdered>>);
+STATIC_ASSERT_OPTIONAL_CMP(!HasOperatorGreaterThanEqual<TotallyOrdered, std::optional<NonComparable>>);
// LWG4072: avoid ambiguity with optional's own comparison operators
-static_assert(try_cmp_gteq(std::optional<int>{}, std::optional<tester>{}) == std::optional<bool>{});
-static_assert(try_cmp_gteq(std::optional<int>{}, std::optional<int>{}) == std::optional<bool>{true});
-
-#endif
+STATIC_ASSERT_OPTIONAL_CMP(try_cmp_gteq(std::optional<int>{}, std::optional<tester>{}) == std::optional<bool>{});
+STATIC_ASSERT_OPTIONAL_CMP(try_cmp_gteq(std::optional<int>{}, std::optional<int>{}) == std::optional<bool>{true});
using std::optional;
diff --git a/libcxx/test/std/utilities/optional/optional.comp_with_t/less_equal.pass.cpp b/libcxx/test/std/utilities/optional/optional.comp_with_t/less_equal.pass.cpp
index c937d7b2a5faf..81bd00bbba579 100644
--- a/libcxx/test/std/utilities/optional/optional.comp_with_t/less_equal.pass.cpp
+++ b/libcxx/test/std/utilities/optional/optional.comp_with_t/less_equal.pass.cpp
@@ -6,18 +6,23 @@
//
//===----------------------------------------------------------------------===//
-// UNSUPPORTED: c++03, c++11, c++14
+// REQUIRES: std-at-least-c++17
// <optional>
// template <class T, class U> constexpr bool operator<=(const optional<T>& x, const U& v);
// template <class T, class U> constexpr bool operator<=(const U& v, const optional<T>& x);
#include <optional>
+#include <type_traits>
#include "test_comparisons.h"
#include "test_macros.h"
#if TEST_STD_VER >= 26
+# define STATIC_ASSERT_OPTIONAL_CMP static_assert
+#else
+# define STATIC_ASSERT_OPTIONAL_CMP LIBCPP_STATIC_ASSERT
+#endif
struct tester {};
@@ -32,32 +37,30 @@ constexpr bool operator<=(const T& t, const tester& a) {
template <class T, class U>
constexpr std::optional<bool> try_cmp_lteq(const T& t, const U& u) {
- if constexpr (requires { t <= u; })
+ if constexpr (HasOperatorLessThanEqual<const T, const U>)
return t <= u;
else
return {};
}
// Test SFINAE.
-static_assert(HasOperatorLessThanEqual<std::optional<ThreeWayComparable>, int>);
-static_assert(HasOperatorLessThanEqual<std::optional<ThreeWayComparable>, ThreeWayComparable>);
+STATIC_ASSERT_OPTIONAL_CMP(HasOperatorLessThanEqual<std::optional<TotallyOrdered>, int>);
+STATIC_ASSERT_OPTIONAL_CMP(HasOperatorLessThanEqual<std::optional<TotallyOrdered>, TotallyOrdered>);
-static_assert(!HasOperatorLessThanEqual<std::optional<NonComparable>, NonComparable>);
-static_assert(!HasOperatorLessThanEqual<std::optional<ThreeWayComparable>, NonComparable>);
-static_assert(!HasOperatorLessThanEqual<std::optional<NonComparable>, ThreeWayComparable>);
+STATIC_ASSERT_OPTIONAL_CMP(!HasOperatorLessThanEqual<std::optional<NonComparable>, NonComparable>);
+STATIC_ASSERT_OPTIONAL_CMP(!HasOperatorLessThanEqual<std::optional<TotallyOrdered>, NonComparable>);
+STATIC_ASSERT_OPTIONAL_CMP(!HasOperatorLessThanEqual<std::optional<NonComparable>, TotallyOrdered>);
-static_assert(HasOperatorLessThanEqual<int, std::optional<ThreeWayComparable>>);
-static_assert(HasOperatorLessThanEqual<ThreeWayComparable, std::optional<ThreeWayComparable>>);
+STATIC_ASSERT_OPTIONAL_CMP(HasOperatorLessThanEqual<int, std::optional<TotallyOrdered>>);
+STATIC_ASSERT_OPTIONAL_CMP(HasOperatorLessThanEqual<TotallyOrdered, std::optional<TotallyOrdered>>);
-static_assert(!HasOperatorLessThanEqual<NonComparable, std::optional<NonComparable>>);
-static_assert(!HasOperatorLessThanEqual<NonComparable, std::optional<ThreeWayComparable>>);
-static_assert(!HasOperatorLessThanEqual<ThreeWayComparable, std::optional<NonComparable>>);
+STATIC_ASSERT_OPTIONAL_CMP(!HasOperatorLessThanEqual<NonComparable, std::optional<NonComparable>>);
+STATIC_ASSERT_OPTIONAL_CMP(!HasOperatorLessThanEqual<NonComparable, std::optional<TotallyOrdered>>);
+STATIC_ASSERT_OPTIONAL_CMP(!HasOperatorLessThanEqual<TotallyOrdered, std::optional<NonComparable>>);
// LWG4072: avoid ambiguity with optional's own comparison operators
-static_assert(try_cmp_lteq(std::optional<int>{}, std::optional<tester>{}) == std::optional<bool>{});
-static_assert(try_cmp_lteq(std::optional<int>{}, std::optional<int>{}) == std::optional<bool>{true});
-
-#endif
+STATIC_ASSERT_OPTIONAL_CMP(try_cmp_lteq(std::optional<int>{}, std::optional<tester>{}) == std::optional<bool>{});
+STATIC_ASSERT_OPTIONAL_CMP(try_cmp_lteq(std::optional<int>{}, std::optional<int>{}) == std::optional<bool>{true});
using std::optional;
diff --git a/libcxx/test/std/utilities/optional/optional.comp_with_t/less_than.pass.cpp b/libcxx/test/std/utilities/optional/optional.comp_with_t/less_than.pass.cpp
index 9a1aa0c65f272..5ffed14348345 100644
--- a/libcxx/test/std/utilities/optional/optional.comp_with_t/less_than.pass.cpp
+++ b/libcxx/test/std/utilities/optional/optional.comp_with_t/less_than.pass.cpp
@@ -6,18 +6,23 @@
//
//===----------------------------------------------------------------------===//
-// UNSUPPORTED: c++03, c++11, c++14
+// REQUIRES: std-at-least-c++17
// <optional>
// template <class T, class U> constexpr bool operator<(const optional<T>& x, const U& v);
// template <class T, class U> constexpr bool operator<(const U& v, const optional<T>& x);
#include <optional>
+#include <type_traits>
#include "test_comparisons.h"
#include "test_macros.h"
#if TEST_STD_VER >= 26
+# define STATIC_ASSERT_OPTIONAL_CMP static_assert
+#else
+# define STATIC_ASSERT_OPTIONAL_CMP LIBCPP_STATIC_ASSERT
+#endif
struct tester {};
@@ -32,32 +37,30 @@ constexpr bool operator<(const T& t, const tester& a) {
template <class T, class U>
constexpr std::optional<bool> try_cmp_lt(const T& t, const U& u) {
- if constexpr (requires { t < u; })
+ if constexpr (HasOperatorLessThan<const T, const U>)
return t < u;
else
return {};
}
// Test SFINAE.
-static_assert(HasOperatorLessThan<std::optional<ThreeWayComparable>, int>);
-static_assert(HasOperatorLessThan<std::optional<ThreeWayComparable>, ThreeWayComparable>);
+STATIC_ASSERT_OPTIONAL_CMP(HasOperatorLessThan<std::optional<TotallyOrdered>, int>);
+STATIC_ASSERT_OPTIONAL_CMP(HasOperatorLessThan<std::optional<TotallyOrdered>, TotallyOrdered>);
-static_assert(!HasOperatorLessThan<std::optional<NonComparable>, NonComparable>);
-static_assert(!HasOperatorLessThan<std::optional<ThreeWayComparable>, NonComparable>);
-static_assert(!HasOperatorLessThan<std::optional<NonComparable>, ThreeWayComparable>);
+STATIC_ASSERT_OPTIONAL_CMP(!HasOperatorLessThan<std::optional<NonComparable>, NonComparable>);
+STATIC_ASSERT_OPTIONAL_CMP(!HasOperatorLessThan<std::optional<TotallyOrdered>, NonComparable>);
+STATIC_ASSERT_OPTIONAL_CMP(!HasOperatorLessThan<std::optional<NonComparable>, TotallyOrdered>);
-static_assert(HasOperatorLessThan<int, std::optional<ThreeWayComparable>>);
-static_assert(HasOperatorLessThan<ThreeWayComparable, std::optional<ThreeWayComparable>>);
+STATIC_ASSERT_OPTIONAL_CMP(HasOperatorLessThan<int, std::optional<TotallyOrdered>>);
+STATIC_ASSERT_OPTIONAL_CMP(HasOperatorLessThan<TotallyOrdered, std::optional<TotallyOrdered>>);
-static_assert(!HasOperatorLessThan<NonComparable, std::optional<NonComparable>>);
-static_assert(!HasOperatorLessThan<NonComparable, std::optional<ThreeWayComparable>>);
-static_assert(!HasOperatorLessThan<ThreeWayComparable, std::optional<NonComparable>>);
+STATIC_ASSERT_OPTIONAL_CMP(!HasOperatorLessThan<NonComparable, std::optional<NonComparable>>);
+STATIC_ASSERT_OPTIONAL_CMP(!HasOperatorLessThan<NonComparable, std::optional<TotallyOrdered>>);
+STATIC_ASSERT_OPTIONAL_CMP(!HasOperatorLessThan<TotallyOrdered, std::optional<NonComparable>>);
// LWG4072: avoid ambiguity with optional's own comparison operators
-static_assert(try_cmp_lt(std::optional<int>{}, std::optional<tester>{}) == std::optional<bool>{});
-static_assert(try_cmp_lt(std::optional<int>{}, std::optional<int>{}) == std::optional<bool>{false});
-
-#endif
+STATIC_ASSERT_OPTIONAL_CMP(try_cmp_lt(std::optional<int>{}, std::optional<tester>{}) == std::optional<bool>{});
+STATIC_ASSERT_OPTIONAL_CMP(try_cmp_lt(std::optional<int>{}, std::optional<int>{}) == std::optional<bool>{false});
using std::optional;
diff --git a/libcxx/test/std/utilities/optional/optional.comp_with_t/not_equal.pass.cpp b/libcxx/test/std/utilities/optional/optional.comp_with_t/not_equal.pass.cpp
index e7940b9b421a3..8c9e6e2d73e9f 100644
--- a/libcxx/test/std/utilities/optional/optional.comp_with_t/not_equal.pass.cpp
+++ b/libcxx/test/std/utilities/optional/optional.comp_with_t/not_equal.pass.cpp
@@ -6,18 +6,23 @@
//
//===----------------------------------------------------------------------===//
-// UNSUPPORTED: c++03, c++11, c++14
+// REQUIRES: std-at-least-c++17
// <optional>
// template <class T, class U> constexpr bool operator!=(const optional<T>& x, const U& v);
// template <class T, class U> constexpr bool operator!=(const U& v, const optional<T>& x);
#include <optional>
+#include <type_traits>
#include "test_comparisons.h"
#include "test_macros.h"
#if TEST_STD_VER >= 26
+# define STATIC_ASSERT_OPTIONAL_CMP static_assert
+#else
+# define STATIC_ASSERT_OPTIONAL_CMP LIBCPP_STATIC_ASSERT
+#endif
struct tester {};
@@ -32,7 +37,7 @@ constexpr bool operator!=(const T& t, const tester& a) {
template <class T, class U>
constexpr std::optional<bool> try_cmp_neq(const T& t, const U& u) {
- if constexpr (requires { t != u; })
+ if constexpr (HasOperatorNotEqual<const T, const U>)
return t != u;
else
return {};
@@ -40,25 +45,23 @@ constexpr std::optional<bool> try_cmp_neq(const T& t, const U& u) {
// Test SFINAE.
-static_assert(HasOperatorNotEqual<int, std::optional<int>>);
-static_assert(HasOperatorNotEqual<int, std::optional<EqualityComparable>>);
-static_assert(HasOperatorNotEqual<EqualityComparable, std::optional<EqualityComparable>>);
+STATIC_ASSERT_OPTIONAL_CMP(HasOperatorNotEqual<int, std::optional<int>>);
+STATIC_ASSERT_OPTIONAL_CMP(HasOperatorNotEqual<int, std::optional<EqualityComparable>>);
+STATIC_ASSERT_OPTIONAL_CMP(HasOperatorNotEqual<EqualityComparable, std::optional<EqualityComparable>>);
-static_assert(!HasOperatorNotEqual<NonComparable, std::optional<NonComparable>>);
-static_assert(!HasOperatorNotEqual<NonComparable, std::optional<EqualityComparable>>);
+STATIC_ASSERT_OPTIONAL_CMP(!HasOperatorNotEqual<NonComparable, std::optional<NonComparable>>);
+STATIC_ASSERT_OPTIONAL_CMP(!HasOperatorNotEqual<NonComparable, std::optional<EqualityComparable>>);
-static_assert(HasOperatorNotEqual<std::optional<int>, int>);
-static_assert(HasOperatorNotEqual<std::optional<EqualityComparable>, int>);
-static_assert(HasOperatorNotEqual<std::optional<EqualityComparable>, EqualityComparable>);
+STATIC_ASSERT_OPTIONAL_CMP(HasOperatorNotEqual<std::optional<int>, int>);
+STATIC_ASSERT_OPTIONAL_CMP(HasOperatorNotEqual<std::optional<EqualityComparable>, int>);
+STATIC_ASSERT_OPTIONAL_CMP(HasOperatorNotEqual<std::optional<EqualityComparable>, EqualityComparable>);
-static_assert(!HasOperatorNotEqual<std::optional<NonComparable>, NonComparable>);
-static_assert(!HasOperatorNotEqual<std::optional<EqualityComparable>, NonComparable>);
+STATIC_ASSERT_OPTIONAL_CMP(!HasOperatorNotEqual<std::optional<NonComparable>, NonComparable>);
+STATIC_ASSERT_OPTIONAL_CMP(!HasOperatorNotEqual<std::optional<EqualityComparable>, NonComparable>);
// LWG4072: avoid ambiguity with optional's own comparison operators
-static_assert(try_cmp_neq(std::optional<int>{}, std::optional<tester>{}) == std::optional<bool>{});
-static_assert(try_cmp_neq(std::optional<int>{}, std::optional<int>{}) == std::optional<bool>{false});
-
-#endif
+STATIC_ASSERT_OPTIONAL_CMP(try_cmp_neq(std::optional<int>{}, std::optional<tester>{}) == std::optional<bool>{});
+STATIC_ASSERT_OPTIONAL_CMP(try_cmp_neq(std::optional<int>{}, std::optional<int>{}) == std::optional<bool>{false});
using std::optional;
diff --git a/libcxx/test/std/utilities/optional/optional.relops/equal.pass.cpp b/libcxx/test/std/utilities/optional/optional.relops/equal.pass.cpp
index 6915b604d4ef4..96a2c1d6acdb7 100644
--- a/libcxx/test/std/utilities/optional/optional.relops/equal.pass.cpp
+++ b/libcxx/test/std/utilities/optional/optional.relops/equal.pass.cpp
@@ -6,30 +6,32 @@
//
//===----------------------------------------------------------------------===//
-// UNSUPPORTED: c++03, c++11, c++14
+// REQUIRES: std-at-least-c++17
// <optional>
// template <class T, class U> constexpr bool operator==(const optional<T>& x, const optional<U>& y);
+#include <cassert>
#include <optional>
#include <type_traits>
-#include <cassert>
#include "test_comparisons.h"
#include "test_macros.h"
#if TEST_STD_VER >= 26
+# define STATIC_ASSERT_OPTIONAL_CMP static_assert
+#else
+# define STATIC_ASSERT_OPTIONAL_CMP LIBCPP_STATIC_ASSERT
+#endif
// Test SFINAE.
-static_assert(HasOperatorEqual<std::optional<int>>);
-static_assert(HasOperatorEqual<std::optional<EqualityComparable>>);
-static_assert(HasOperatorEqual<std::optional<EqualityComparable>, std::optional<int>>);
+STATIC_ASSERT_OPTIONAL_CMP(HasOperatorEqual<std::optional<int>>);
+STATIC_ASSERT_OPTIONAL_CMP(HasOperatorEqual<std::optional<EqualityComparable>>);
+STATIC_ASSERT_OPTIONAL_CMP(HasOperatorEqual<std::optional<EqualityComparable>, std::optional<int>>);
-static_assert(!HasOperatorEqual<std::optional<NonComparable>>);
-static_assert(!HasOperatorEqual<std::optional<EqualityComparable>, std::optional<NonComparable>>);
-
-#endif
+STATIC_ASSERT_OPTIONAL_CMP(!HasOperatorEqual<std::optional<NonComparable>>);
+STATIC_ASSERT_OPTIONAL_CMP(!HasOperatorEqual<std::optional<EqualityComparable>, std::optional<NonComparable>>);
using std::optional;
diff --git a/libcxx/test/std/utilities/optional/optional.relops/greater_equal.pass.cpp b/libcxx/test/std/utilities/optional/optional.relops/greater_equal.pass.cpp
index d14e7df6abc80..845912eb5deb0 100644
--- a/libcxx/test/std/utilities/optional/optional.relops/greater_equal.pass.cpp
+++ b/libcxx/test/std/utilities/optional/optional.relops/greater_equal.pass.cpp
@@ -6,7 +6,7 @@
//
//===----------------------------------------------------------------------===//
-// UNSUPPORTED: c++03, c++11, c++14
+// REQUIRES: std-at-least-c++17
// <optional>
// template <class T, class U> constexpr bool operator>= (const optional<T>& x, const optional<U>& y);
@@ -17,16 +17,18 @@
#include "test_macros.h"
#if TEST_STD_VER >= 26
+# define STATIC_ASSERT_OPTIONAL_CMP static_assert
+#else
+# define STATIC_ASSERT_OPTIONAL_CMP LIBCPP_STATIC_ASSERT
+#endif
// Test SFINAE.
-static_assert(HasOperatorGreaterThanEqual<std::optional<ThreeWayComparable>>);
-static_assert(HasOperatorGreaterThanEqual<std::optional<ThreeWayComparable>, std::optional<int>>);
-
-static_assert(!HasOperatorGreaterThanEqual<std::optional<NonComparable>>);
-static_assert(!HasOperatorGreaterThanEqual<std::optional<EqualityComparable>>);
-static_assert(!HasOperatorGreaterThanEqual<std::optional<ThreeWayComparable>, std::optional<NonComparable>>);
+STATIC_ASSERT_OPTIONAL_CMP(HasOperatorGreaterThanEqual<std::optional<TotallyOrdered>>);
+STATIC_ASSERT_OPTIONAL_CMP(HasOperatorGreaterThanEqual<std::optional<TotallyOrdered>, std::optional<int>>);
-#endif
+STATIC_ASSERT_OPTIONAL_CMP(!HasOperatorGreaterThanEqual<std::optional<NonComparable>>);
+STATIC_ASSERT_OPTIONAL_CMP(!HasOperatorGreaterThanEqual<std::optional<EqualityComparable>>);
+STATIC_ASSERT_OPTIONAL_CMP(!HasOperatorGreaterThanEqual<std::optional<TotallyOrdered>, std::optional<NonComparable>>);
using std::optional;
diff --git a/libcxx/test/std/utilities/optional/optional.relops/greater_than.pass.cpp b/libcxx/test/std/utilities/optional/optional.relops/greater_than.pass.cpp
index f19ea23e8ae78..ff92a3362fa06 100644
--- a/libcxx/test/std/utilities/optional/optional.relops/greater_than.pass.cpp
+++ b/libcxx/test/std/utilities/optional/optional.relops/greater_than.pass.cpp
@@ -6,27 +6,30 @@
//
//===----------------------------------------------------------------------===//
-// UNSUPPORTED: c++03, c++11, c++14
+// REQUIRES: std-at-least-c++17
// <optional>
// template <class T, class U> constexpr bool operator> (const optional<T>& x, const optional<U>& y);
#include <optional>
+#include <type_traits>
#include "test_comparisons.h"
#include "test_macros.h"
#if TEST_STD_VER >= 26
+# define STATIC_ASSERT_OPTIONAL_CMP static_assert
+#else
+# define STATIC_ASSERT_OPTIONAL_CMP LIBCPP_STATIC_ASSERT
+#endif
// Test SFINAE.
-static_assert(HasOperatorGreaterThan<std::optional<ThreeWayComparable>>);
-static_assert(HasOperatorGreaterThan<std::optional<ThreeWayComparable>, std::optional<int>>);
-
-static_assert(!HasOperatorGreaterThan<std::optional<NonComparable>>);
-static_assert(!HasOperatorGreaterThan<std::optional<EqualityComparable>>);
-static_assert(!HasOperatorGreaterThan<std::optional<ThreeWayComparable>, std::optional<NonComparable>>);
+STATIC_ASSERT_OPTIONAL_CMP(HasOperatorGreaterThan<std::optional<TotallyOrdered>>);
+STATIC_ASSERT_OPTIONAL_CMP(HasOperatorGreaterThan<std::optional<TotallyOrdered>, std::optional<int>>);
-#endif
+STATIC_ASSERT_OPTIONAL_CMP(!HasOperatorGreaterThan<std::optional<NonComparable>>);
+STATIC_ASSERT_OPTIONAL_CMP(!HasOperatorGreaterThan<std::optional<EqualityComparable>>);
+STATIC_ASSERT_OPTIONAL_CMP(!HasOperatorGreaterThan<std::optional<TotallyOrdered>, std::optional<NonComparable>>);
using std::optional;
diff --git a/libcxx/test/std/utilities/optional/optional.relops/less_equal.pass.cpp b/libcxx/test/std/utilities/optional/optional.relops/less_equal.pass.cpp
index bd81a79f1265e..aaee72229d2ef 100644
--- a/libcxx/test/std/utilities/optional/optional.relops/less_equal.pass.cpp
+++ b/libcxx/test/std/utilities/optional/optional.relops/less_equal.pass.cpp
@@ -6,7 +6,7 @@
//
//===----------------------------------------------------------------------===//
-// UNSUPPORTED: c++03, c++11, c++14
+// REQUIRES: std-at-least-c++17
// <optional>
// template <class T, class U> constexpr bool operator<= (const optional<T>& x, const optional<U>& y);
@@ -17,16 +17,18 @@
#include "test_macros.h"
#if TEST_STD_VER >= 26
+# define STATIC_ASSERT_OPTIONAL_CMP static_assert
+#else
+# define STATIC_ASSERT_OPTIONAL_CMP LIBCPP_STATIC_ASSERT
+#endif
// Test SFINAE.
-static_assert(HasOperatorLessThanEqual<std::optional<ThreeWayComparable>>);
-static_assert(HasOperatorLessThanEqual<std::optional<ThreeWayComparable>, std::optional<int>>);
-
-static_assert(!HasOperatorLessThanEqual<std::optional<NonComparable>>);
-static_assert(!HasOperatorLessThanEqual<std::optional<EqualityComparable>>);
-static_assert(!HasOperatorLessThanEqual<std::optional<ThreeWayComparable>, std::optional<NonComparable>>);
+STATIC_ASSERT_OPTIONAL_CMP(HasOperatorLessThanEqual<std::optional<TotallyOrdered>>);
+STATIC_ASSERT_OPTIONAL_CMP(HasOperatorLessThanEqual<std::optional<TotallyOrdered>, std::optional<int>>);
-#endif
+STATIC_ASSERT_OPTIONAL_CMP(!HasOperatorLessThanEqual<std::optional<NonComparable>>);
+STATIC_ASSERT_OPTIONAL_CMP(!HasOperatorLessThanEqual<std::optional<EqualityComparable>>);
+STATIC_ASSERT_OPTIONAL_CMP(!HasOperatorLessThanEqual<std::optional<TotallyOrdered>, std::optional<NonComparable>>);
using std::optional;
diff --git a/libcxx/test/std/utilities/optional/optional.relops/less_than.pass.cpp b/libcxx/test/std/utilities/optional/optional.relops/less_than.pass.cpp
index c87bfd6f73e54..b5e8a85aa5e50 100644
--- a/libcxx/test/std/utilities/optional/optional.relops/less_than.pass.cpp
+++ b/libcxx/test/std/utilities/optional/optional.relops/less_than.pass.cpp
@@ -6,7 +6,7 @@
//
//===----------------------------------------------------------------------===//
-// UNSUPPORTED: c++03, c++11, c++14
+// REQUIRES: std-at-least-c++17
// <optional>
// template <class T, class U> constexpr bool operator< (const optional<T>& x, const optional<U>& y);
@@ -17,16 +17,18 @@
#include "test_macros.h"
#if TEST_STD_VER >= 26
+# define STATIC_ASSERT_OPTIONAL_CMP static_assert
+#else
+# define STATIC_ASSERT_OPTIONAL_CMP LIBCPP_STATIC_ASSERT
+#endif
// Test SFINAE.
-static_assert(HasOperatorLessThan<std::optional<ThreeWayComparable>>);
-static_assert(HasOperatorLessThan<std::optional<ThreeWayComparable>, std::optional<int>>);
-
-static_assert(!HasOperatorLessThan<std::optional<NonComparable>>);
-static_assert(!HasOperatorLessThan<std::optional<EqualityComparable>>);
-static_assert(!HasOperatorLessThan<std::optional<ThreeWayComparable>, std::optional<NonComparable>>);
+STATIC_ASSERT_OPTIONAL_CMP(HasOperatorLessThan<std::optional<TotallyOrdered>>);
+STATIC_ASSERT_OPTIONAL_CMP(HasOperatorLessThan<std::optional<TotallyOrdered>, std::optional<int>>);
-#endif
+STATIC_ASSERT_OPTIONAL_CMP(!HasOperatorLessThan<std::optional<NonComparable>>);
+STATIC_ASSERT_OPTIONAL_CMP(!HasOperatorLessThan<std::optional<EqualityComparable>>);
+STATIC_ASSERT_OPTIONAL_CMP(!HasOperatorLessThan<std::optional<TotallyOrdered>, std::optional<NonComparable>>);
using std::optional;
diff --git a/libcxx/test/std/utilities/optional/optional.relops/not_equal.pass.cpp b/libcxx/test/std/utilities/optional/optional.relops/not_equal.pass.cpp
index 1b7d2621c9193..6ca2d4818a63a 100644
--- a/libcxx/test/std/utilities/optional/optional.relops/not_equal.pass.cpp
+++ b/libcxx/test/std/utilities/optional/optional.relops/not_equal.pass.cpp
@@ -6,30 +6,32 @@
//
//===----------------------------------------------------------------------===//
-// UNSUPPORTED: c++03, c++11, c++14
+// REQUIRES: std-at-least-c++17
// <optional>
// template <class T, class U> constexpr bool operator!=(const optional<T>& x, const optional<U>& y);
+#include <cassert>
#include <optional>
#include <type_traits>
-#include <cassert>
#include "test_comparisons.h"
#include "test_macros.h"
#if TEST_STD_VER >= 26
+# define STATIC_ASSERT_OPTIONAL_CMP static_assert
+#else
+# define STATIC_ASSERT_OPTIONAL_CMP LIBCPP_STATIC_ASSERT
+#endif
// Test SFINAE.
-static_assert(HasOperatorNotEqual<std::optional<int>>);
-static_assert(HasOperatorNotEqual<std::optional<EqualityComparable>>);
-static_assert(HasOperatorNotEqual<std::optional<EqualityComparable>, std::optional<int>>);
+STATIC_ASSERT_OPTIONAL_CMP(HasOperatorNotEqual<std::optional<int>>);
+STATIC_ASSERT_OPTIONAL_CMP(HasOperatorNotEqual<std::optional<EqualityComparable>>);
+STATIC_ASSERT_OPTIONAL_CMP(HasOperatorNotEqual<std::optional<EqualityComparable>, std::optional<int>>);
-static_assert(!HasOperatorNotEqual<std::optional<NonComparable>>);
-static_assert(!HasOperatorNotEqual<std::optional<EqualityComparable>, std::optional<NonComparable>>);
-
-#endif
+STATIC_ASSERT_OPTIONAL_CMP(!HasOperatorNotEqual<std::optional<NonComparable>>);
+STATIC_ASSERT_OPTIONAL_CMP(!HasOperatorNotEqual<std::optional<EqualityComparable>, std::optional<NonComparable>>);
using std::optional;
diff --git a/libcxx/test/support/test_comparisons.h b/libcxx/test/support/test_comparisons.h
index 9d8bf910a2ebc..794c9ebc6dc9d 100644
--- a/libcxx/test/support/test_comparisons.h
+++ b/libcxx/test/support/test_comparisons.h
@@ -288,29 +288,6 @@ concept HasOperatorNotEqual = requires(T1 t1, T2 t2) { t1 != t2; };
template <typename T1, typename T2 = T1>
concept HasOperatorSpaceship = requires(T1 t1, T2 t2) { t1 <=> t2; };
-struct NonComparable {};
-static_assert(!std::equality_comparable<NonComparable>);
-static_assert(!HasOperatorEqual<NonComparable>);
-static_assert(!HasOperatorGreaterThan<NonComparable>);
-static_assert(!HasOperatorGreaterThanEqual<NonComparable>);
-static_assert(!HasOperatorLessThan<NonComparable>);
-static_assert(!HasOperatorLessThanEqual<NonComparable>);
-static_assert(!HasOperatorNotEqual<NonComparable>);
-static_assert(!HasOperatorSpaceship<NonComparable>);
-
-class EqualityComparable {
-public:
- constexpr EqualityComparable(int value) : value_{value} {};
-
- friend constexpr bool operator==(const EqualityComparable&, const EqualityComparable&) noexcept = default;
-
-private:
- int value_;
-};
-static_assert(std::equality_comparable<EqualityComparable>);
-static_assert(HasOperatorEqual<EqualityComparable>);
-static_assert(HasOperatorNotEqual<EqualityComparable>);
-
class ThreeWayComparable {
public:
constexpr ThreeWayComparable(int value) : value_{value} {};
@@ -349,6 +326,139 @@ struct ImplicitBool {
constexpr ImplicitBool operator==(ImplicitBool::E1 lhs, ImplicitBool::E2 rhs) { return {lhs.x == rhs.y}; }
+#elif TEST_STD_VER >= 14
+
+template <typename T1, typename T2 = T1, typename = void>
+constexpr bool HasOperatorEqual = false;
+template <typename T1, typename T2>
+constexpr bool HasOperatorEqual<T1, T2, decltype((void)(std::declval<T1&>() == std::declval<T2&>()))> = true;
+
+template <typename T1, typename T2 = T1, typename = void>
+constexpr bool HasOperatorGreaterThan = false;
+template <typename T1, typename T2>
+constexpr bool HasOperatorGreaterThan<T1, T2, decltype((void)(std::declval<T1&>() > std::declval<T2&>()))> = true;
+
+template <typename T1, typename T2 = T1, typename = void>
+constexpr bool HasOperatorGreaterThanEqual = false;
+template <typename T1, typename T2>
+constexpr bool HasOperatorGreaterThanEqual<T1, T2, decltype((void)(std::declval<T1&>() >= std::declval<T2&>()))> = true;
+
+template <typename T1, typename T2 = T1, typename = void>
+constexpr bool HasOperatorLessThan = false;
+template <typename T1, typename T2>
+constexpr bool HasOperatorLessThan<T1, T2, decltype((void)(std::declval<T1&>() < std::declval<T2&>()))> = true;
+
+template <typename T1, typename T2 = T1, typename = void>
+constexpr bool HasOperatorLessThanEqual = false;
+template <typename T1, typename T2>
+constexpr bool HasOperatorLessThanEqual<T1, T2, decltype((void)(std::declval<T1&>() <= std::declval<T2&>()))> = true;
+
+template <typename T1, typename T2 = T1, typename = void>
+constexpr bool HasOperatorNotEqual = false;
+template <typename T1, typename T2>
+constexpr bool HasOperatorNotEqual<T1, T2, decltype((void)(std::declval<T1&>() != std::declval<T2&>()))> = true;
+
+#endif // TEST_STD_VER >= 20
+
+struct NonComparable {};
+
+class EqualityComparable {
+public:
+ TEST_CONSTEXPR EqualityComparable(int value) : value_(value) {};
+
+#if TEST_STD_VER >= 20
+ friend constexpr bool operator==(const EqualityComparable&, const EqualityComparable&) noexcept = default;
+#else
+ friend TEST_CONSTEXPR bool operator==(const EqualityComparable& lhs, const EqualityComparable& rhs) TEST_NOEXCEPT {
+ return lhs.value_ == rhs.value_;
+ }
+
+ friend TEST_CONSTEXPR bool operator!=(const EqualityComparable& lhs, const EqualityComparable& rhs) TEST_NOEXCEPT {
+ return !(lhs == rhs);
+ }
+#endif
+
+private:
+ int value_;
+};
+
+class TotallyOrdered {
+public:
+ TEST_CONSTEXPR TotallyOrdered(int value) : value_(value) {};
+
+#if TEST_STD_VER >= 20
+ friend constexpr bool operator==(const TotallyOrdered&, const TotallyOrdered&) noexcept = default;
+#else
+ friend TEST_CONSTEXPR bool operator==(const TotallyOrdered& lhs, const TotallyOrdered& rhs) TEST_NOEXCEPT {
+ return lhs.value_ == rhs.value_;
+ }
+
+ friend TEST_CONSTEXPR bool operator!=(const TotallyOrdered& lhs, const TotallyOrdered& rhs) TEST_NOEXCEPT {
+ return !(lhs == rhs);
+ }
+#endif
+
+ friend TEST_CONSTEXPR bool operator<(const TotallyOrdered& lhs, const TotallyOrdered& rhs) TEST_NOEXCEPT {
+ return lhs.value_ < rhs.value_;
+ }
+
+ friend TEST_CONSTEXPR bool operator>(const TotallyOrdered& lhs, const TotallyOrdered& rhs) TEST_NOEXCEPT {
+ return rhs < lhs;
+ }
+
+ friend TEST_CONSTEXPR bool operator<=(const TotallyOrdered& lhs, const TotallyOrdered& rhs) TEST_NOEXCEPT {
+ return !(rhs < lhs);
+ }
+
+ friend TEST_CONSTEXPR bool operator>=(const TotallyOrdered& lhs, const TotallyOrdered& rhs) TEST_NOEXCEPT {
+ return !(lhs < rhs);
+ }
+
+private:
+ int value_;
+};
+
+#if TEST_STD_VER >= 14
+
+static_assert(!HasOperatorEqual<NonComparable>);
+static_assert(!HasOperatorGreaterThan<NonComparable>);
+static_assert(!HasOperatorGreaterThanEqual<NonComparable>);
+static_assert(!HasOperatorLessThan<NonComparable>);
+static_assert(!HasOperatorLessThanEqual<NonComparable>);
+static_assert(!HasOperatorNotEqual<NonComparable>);
+
+static_assert(HasOperatorEqual<EqualityComparable>);
+static_assert(HasOperatorNotEqual<EqualityComparable>);
+static_assert(!HasOperatorGreaterThanEqual<EqualityComparable>);
+static_assert(!HasOperatorLessThan<EqualityComparable>);
+static_assert(!HasOperatorLessThanEqual<EqualityComparable>);
+
+static_assert(HasOperatorEqual<TotallyOrdered>);
+static_assert(HasOperatorNotEqual<TotallyOrdered>);
+static_assert(HasOperatorGreaterThanEqual<TotallyOrdered>);
+static_assert(HasOperatorLessThan<TotallyOrdered>);
+static_assert(HasOperatorLessThanEqual<TotallyOrdered>);
+static_assert(HasOperatorNotEqual<TotallyOrdered>);
+
+#endif // TEST_STD_VER >= 14
+
+#if TEST_STD_VER >= 20
+
+static_assert(!std::equality_comparable<NonComparable>);
+static_assert(!std::totally_ordered<NonComparable>);
+static_assert(!std::three_way_comparable<NonComparable>);
+static_assert(!HasOperatorSpaceship<NonComparable>);
+
+static_assert(std::equality_comparable<EqualityComparable>);
+static_assert(!std::totally_ordered<EqualityComparable>);
+static_assert(!std::three_way_comparable<EqualityComparable>);
+static_assert(!HasOperatorSpaceship<EqualityComparable>);
+
+static_assert(std::equality_comparable<TotallyOrdered>);
+static_assert(std::totally_ordered<TotallyOrdered>);
+static_assert(!std::three_way_comparable<TotallyOrdered>);
+static_assert(!HasOperatorSpaceship<TotallyOrdered>);
+
#endif // TEST_STD_VER >= 20
#endif // TEST_COMPARISONS_H
More information about the libcxx-commits
mailing list