[libcxx-commits] [libcxx] [libc++] P2944R3: Constrained comparisons - update `reference_wrapper` implementation (PR #139368)

Hristo Hristov via libcxx-commits libcxx-commits at lists.llvm.org
Wed Jun 4 03:46:05 PDT 2025


https://github.com/H-G-Hristov updated https://github.com/llvm/llvm-project/pull/139368

>From 61e16a889d0ad46fd490f0712d3cf2b32ac3bfa4 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Wed, 30 Apr 2025 14:32:32 +0300
Subject: [PATCH 01/15] [libc++] P2944R3: Constrained comparisions - the
 `optional` and `reference_wrapper`

Partially implements [P2944R3](https://wg21.link/P2944R3), which adds constrained comparisons to `optional` and `reference_wrapper`.

Generalizes the test helpers in `test_comparisons.h` to support constrained comparisons.

- [refwrap.comparisons](https://wg21.link/refwrap.comparisons)
- [optional.relops](https://wg21.link/optional.relops)
- [https://wg21.link/optional.comp.with.t](https://wg21.link/optional.comp.with.t)

Closes #136767
Closes #138233

Relates to: #135759
---
 libcxx/docs/Status/Cxx2cPapers.csv            |   2 +-
 .../include/__functional/reference_wrapper.h  |   8 +-
 libcxx/include/optional                       | 226 ++++++++++++++++--
 .../algorithms/no_specializations.verify.cpp  |   2 +-
 .../specialization.verify.cpp                 |   2 +-
 ...mpare.three_way.refwrap.const_ref.pass.cpp |  13 +-
 ...compare.three_way.refwrap.refwrap.pass.cpp |  14 +-
 ...e.three_way.refwrap.refwrap_const.pass.cpp |  17 +-
 .../equal.refwrap.const_ref.pass.cpp          |  12 +-
 .../equal.refwrap.refwrap.pass.cpp            |   9 +-
 .../equal.refwrap.refwrap_const.pass.cpp      |  13 +-
 .../refwrap.comparissons/helper_concepts.h    |  38 ---
 .../refwrap.comparissons/helper_types.h       |  30 ---
 .../optional/optional.relops/equal.pass.cpp   |   6 +
 .../pairs/pairs.spec/comparison.pass.cpp      |  15 +-
 libcxx/test/support/test_comparisons.h        | 104 +++++++-
 .../generate_feature_test_macro_components.py |   7 +-
 17 files changed, 358 insertions(+), 160 deletions(-)
 delete mode 100644 libcxx/test/std/utilities/function.objects/refwrap/refwrap.comparissons/helper_concepts.h
 delete mode 100644 libcxx/test/std/utilities/function.objects/refwrap/refwrap.comparissons/helper_types.h

diff --git a/libcxx/docs/Status/Cxx2cPapers.csv b/libcxx/docs/Status/Cxx2cPapers.csv
index 3809446a57896..99fc0b38077ab 100644
--- a/libcxx/docs/Status/Cxx2cPapers.csv
+++ b/libcxx/docs/Status/Cxx2cPapers.csv
@@ -59,7 +59,7 @@
 "`P2248R8 <https://wg21.link/P2248R8>`__","Enabling list-initialization for algorithms","2024-03 (Tokyo)","","",""
 "`P2810R4 <https://wg21.link/P2810R4>`__","``is_debugger_present`` ``is_replaceable``","2024-03 (Tokyo)","","",""
 "`P1068R11 <https://wg21.link/P1068R11>`__","Vector API for random number generation","2024-03 (Tokyo)","","",""
-"`P2944R3 <https://wg21.link/P2944R3>`__","Comparisons for ``reference_wrapper``","2024-03 (Tokyo)","|Partial|","","Implemented changes to ``reference_wrapper`` and ``pair``"
+"`P2944R3 <https://wg21.link/P2944R3>`__","Comparisons for ``reference_wrapper``","2024-03 (Tokyo)","|Partial|","","Not implemented ``tuple`` and ``variant``"
 "`P2642R6 <https://wg21.link/P2642R6>`__","Padded ``mdspan`` layouts","2024-03 (Tokyo)","","",""
 "`P3029R1 <https://wg21.link/P3029R1>`__","Better ``mdspan``'s CTAD","2024-03 (Tokyo)","|Complete|","19",""
 "","","","","",""
diff --git a/libcxx/include/__functional/reference_wrapper.h b/libcxx/include/__functional/reference_wrapper.h
index b409ad7511f6c..4b64b7ce262ef 100644
--- a/libcxx/include/__functional/reference_wrapper.h
+++ b/libcxx/include/__functional/reference_wrapper.h
@@ -11,12 +11,12 @@
 #define _LIBCPP___FUNCTIONAL_REFERENCE_WRAPPER_H
 
 #include <__compare/synth_three_way.h>
-#include <__concepts/boolean_testable.h>
 #include <__config>
 #include <__functional/weak_result_type.h>
 #include <__memory/addressof.h>
 #include <__type_traits/desugars_to.h>
 #include <__type_traits/enable_if.h>
+#include <__type_traits/is_core_convertible.h>
 #include <__type_traits/invoke.h>
 #include <__type_traits/is_const.h>
 #include <__type_traits/remove_cvref.h>
@@ -75,7 +75,7 @@ class reference_wrapper : public __weak_result_type<_Tp> {
 
   _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(reference_wrapper __x, reference_wrapper __y)
     requires requires {
-      { __x.get() == __y.get() } -> __boolean_testable;
+      { __x.get() == __y.get() } -> __core_convertible_to<bool>;
     }
   {
     return __x.get() == __y.get();
@@ -83,7 +83,7 @@ class reference_wrapper : public __weak_result_type<_Tp> {
 
   _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(reference_wrapper __x, const _Tp& __y)
     requires requires {
-      { __x.get() == __y } -> __boolean_testable;
+      { __x.get() == __y } -> __core_convertible_to<bool>;
     }
   {
     return __x.get() == __y;
@@ -91,7 +91,7 @@ class reference_wrapper : public __weak_result_type<_Tp> {
 
   _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(reference_wrapper __x, reference_wrapper<const _Tp> __y)
     requires(!is_const_v<_Tp>) && requires {
-      { __x.get() == __y.get() } -> __boolean_testable;
+      { __x.get() == __y.get() } -> __core_convertible_to<bool>;
     }
   {
     return __x.get() == __y.get();
diff --git a/libcxx/include/optional b/libcxx/include/optional
index 2153efb2ab899..fede9a3e2751f 100644
--- a/libcxx/include/optional
+++ b/libcxx/include/optional
@@ -205,6 +205,7 @@ namespace std {
 #  include <__type_traits/is_assignable.h>
 #  include <__type_traits/is_constructible.h>
 #  include <__type_traits/is_convertible.h>
+#  include <__type_traits/is_core_convertible.h>
 #  include <__type_traits/is_destructible.h>
 #  include <__type_traits/is_nothrow_assignable.h>
 #  include <__type_traits/is_nothrow_constructible.h>
@@ -983,12 +984,23 @@ public:
 template <class _Tp>
 optional(_Tp) -> optional<_Tp>;
 
-// Comparisons between optionals
+// [optional.relops] Relational operators
+
+#    if _LIBCPP_STD_VER < 26
+template < class _Tp, class _Up>
+#    else
 template <
     class _Tp,
     class _Up,
     enable_if_t<is_convertible_v<decltype(std::declval<const _Tp&>() == std::declval<const _Up&>()), bool>, int> = 0>
-_LIBCPP_HIDE_FROM_ABI constexpr bool operator==(const optional<_Tp>& __x, const optional<_Up>& __y) {
+#    endif
+_LIBCPP_HIDE_FROM_ABI constexpr bool operator==(const optional<_Tp>& __x, const optional<_Up>& __y)
+#    if _LIBCPP_STD_VER >= 26
+  requires requires {
+    { *__x == *__y } -> __core_convertible_to<bool>;
+  }
+#    endif
+{
   if (static_cast<bool>(__x) != static_cast<bool>(__y))
     return false;
   if (!static_cast<bool>(__x))
@@ -996,11 +1008,21 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool operator==(const optional<_Tp>& __x, const
   return *__x == *__y;
 }
 
+#    if _LIBCPP_STD_VER < 26
+template < class _Tp, class _Up>
+#    else
 template <
     class _Tp,
     class _Up,
     enable_if_t<is_convertible_v<decltype(std::declval<const _Tp&>() != std::declval<const _Up&>()), bool>, int> = 0>
-_LIBCPP_HIDE_FROM_ABI constexpr bool operator!=(const optional<_Tp>& __x, const optional<_Up>& __y) {
+#    endif
+_LIBCPP_HIDE_FROM_ABI constexpr bool operator!=(const optional<_Tp>& __x, const optional<_Up>& __y)
+#    if _LIBCPP_STD_VER >= 26
+  requires requires {
+    { *__x != *__y } -> __core_convertible_to<bool>;
+  }
+#    endif
+{
   if (static_cast<bool>(__x) != static_cast<bool>(__y))
     return true;
   if (!static_cast<bool>(__x))
@@ -1008,11 +1030,21 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool operator!=(const optional<_Tp>& __x, const
   return *__x != *__y;
 }
 
+#    if _LIBCPP_STD_VER < 26
+template < class _Tp, class _Up>
+#    else
 template <
     class _Tp,
     class _Up,
     enable_if_t<is_convertible_v<decltype(std::declval<const _Tp&>() < std::declval<const _Up&>()), bool>, int> = 0>
-_LIBCPP_HIDE_FROM_ABI constexpr bool operator<(const optional<_Tp>& __x, const optional<_Up>& __y) {
+#    endif
+_LIBCPP_HIDE_FROM_ABI constexpr bool operator<(const optional<_Tp>& __x, const optional<_Up>& __y)
+#    if _LIBCPP_STD_VER >= 26
+  requires requires {
+    { *__x < *__y } -> __core_convertible_to<bool>;
+  }
+#    endif
+{
   if (!static_cast<bool>(__y))
     return false;
   if (!static_cast<bool>(__x))
@@ -1020,11 +1052,21 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool operator<(const optional<_Tp>& __x, const o
   return *__x < *__y;
 }
 
+#    if _LIBCPP_STD_VER < 26
+template < class _Tp, class _Up>
+#    else
 template <
     class _Tp,
     class _Up,
     enable_if_t<is_convertible_v<decltype(std::declval<const _Tp&>() > std::declval<const _Up&>()), bool>, int> = 0>
-_LIBCPP_HIDE_FROM_ABI constexpr bool operator>(const optional<_Tp>& __x, const optional<_Up>& __y) {
+#    endif
+_LIBCPP_HIDE_FROM_ABI constexpr bool operator>(const optional<_Tp>& __x, const optional<_Up>& __y)
+#    if _LIBCPP_STD_VER >= 26
+  requires requires {
+    { *__x > *__y } -> __core_convertible_to<bool>;
+  }
+#    endif
+{
   if (!static_cast<bool>(__x))
     return false;
   if (!static_cast<bool>(__y))
@@ -1032,11 +1074,21 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool operator>(const optional<_Tp>& __x, const o
   return *__x > *__y;
 }
 
+#    if _LIBCPP_STD_VER < 26
+template < class _Tp, class _Up>
+#    else
 template <
     class _Tp,
     class _Up,
     enable_if_t<is_convertible_v<decltype(std::declval<const _Tp&>() <= std::declval<const _Up&>()), bool>, int> = 0>
-_LIBCPP_HIDE_FROM_ABI constexpr bool operator<=(const optional<_Tp>& __x, const optional<_Up>& __y) {
+#    endif
+_LIBCPP_HIDE_FROM_ABI constexpr bool operator<=(const optional<_Tp>& __x, const optional<_Up>& __y)
+#    if _LIBCPP_STD_VER >= 26
+  requires requires {
+    { *__x <= *__y } -> __core_convertible_to<bool>;
+  }
+#    endif
+{
   if (!static_cast<bool>(__x))
     return true;
   if (!static_cast<bool>(__y))
@@ -1044,11 +1096,21 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool operator<=(const optional<_Tp>& __x, const
   return *__x <= *__y;
 }
 
+#    if _LIBCPP_STD_VER < 26
+template < class _Tp, class _Up>
+#    else
 template <
     class _Tp,
     class _Up,
     enable_if_t<is_convertible_v<decltype(std::declval<const _Tp&>() >= std::declval<const _Up&>()), bool>, int> = 0>
-_LIBCPP_HIDE_FROM_ABI constexpr bool operator>=(const optional<_Tp>& __x, const optional<_Up>& __y) {
+#    endif
+_LIBCPP_HIDE_FROM_ABI constexpr bool operator>=(const optional<_Tp>& __x, const optional<_Up>& __y)
+#    if _LIBCPP_STD_VER >= 26
+  requires requires {
+    { *__x >= *__y } -> __core_convertible_to<bool>;
+  }
+#    endif
+{
   if (!static_cast<bool>(__y))
     return true;
   if (!static_cast<bool>(__x))
@@ -1068,7 +1130,8 @@ operator<=>(const optional<_Tp>& __x, const optional<_Up>& __y) {
 
 #    endif // _LIBCPP_STD_VER >= 20
 
-// Comparisons with nullopt
+// [optional.nullops] Comparison with nullopt
+
 template <class _Tp>
 _LIBCPP_HIDE_FROM_ABI constexpr bool operator==(const optional<_Tp>& __x, nullopt_t) noexcept {
   return !static_cast<bool>(__x);
@@ -1140,100 +1203,221 @@ _LIBCPP_HIDE_FROM_ABI constexpr strong_ordering operator<=>(const optional<_Tp>&
 
 #    endif // _LIBCPP_STD_VER <= 17
 
-// Comparisons with T
+// [optional.comp.with.t] Comparison with T
+
+#    if _LIBCPP_STD_VER < 26
+template < class _Tp, class _Up>
+#    else
 template <
     class _Tp,
     class _Up,
     enable_if_t<is_convertible_v<decltype(std::declval<const _Tp&>() == std::declval<const _Up&>()), bool>, int> = 0>
-_LIBCPP_HIDE_FROM_ABI constexpr bool operator==(const optional<_Tp>& __x, const _Up& __v) {
+#    endif
+_LIBCPP_HIDE_FROM_ABI constexpr bool operator==(const optional<_Tp>& __x, const _Up& __v)
+#    if _LIBCPP_STD_VER >= 26
+  requires(!__is_std_optional<_Up>::value) && requires {
+    { *__x == __v } -> __core_convertible_to<bool>;
+  }
+#    endif
+{
   return static_cast<bool>(__x) ? *__x == __v : false;
 }
 
+#    if _LIBCPP_STD_VER < 26
+template < class _Tp, class _Up>
+#    else
 template <
     class _Tp,
     class _Up,
     enable_if_t<is_convertible_v<decltype(std::declval<const _Tp&>() == std::declval<const _Up&>()), bool>, int> = 0>
-_LIBCPP_HIDE_FROM_ABI constexpr bool operator==(const _Tp& __v, const optional<_Up>& __x) {
+#    endif
+_LIBCPP_HIDE_FROM_ABI constexpr bool operator==(const _Tp& __v, const optional<_Up>& __x)
+#    if _LIBCPP_STD_VER >= 26
+  requires(!__is_std_optional<_Tp>::value) && requires {
+    { __v == *__x } -> __core_convertible_to<bool>;
+  }
+#    endif
+{
   return static_cast<bool>(__x) ? __v == *__x : false;
 }
 
+#    if _LIBCPP_STD_VER < 26
+template < class _Tp, class _Up>
+#    else
 template <
     class _Tp,
     class _Up,
     enable_if_t<is_convertible_v<decltype(std::declval<const _Tp&>() != std::declval<const _Up&>()), bool>, int> = 0>
-_LIBCPP_HIDE_FROM_ABI constexpr bool operator!=(const optional<_Tp>& __x, const _Up& __v) {
+#    endif
+_LIBCPP_HIDE_FROM_ABI constexpr bool operator!=(const optional<_Tp>& __x, const _Up& __v)
+#    if _LIBCPP_STD_VER >= 26
+  requires(!__is_std_optional<_Up>::value) && requires {
+    { *__x != __v } -> __core_convertible_to<bool>;
+  }
+#    endif
+{
   return static_cast<bool>(__x) ? *__x != __v : true;
 }
 
+#    if _LIBCPP_STD_VER < 26
+template < class _Tp, class _Up>
+#    else
 template <
     class _Tp,
     class _Up,
     enable_if_t<is_convertible_v<decltype(std::declval<const _Tp&>() != std::declval<const _Up&>()), bool>, int> = 0>
-_LIBCPP_HIDE_FROM_ABI constexpr bool operator!=(const _Tp& __v, const optional<_Up>& __x) {
+#    endif
+_LIBCPP_HIDE_FROM_ABI constexpr bool operator!=(const _Tp& __v, const optional<_Up>& __x)
+#    if _LIBCPP_STD_VER >= 26
+  requires(!__is_std_optional<_Tp>::value) && requires {
+    { __v != *__x } -> __core_convertible_to<bool>;
+  }
+#    endif
+{
   return static_cast<bool>(__x) ? __v != *__x : true;
 }
 
+#    if _LIBCPP_STD_VER < 26
+template < class _Tp, class _Up>
+#    else
 template <
     class _Tp,
     class _Up,
     enable_if_t<is_convertible_v<decltype(std::declval<const _Tp&>() < std::declval<const _Up&>()), bool>, int> = 0>
-_LIBCPP_HIDE_FROM_ABI constexpr bool operator<(const optional<_Tp>& __x, const _Up& __v) {
+#    endif
+_LIBCPP_HIDE_FROM_ABI constexpr bool operator<(const optional<_Tp>& __x, const _Up& __v)
+#    if _LIBCPP_STD_VER >= 26
+  requires(!__is_std_optional<_Up>::value) && requires {
+    { *__x < __v } -> __core_convertible_to<bool>;
+  }
+#    endif
+{
   return static_cast<bool>(__x) ? *__x < __v : true;
 }
 
+#    if _LIBCPP_STD_VER < 26
+template < class _Tp, class _Up>
+#    else
 template <
     class _Tp,
     class _Up,
     enable_if_t<is_convertible_v<decltype(std::declval<const _Tp&>() < std::declval<const _Up&>()), bool>, int> = 0>
-_LIBCPP_HIDE_FROM_ABI constexpr bool operator<(const _Tp& __v, const optional<_Up>& __x) {
+#    endif
+_LIBCPP_HIDE_FROM_ABI constexpr bool operator<(const _Tp& __v, const optional<_Up>& __x)
+#    if _LIBCPP_STD_VER >= 26
+  requires(!__is_std_optional<_Tp>::value) && requires {
+    { __v < *__x } -> __core_convertible_to<bool>;
+  }
+#    endif
+{
   return static_cast<bool>(__x) ? __v < *__x : false;
 }
 
+#    if _LIBCPP_STD_VER < 26
+template < class _Tp, class _Up>
+#    else
 template <
     class _Tp,
     class _Up,
     enable_if_t<is_convertible_v<decltype(std::declval<const _Tp&>() <= std::declval<const _Up&>()), bool>, int> = 0>
-_LIBCPP_HIDE_FROM_ABI constexpr bool operator<=(const optional<_Tp>& __x, const _Up& __v) {
+#    endif
+_LIBCPP_HIDE_FROM_ABI constexpr bool operator<=(const optional<_Tp>& __x, const _Up& __v)
+#    if _LIBCPP_STD_VER >= 26
+  requires(!__is_std_optional<_Up>::value) && requires {
+    { *__x <= __v } -> __core_convertible_to<bool>;
+  }
+#    endif
+{
   return static_cast<bool>(__x) ? *__x <= __v : true;
 }
 
+#    if _LIBCPP_STD_VER < 26
+template < class _Tp, class _Up>
+#    else
 template <
     class _Tp,
     class _Up,
     enable_if_t<is_convertible_v<decltype(std::declval<const _Tp&>() <= std::declval<const _Up&>()), bool>, int> = 0>
-_LIBCPP_HIDE_FROM_ABI constexpr bool operator<=(const _Tp& __v, const optional<_Up>& __x) {
+#    endif
+_LIBCPP_HIDE_FROM_ABI constexpr bool operator<=(const _Tp& __v, const optional<_Up>& __x)
+#    if _LIBCPP_STD_VER >= 26
+  requires(!__is_std_optional<_Tp>::value) && requires {
+    { __v <= __x } -> __core_convertible_to<bool>;
+  }
+#    endif
+{
   return static_cast<bool>(__x) ? __v <= *__x : false;
 }
 
+#    if _LIBCPP_STD_VER < 26
+template < class _Tp, class _Up>
+#    else
 template <
     class _Tp,
     class _Up,
     enable_if_t<is_convertible_v<decltype(std::declval<const _Tp&>() > std::declval<const _Up&>()), bool>, int> = 0>
-_LIBCPP_HIDE_FROM_ABI constexpr bool operator>(const optional<_Tp>& __x, const _Up& __v) {
+#    endif
+_LIBCPP_HIDE_FROM_ABI constexpr bool operator>(const optional<_Tp>& __x, const _Up& __v)
+#    if _LIBCPP_STD_VER >= 26
+  requires(!__is_std_optional<_Up>::value) && requires {
+    { *__x > __v } -> __core_convertible_to<bool>;
+  }
+#    endif
+{
   return static_cast<bool>(__x) ? *__x > __v : false;
 }
 
+#    if _LIBCPP_STD_VER < 26
+template < class _Tp, class _Up>
+#    else
 template <
     class _Tp,
     class _Up,
     enable_if_t<is_convertible_v<decltype(std::declval<const _Tp&>() > std::declval<const _Up&>()), bool>, int> = 0>
-_LIBCPP_HIDE_FROM_ABI constexpr bool operator>(const _Tp& __v, const optional<_Up>& __x) {
+#    endif
+_LIBCPP_HIDE_FROM_ABI constexpr bool operator>(const _Tp& __v, const optional<_Up>& __x)
+#    if _LIBCPP_STD_VER >= 26
+  requires(!__is_std_optional<_Tp>::value) && requires {
+    { __v > *__x } -> __core_convertible_to<bool>;
+  }
+#    endif
+{
   return static_cast<bool>(__x) ? __v > *__x : true;
 }
 
+#    if _LIBCPP_STD_VER < 26
+template < class _Tp, class _Up>
+#    else
 template <
     class _Tp,
     class _Up,
     enable_if_t<is_convertible_v<decltype(std::declval<const _Tp&>() >= std::declval<const _Up&>()), bool>, int> = 0>
-_LIBCPP_HIDE_FROM_ABI constexpr bool operator>=(const optional<_Tp>& __x, const _Up& __v) {
+#    endif
+_LIBCPP_HIDE_FROM_ABI constexpr bool operator>=(const optional<_Tp>& __x, const _Up& __v)
+#    if _LIBCPP_STD_VER >= 26
+  requires(!__is_std_optional<_Up>::value) && requires {
+    { *__x >= __v } -> __core_convertible_to<bool>;
+  }
+#    endif
+{
   return static_cast<bool>(__x) ? *__x >= __v : false;
 }
 
+#    if _LIBCPP_STD_VER < 26
+template < class _Tp, class _Up>
+#    else
 template <
     class _Tp,
     class _Up,
     enable_if_t<is_convertible_v<decltype(std::declval<const _Tp&>() >= std::declval<const _Up&>()), bool>, int> = 0>
-_LIBCPP_HIDE_FROM_ABI constexpr bool operator>=(const _Tp& __v, const optional<_Up>& __x) {
+#    endif
+_LIBCPP_HIDE_FROM_ABI constexpr bool operator>=(const _Tp& __v, const optional<_Up>& __x)
+#    if _LIBCPP_STD_VER >= 26
+  requires(!__is_std_optional<_Tp>::value) && requires {
+    { __v >= *__x } -> __core_convertible_to<bool>;
+  }
+#    endif
+{
   return static_cast<bool>(__x) ? __v >= *__x : true;
 }
 
diff --git a/libcxx/test/libcxx/algorithms/no_specializations.verify.cpp b/libcxx/test/libcxx/algorithms/no_specializations.verify.cpp
index 5b2475252b602..da41a6ee0ec0a 100644
--- a/libcxx/test/libcxx/algorithms/no_specializations.verify.cpp
+++ b/libcxx/test/libcxx/algorithms/no_specializations.verify.cpp
@@ -15,7 +15,7 @@
 
 #include <execution>
 
-#if !__has_warning("-Winvalid-specializations")
+#if !__has_warning("-Winvalid-specialization")
 // expected-no-diagnostics
 #else
 struct S {};
diff --git a/libcxx/test/std/language.support/support.initlist/support.initlist.syn/specialization.verify.cpp b/libcxx/test/std/language.support/support.initlist/support.initlist.syn/specialization.verify.cpp
index 11807059c71b0..54b2f6db41c7e 100644
--- a/libcxx/test/std/language.support/support.initlist/support.initlist.syn/specialization.verify.cpp
+++ b/libcxx/test/std/language.support/support.initlist/support.initlist.syn/specialization.verify.cpp
@@ -15,7 +15,7 @@
 
 #include <initializer_list>
 
-#if !__has_warning("-Winvalid-specializations")
+#if !__has_warning("-Winvalid-specialization")
 // expected-no-diagnostics
 #else
 
diff --git a/libcxx/test/std/utilities/function.objects/refwrap/refwrap.comparissons/compare.three_way.refwrap.const_ref.pass.cpp b/libcxx/test/std/utilities/function.objects/refwrap/refwrap.comparissons/compare.three_way.refwrap.const_ref.pass.cpp
index 85106c18ec35a..4a2ae963e3bdb 100644
--- a/libcxx/test/std/utilities/function.objects/refwrap/refwrap.comparissons/compare.three_way.refwrap.const_ref.pass.cpp
+++ b/libcxx/test/std/utilities/function.objects/refwrap/refwrap.comparissons/compare.three_way.refwrap.const_ref.pass.cpp
@@ -6,7 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20, c++23
+// REQUIRES: std-at-least-c++26
 
 // <functional>
 
@@ -23,16 +23,13 @@
 #include "test_comparisons.h"
 #include "test_macros.h"
 
-#include "helper_concepts.h"
-#include "helper_types.h"
-
 // Test SFINAE.
 
-static_assert(HasSpaceshipOperatorWithInt<std::reference_wrapper<StrongOrder>>);
-static_assert(HasSpaceshipOperatorWithInt<std::reference_wrapper<WeakOrder>>);
-static_assert(HasSpaceshipOperatorWithInt<std::reference_wrapper<PartialOrder>>);
+static_assert(HasOperatorSpaceship<std::reference_wrapper<StrongOrder>, int>);
+static_assert(HasOperatorSpaceship<std::reference_wrapper<WeakOrder>, int>);
+static_assert(HasOperatorSpaceship<std::reference_wrapper<PartialOrder>, int>);
 
-static_assert(!HasSpaceshipOperatorWithInt<std::reference_wrapper<NonComparable>>);
+static_assert(!HasOperatorSpaceship<std::reference_wrapper<NonComparable>, int>);
 
 // Test comparisons.
 
diff --git a/libcxx/test/std/utilities/function.objects/refwrap/refwrap.comparissons/compare.three_way.refwrap.refwrap.pass.cpp b/libcxx/test/std/utilities/function.objects/refwrap/refwrap.comparissons/compare.three_way.refwrap.refwrap.pass.cpp
index 794fac00de8a6..a4e82d296861f 100644
--- a/libcxx/test/std/utilities/function.objects/refwrap/refwrap.comparissons/compare.three_way.refwrap.refwrap.pass.cpp
+++ b/libcxx/test/std/utilities/function.objects/refwrap/refwrap.comparissons/compare.three_way.refwrap.refwrap.pass.cpp
@@ -6,7 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20, c++23
+// REQUIRES: std-at-least-c++26
 
 // <functional>
 
@@ -22,17 +22,13 @@
 
 #include "test_comparisons.h"
 #include "test_macros.h"
-
-#include "helper_concepts.h"
-#include "helper_types.h"
-
 // Test SFINAE.
 
-static_assert(std::three_way_comparable<std::reference_wrapper<StrongOrder>>);
-static_assert(std::three_way_comparable<std::reference_wrapper<WeakOrder>>);
-static_assert(std::three_way_comparable<std::reference_wrapper<PartialOrder>>);
+static_assert(HasSpaceshipOperator<std::reference_wrapper<StrongOrder>>);
+static_assert(HasSpaceshipOperator<std::reference_wrapper<WeakOrder>>);
+static_assert(HasSpaceshipOperator<std::reference_wrapper<PartialOrder>>);
 
-static_assert(!std::three_way_comparable<std::reference_wrapper<NonComparable>>);
+static_assert(!HasSpaceshipOperator<std::reference_wrapper<NonComparable>>);
 
 // Test comparisons.
 
diff --git a/libcxx/test/std/utilities/function.objects/refwrap/refwrap.comparissons/compare.three_way.refwrap.refwrap_const.pass.cpp b/libcxx/test/std/utilities/function.objects/refwrap/refwrap.comparissons/compare.three_way.refwrap.refwrap_const.pass.cpp
index 9b1302affa851..1ae22b4ac58e0 100644
--- a/libcxx/test/std/utilities/function.objects/refwrap/refwrap.comparissons/compare.three_way.refwrap.refwrap_const.pass.cpp
+++ b/libcxx/test/std/utilities/function.objects/refwrap/refwrap.comparissons/compare.three_way.refwrap.refwrap_const.pass.cpp
@@ -6,7 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20, c++23
+// REQUIRES: std-at-least-c++26
 
 // <functional>
 
@@ -23,18 +23,15 @@
 #include "test_comparisons.h"
 #include "test_macros.h"
 
-#include "helper_concepts.h"
-#include "helper_types.h"
-
 // Test SFINAE.
 
-static_assert(std::three_way_comparable_with<std::reference_wrapper<StrongOrder>, const StrongOrder>);
-static_assert(std::three_way_comparable_with<std::reference_wrapper<WeakOrder>, const WeakOrder>);
-static_assert(std::three_way_comparable_with<std::reference_wrapper<PartialOrder>, const PartialOrder>);
+static_assert(HasOperatorSpaceship<std::reference_wrapper<StrongOrder>, std::reference_wrapper<const StrongOrder>>);
+static_assert(HasOperatorSpaceship<std::reference_wrapper<WeakOrder>, std::reference_wrapper<const WeakOrder>>);
+static_assert(HasOperatorSpaceship<std::reference_wrapper<PartialOrder>, std::reference_wrapper<const PartialOrder>>);
 
-static_assert(!std::three_way_comparable_with<std::reference_wrapper<StrongOrder>, const NonComparable>);
-static_assert(!std::three_way_comparable_with<std::reference_wrapper<WeakOrder>, const NonComparable>);
-static_assert(!std::three_way_comparable_with<std::reference_wrapper<PartialOrder>, const NonComparable>);
+static_assert(!HasOperatorSpaceship<std::reference_wrapper<StrongOrder>, std::reference_wrapper<const NonComparable>>);
+static_assert(!HasOperatorSpaceship<std::reference_wrapper<WeakOrder>, std::reference_wrapper<const NonComparable>>);
+static_assert(!HasOperatorSpaceship<std::reference_wrapper<PartialOrder>, std::reference_wrapper<const NonComparable>>);
 
 // Test comparisons.
 
diff --git a/libcxx/test/std/utilities/function.objects/refwrap/refwrap.comparissons/equal.refwrap.const_ref.pass.cpp b/libcxx/test/std/utilities/function.objects/refwrap/refwrap.comparissons/equal.refwrap.const_ref.pass.cpp
index 465326818f17c..2e46cf8d1e478 100644
--- a/libcxx/test/std/utilities/function.objects/refwrap/refwrap.comparissons/equal.refwrap.const_ref.pass.cpp
+++ b/libcxx/test/std/utilities/function.objects/refwrap/refwrap.comparissons/equal.refwrap.const_ref.pass.cpp
@@ -6,7 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20, c++23
+// REQUIRES: std-at-least-c++26
 
 // <functional>
 
@@ -23,14 +23,14 @@
 #include "test_comparisons.h"
 #include "test_macros.h"
 
-#include "helper_concepts.h"
-#include "helper_types.h"
-
 // Test SFINAE.
 
-static_assert(HasEqualityOperatorWithInt<std::reference_wrapper<EqualityComparable>>);
 
-static_assert(!HasEqualityOperatorWithInt<std::reference_wrapper<NonComparable>>);
+static_assert(HasOperatorEqual<std::reference_wrapper<EqualityComparable>>);
+static_assert(HasOperatorEqual<std::reference_wrapper<EqualityComparable>, int>);
+
+static_assert(!HasOperatorEqual<std::reference_wrapper<NonComparable>>);
+static_assert(!HasOperatorEqual<std::reference_wrapper<NonComparable>, int>);
 
 // Test equality.
 
diff --git a/libcxx/test/std/utilities/function.objects/refwrap/refwrap.comparissons/equal.refwrap.refwrap.pass.cpp b/libcxx/test/std/utilities/function.objects/refwrap/refwrap.comparissons/equal.refwrap.refwrap.pass.cpp
index a50b530bbc6e1..70e79d399861a 100644
--- a/libcxx/test/std/utilities/function.objects/refwrap/refwrap.comparissons/equal.refwrap.refwrap.pass.cpp
+++ b/libcxx/test/std/utilities/function.objects/refwrap/refwrap.comparissons/equal.refwrap.refwrap.pass.cpp
@@ -6,7 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20, c++23
+// REQUIRES: std-at-least-c++26
 
 // <functional>
 
@@ -22,14 +22,11 @@
 #include "test_comparisons.h"
 #include "test_macros.h"
 
-#include "helper_concepts.h"
-#include "helper_types.h"
-
 // Test SFINAE.
 
-static_assert(std::equality_comparable<std::reference_wrapper<EqualityComparable>>);
+static_assert(HasOperatorEqual<std::reference_wrapper<EqualityComparable>>);
 
-static_assert(!std::equality_comparable<std::reference_wrapper<NonComparable>>);
+static_assert(!HasOperatorEqual<std::reference_wrapper<NonComparable>>);
 
 // Test equality.
 
diff --git a/libcxx/test/std/utilities/function.objects/refwrap/refwrap.comparissons/equal.refwrap.refwrap_const.pass.cpp b/libcxx/test/std/utilities/function.objects/refwrap/refwrap.comparissons/equal.refwrap.refwrap_const.pass.cpp
index 10f017742a87f..c68ad5c4aa527 100644
--- a/libcxx/test/std/utilities/function.objects/refwrap/refwrap.comparissons/equal.refwrap.refwrap_const.pass.cpp
+++ b/libcxx/test/std/utilities/function.objects/refwrap/refwrap.comparissons/equal.refwrap.refwrap_const.pass.cpp
@@ -6,7 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20, c++23
+// REQUIRES: std-at-least-c++26
 
 // <functional>
 
@@ -23,16 +23,13 @@
 #include "test_comparisons.h"
 #include "test_macros.h"
 
-#include "helper_concepts.h"
-#include "helper_types.h"
-
 // Test SFINAE.
 
-static_assert(std::equality_comparable_with<std::reference_wrapper<EqualityComparable>,
-                                            std::reference_wrapper<const EqualityComparable>>);
+static_assert(
+    HasOperatorEqual<std::reference_wrapper<EqualityComparable>, std::reference_wrapper<const EqualityComparable>>);
 
-static_assert(!std::equality_comparable_with<std::reference_wrapper<EqualityComparable>,
-                                             std::reference_wrapper<const NonComparable>>);
+static_assert(
+    !HasOperatorEqual<std::reference_wrapper<EqualityComparable>, std::reference_wrapper<const NonComparable>>);
 
 // Test equality.
 
diff --git a/libcxx/test/std/utilities/function.objects/refwrap/refwrap.comparissons/helper_concepts.h b/libcxx/test/std/utilities/function.objects/refwrap/refwrap.comparissons/helper_concepts.h
deleted file mode 100644
index 2dbb304f8af63..0000000000000
--- a/libcxx/test/std/utilities/function.objects/refwrap/refwrap.comparissons/helper_concepts.h
+++ /dev/null
@@ -1,38 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef TEST_STD_FUNCTIONOBJECTS_REFWRAP_HELPER_CONCEPTS_H
-#define TEST_STD_FUNCTIONOBJECTS_REFWRAP_HELPER_CONCEPTS_H
-
-#include <concepts>
-#include <utility>
-
-// Equality
-
-template <typename T>
-concept HasEqualityOperatorWithInt = requires(T t, int i) {
-  { t.get() == i } -> std::convertible_to<bool>;
-};
-
-// Spaceship
-
-template <class T>
-concept BooleanTestableImpl = std::convertible_to<T, bool>;
-
-template <class T>
-concept BooleanTestable = BooleanTestableImpl<T> && requires(T&& t) {
-  { !std::forward<T>(t) } -> BooleanTestableImpl;
-};
-
-template <typename T>
-concept HasSpaceshipOperatorWithInt = requires(T t, int i) {
-  { t < i } -> BooleanTestable;
-  { i < t } -> BooleanTestable;
-};
-
-#endif // TEST_STD_FUNCTIONOBJECTS_REFWRAP_HELPER_CONCEPTS_H
diff --git a/libcxx/test/std/utilities/function.objects/refwrap/refwrap.comparissons/helper_types.h b/libcxx/test/std/utilities/function.objects/refwrap/refwrap.comparissons/helper_types.h
deleted file mode 100644
index cf5e568dbf936..0000000000000
--- a/libcxx/test/std/utilities/function.objects/refwrap/refwrap.comparissons/helper_types.h
+++ /dev/null
@@ -1,30 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef TEST_STD_FUNCTIONOBJECTS_REFWRAP_HELPER_TYPES_H
-#define TEST_STD_FUNCTIONOBJECTS_REFWRAP_HELPER_TYPES_H
-
-#include <concepts>
-
-struct EqualityComparable {
-  constexpr EqualityComparable(int value) : value_{value} {};
-
-  friend constexpr bool operator==(const EqualityComparable&, const EqualityComparable&) noexcept = default;
-
-  int value_;
-};
-
-static_assert(std::equality_comparable<EqualityComparable>);
-static_assert(EqualityComparable{94} == EqualityComparable{94});
-static_assert(EqualityComparable{94} != EqualityComparable{82});
-
-struct NonComparable {};
-
-static_assert(!std::three_way_comparable<NonComparable>);
-
-#endif // TEST_STD_FUNCTIONOBJECTS_REFWRAP_HELPER_TYPES_H
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 96bda6a5afa26..e41c7683053dc 100644
--- a/libcxx/test/std/utilities/optional/optional.relops/equal.pass.cpp
+++ b/libcxx/test/std/utilities/optional/optional.relops/equal.pass.cpp
@@ -16,6 +16,12 @@
 #include <cassert>
 
 #include "test_macros.h"
+#include "test_comparisons.h"
+
+// Test SFINAE.
+
+static_assert(HasOperatorEqual<std::optional<int>, std::optional<int>>);
+static_assert(HasOperatorEqual<std::optional<EqualityComparable>, std::optional<EqualityComparable>>);
 
 using std::optional;
 
diff --git a/libcxx/test/std/utilities/utility/pairs/pairs.spec/comparison.pass.cpp b/libcxx/test/std/utilities/utility/pairs/pairs.spec/comparison.pass.cpp
index c472906c5ed7f..650ae970730c1 100644
--- a/libcxx/test/std/utilities/utility/pairs/pairs.spec/comparison.pass.cpp
+++ b/libcxx/test/std/utilities/utility/pairs/pairs.spec/comparison.pass.cpp
@@ -22,27 +22,14 @@
 #include <concepts>
 
 #include "test_macros.h"
+#include "test_comparisons.h"
 
 #if TEST_STD_VER >= 26
 
 // Test SFINAE.
 
-struct EqualityComparable {
-  constexpr EqualityComparable(int value) : value_{value} {};
-
-  friend constexpr bool operator==(const EqualityComparable&, const EqualityComparable&) noexcept = default;
-
-  int value_;
-};
-
-static_assert(std::equality_comparable<EqualityComparable>);
-
 static_assert(std::equality_comparable<std::pair<EqualityComparable, EqualityComparable>>);
 
-struct NonComparable {};
-
-static_assert(!std::equality_comparable<NonComparable>);
-
 static_assert(!std::equality_comparable<std::pair<EqualityComparable, NonComparable>>);
 static_assert(!std::equality_comparable<std::pair<NonComparable, EqualityComparable>>);
 
diff --git a/libcxx/test/support/test_comparisons.h b/libcxx/test/support/test_comparisons.h
index db6977a96a2fe..86cb26e21273d 100644
--- a/libcxx/test/support/test_comparisons.h
+++ b/libcxx/test/support/test_comparisons.h
@@ -268,6 +268,108 @@ struct PartialOrder {
   }
 };
 
-#endif
+#endif // TEST_STD_VER >= 20
+
+#if TEST_STD_VER >= 26
+
+template <typename T1, typename T2 = T1>
+concept HasOperatorEqual = requires(T1 t1, T2 t2) { t1 == t2; };
+
+template <typename T1, typename T2 = T1>
+concept HasOperatorNotEqual = requires(T1 t1, T2 t2) { t1 != t2; };
+
+template <typename T1, typename T2 = T1>
+concept HasOperatorLessThen = requires(T1 t1, T2 t2) { t1 < t2; };
+
+template <typename T1, typename T2 = T1>
+concept HasOperatorGreaterThen = requires(T1 t1, T2 t2) { t1 > t2; };
+
+template <typename T1, typename T2 = T1>
+concept HasOperatorLessThenEqual = requires(T1 t1, T2 t2) { t1 <= t2; };
+
+template <typename T1, typename T2 = T1>
+concept HasOperatorGreaterThenEqual = requires(T1 t1, T2 t2) { t1 >= t2; };
+
+template <typename T1, typename T2 = T1>
+concept HasOperatorSpaceship = requires(T1 t1, T2 t2) { t1 <=> t2; };
+
+template <typename T1, typename T2 = T1>
+concept CanCompareWithSpaceship = HasOperatorSpaceship<T1, T2> && requires(T1 t1, T2 t2) {
+  { t1 <=> t2 } -> std::same_as<std::strong_ordering>;
+};
+
+template <typename T1, typename T2 = T1>
+concept CanCompare =
+    HasOperatorEqual<T1, T2> && HasOperatorNotEqual<T1, T2> && HasOperatorLessThen<T1, T2> &&
+    HasOperatorGreaterThen<T1, T2> && HasOperatorLessThenEqual<T1, T2> && HasOperatorGreaterThenEqual<T1, T2>;
+
+struct NonComparable {};
+
+static_assert(!std::equality_comparable<NonComparable>);
+static_assert(!CanCompare<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>);
+
+// class NotEqualityComparable {
+// public:
+//   constexpr NotEqualityComparable(int value) : value_{value} {};
+
+//   friend constexpr bool operator!=(const NotEqualityComparable&, const NotEqualityComparable&) noexcept = default;
+
+// private:
+//   int value_;
+// };
+// static_assert(!std::equality_comparable<NotEqualityComparable>);
+
+// class LessThanComparable {
+// public:
+//   constexpr LessThanComparable(int value) : value_{value} {};
+
+//   friend constexpr bool operator<(const LessThanComparable&, const LessThanComparable&) noexcept = default;
+
+// private:
+//   int value_;
+// };
+
+// class GreaterThanComparable {
+// public:
+//   constexpr GreaterThanComparable(int value) : value_{value} {};
+
+//   friend constexpr bool operator>(const GreaterThanComparable&, const GreaterThanComparable&) noexcept = default;
+
+// private:
+//   int value_;
+// };
+
+// class LessThanEqualComparable {
+// public:
+//   constexpr LessThanEqualComparable(int value) : value_{value} {};
+
+//   friend constexpr bool operator<=(const LessThanEqualComparable&, const LessThanEqualComparable&) noexcept = default;
+
+// private:
+//   int value_;
+// };
+// class GreaterThanEqualComparable {
+// public:
+//   constexpr GreaterThanEqualComparable(int value) : value_{value} {};
+
+//   friend constexpr bool
+//   operator>=(const GreaterThanEqualComparable&, const GreaterThanEqualComparable&) noexcept = default;
+
+// private:
+//   int value_;
+// };
+
+#endif // TEST_STD_VER >= 26
 
 #endif // TEST_COMPARISONS_H
diff --git a/libcxx/utils/generate_feature_test_macro_components.py b/libcxx/utils/generate_feature_test_macro_components.py
index cb92dc17ba707..49e818da0d135 100755
--- a/libcxx/utils/generate_feature_test_macro_components.py
+++ b/libcxx/utils/generate_feature_test_macro_components.py
@@ -415,8 +415,11 @@ def add_version_header(tc):
         },
         {
             "name": "__cpp_lib_constrained_equality",
-            "values": {"c++26": 202403}, # P2944R3: Comparisons for reference_wrapper
-            "headers": ["optional", "tuple", "utility", "variant"],
+            "values": {
+                # "c++26": 202403,  # P2944R3: Comparisons for reference_wrapper
+                "c++26": 202411,  # P3379R0: Constrain std::expected equality operators
+            },
+            "headers": ["expected", "optional", "tuple", "utility", "variant"],
             "unimplemented": True,
         },
         {

>From 37b90414814b6ace7b736333fdec5f7bb720f244 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Fri, 9 May 2025 21:59:32 +0300
Subject: [PATCH 02/15] NFC refactoring of `std::expected` tests

---
 .../equality/equality.T2.pass.cpp             |  8 +++----
 .../equality/equality.other_expected.pass.cpp | 22 +++++++++----------
 .../equality/equality.unexpected.pass.cpp     |  8 +++----
 .../equality/equality.other_expected.pass.cpp | 22 +++++++++----------
 .../equality/equality.unexpected.pass.cpp     |  8 +++----
 libcxx/test/std/utilities/expected/types.h    | 13 -----------
 libcxx/test/support/test_comparisons.h        |  2 +-
 7 files changed, 35 insertions(+), 48 deletions(-)

diff --git a/libcxx/test/std/utilities/expected/expected.expected/equality/equality.T2.pass.cpp b/libcxx/test/std/utilities/expected/expected.expected/equality/equality.T2.pass.cpp
index 25eb97a2df4d3..16c6986ae670e 100644
--- a/libcxx/test/std/utilities/expected/expected.expected/equality/equality.T2.pass.cpp
+++ b/libcxx/test/std/utilities/expected/expected.expected/equality/equality.T2.pass.cpp
@@ -16,14 +16,14 @@
 #include <type_traits>
 #include <utility>
 
+#include "test_comparisons.h"
 #include "test_macros.h"
-#include "../../types.h"
 
 #if TEST_STD_VER >= 26
 // https://wg21.link/P3379R0
-static_assert(CanCompare<std::expected<int, int>, int>);
-static_assert(CanCompare<std::expected<int, int>, EqualityComparable>);
-static_assert(!CanCompare<std::expected<int, int>, NonComparable>);
+static_assert(HasOperatorEqual<std::expected<int, int>, int>);
+static_assert(HasOperatorEqual<std::expected<int, int>, EqualityComparable>);
+static_assert(!HasOperatorEqual<std::expected<int, int>, NonComparable>);
 #endif
 
 constexpr bool test() {
diff --git a/libcxx/test/std/utilities/expected/expected.expected/equality/equality.other_expected.pass.cpp b/libcxx/test/std/utilities/expected/expected.expected/equality/equality.other_expected.pass.cpp
index f0f549b6b7772..218f0c39740e5 100644
--- a/libcxx/test/std/utilities/expected/expected.expected/equality/equality.other_expected.pass.cpp
+++ b/libcxx/test/std/utilities/expected/expected.expected/equality/equality.other_expected.pass.cpp
@@ -17,26 +17,26 @@
 #include <type_traits>
 #include <utility>
 
+#include "test_comparisons.h"
 #include "test_macros.h"
-#include "../../types.h"
 
 // Test constraint
-static_assert(!CanCompare<NonComparable, NonComparable>);
+static_assert(!HasOperatorEqual<NonComparable, NonComparable>);
 
-static_assert(CanCompare<std::expected<int, int>, std::expected<int, int>>);
-static_assert(CanCompare<std::expected<int, int>, std::expected<short, short>>);
+static_assert(HasOperatorEqual<std::expected<int, int>, std::expected<int, int>>);
+static_assert(HasOperatorEqual<std::expected<int, int>, std::expected<short, short>>);
 
 #if TEST_STD_VER >= 26
 // https://wg21.link/P3379R0
-static_assert(!CanCompare<std::expected<int, int>, std::expected<void, int>>);
-static_assert(CanCompare<std::expected<int, int>, std::expected<int, int>>);
-static_assert(!CanCompare<std::expected<NonComparable, int>, std::expected<NonComparable, int>>);
-static_assert(!CanCompare<std::expected<int, NonComparable>, std::expected<int, NonComparable>>);
-static_assert(!CanCompare<std::expected<NonComparable, int>, std::expected<int, NonComparable>>);
-static_assert(!CanCompare<std::expected<int, NonComparable>, std::expected<NonComparable, int>>);
+static_assert(!HasOperatorEqual<std::expected<int, int>, std::expected<void, int>>);
+static_assert(HasOperatorEqual<std::expected<int, int>, std::expected<int, int>>);
+static_assert(!HasOperatorEqual<std::expected<NonComparable, int>, std::expected<NonComparable, int>>);
+static_assert(!HasOperatorEqual<std::expected<int, NonComparable>, std::expected<int, NonComparable>>);
+static_assert(!HasOperatorEqual<std::expected<NonComparable, int>, std::expected<int, NonComparable>>);
+static_assert(!HasOperatorEqual<std::expected<int, NonComparable>, std::expected<NonComparable, int>>);
 #else
 // Note this is true because other overloads in expected<non-void> are unconstrained
-static_assert(CanCompare<std::expected<void, int>, std::expected<int, int>>);
+static_assert(HasOperatorEqual<std::expected<void, int>, std::expected<int, int>>);
 #endif
 constexpr bool test() {
   // x.has_value() && y.has_value()
diff --git a/libcxx/test/std/utilities/expected/expected.expected/equality/equality.unexpected.pass.cpp b/libcxx/test/std/utilities/expected/expected.expected/equality/equality.unexpected.pass.cpp
index 6c7d2f39514e7..153cbbddf3062 100644
--- a/libcxx/test/std/utilities/expected/expected.expected/equality/equality.unexpected.pass.cpp
+++ b/libcxx/test/std/utilities/expected/expected.expected/equality/equality.unexpected.pass.cpp
@@ -16,14 +16,14 @@
 #include <type_traits>
 #include <utility>
 
+#include "test_comparisons.h"
 #include "test_macros.h"
-#include "../../types.h"
 
 #if TEST_STD_VER >= 26
 // https://wg21.link/P3379R0
-static_assert(CanCompare<std::expected<EqualityComparable, EqualityComparable>, std::unexpected<int>>);
-static_assert(CanCompare<std::expected<EqualityComparable, int>, std::unexpected<EqualityComparable>>);
-static_assert(!CanCompare<std::expected<EqualityComparable, NonComparable>, std::unexpected<int>>);
+static_assert(HasOperatorEqual<std::expected<EqualityComparable, EqualityComparable>, std::unexpected<int>>);
+static_assert(HasOperatorEqual<std::expected<EqualityComparable, int>, std::unexpected<EqualityComparable>>);
+static_assert(!HasOperatorEqual<std::expected<EqualityComparable, NonComparable>, std::unexpected<int>>);
 #endif
 
 constexpr bool test() {
diff --git a/libcxx/test/std/utilities/expected/expected.void/equality/equality.other_expected.pass.cpp b/libcxx/test/std/utilities/expected/expected.void/equality/equality.other_expected.pass.cpp
index b6c3d8deee644..af53d0c00f578 100644
--- a/libcxx/test/std/utilities/expected/expected.void/equality/equality.other_expected.pass.cpp
+++ b/libcxx/test/std/utilities/expected/expected.void/equality/equality.other_expected.pass.cpp
@@ -17,26 +17,26 @@
 #include <type_traits>
 #include <utility>
 
+#include "test_comparisons.h"
 #include "test_macros.h"
-#include "../../types.h"
 
 struct Foo{};
-static_assert(!CanCompare<Foo, Foo>);
+static_assert(!HasOperatorEqual<Foo, Foo>);
 
-static_assert(CanCompare<std::expected<void, int>, std::expected<void, int>>);
-static_assert(CanCompare<std::expected<void, int>, std::expected<void, short>>);
+static_assert(HasOperatorEqual<std::expected<void, int>, std::expected<void, int>>);
+static_assert(HasOperatorEqual<std::expected<void, int>, std::expected<void, short>>);
 
 #if TEST_STD_VER >= 26
 // https://wg21.link/P3379R0
-static_assert(!CanCompare<std::expected<void, int>, std::expected<int, int>>);
-static_assert(CanCompare<std::expected<void, int>, std::expected<void, int>>);
-static_assert(CanCompare<std::expected<void, int>, std::expected<void, int>>);
-static_assert(!CanCompare<std::expected<void, NonComparable>, std::expected<void, NonComparable>>);
-static_assert(!CanCompare<std::expected<void, int>, std::expected<void, NonComparable>>);
-static_assert(!CanCompare<std::expected<void, NonComparable>, std::expected<void, int>>);
+static_assert(!HasOperatorEqual<std::expected<void, int>, std::expected<int, int>>);
+static_assert(HasOperatorEqual<std::expected<void, int>, std::expected<void, int>>);
+static_assert(HasOperatorEqual<std::expected<void, int>, std::expected<void, int>>);
+static_assert(!HasOperatorEqual<std::expected<void, NonComparable>, std::expected<void, NonComparable>>);
+static_assert(!HasOperatorEqual<std::expected<void, int>, std::expected<void, NonComparable>>);
+static_assert(!HasOperatorEqual<std::expected<void, NonComparable>, std::expected<void, int>>);
 #else
 // Note this is true because other overloads in expected<non-void> are unconstrained
-static_assert(CanCompare<std::expected<void, int>, std::expected<int, int>>);
+static_assert(HasOperatorEqual<std::expected<void, int>, std::expected<int, int>>);
 #endif
 
 constexpr bool test() {
diff --git a/libcxx/test/std/utilities/expected/expected.void/equality/equality.unexpected.pass.cpp b/libcxx/test/std/utilities/expected/expected.void/equality/equality.unexpected.pass.cpp
index f37f38bb71512..8d040d2ab7c0a 100644
--- a/libcxx/test/std/utilities/expected/expected.void/equality/equality.unexpected.pass.cpp
+++ b/libcxx/test/std/utilities/expected/expected.void/equality/equality.unexpected.pass.cpp
@@ -16,14 +16,14 @@
 #include <type_traits>
 #include <utility>
 
+#include "test_comparisons.h"
 #include "test_macros.h"
-#include "../../types.h"
 
 #if TEST_STD_VER >= 26
 // https://wg21.link/P3379R0
-static_assert(CanCompare<std::expected<void, EqualityComparable>, std::unexpected<int>>);
-static_assert(CanCompare<std::expected<void, int>, std::unexpected<EqualityComparable>>);
-static_assert(!CanCompare<std::expected<void, NonComparable>, std::unexpected<int>>);
+static_assert(HasOperatorEqual<std::expected<void, EqualityComparable>, std::unexpected<int>>);
+static_assert(HasOperatorEqual<std::expected<void, int>, std::unexpected<EqualityComparable>>);
+static_assert(!HasOperatorEqual<std::expected<void, NonComparable>, std::unexpected<int>>);
 #endif
 
 constexpr bool test() {
diff --git a/libcxx/test/std/utilities/expected/types.h b/libcxx/test/std/utilities/expected/types.h
index 11473ca3d97de..df73ebdfe495e 100644
--- a/libcxx/test/std/utilities/expected/types.h
+++ b/libcxx/test/std/utilities/expected/types.h
@@ -336,17 +336,4 @@ struct CheckForInvalidWrites : public CheckForInvalidWritesBase<WithPaddedExpect
   }
 };
 
-struct NonComparable {};
-
-struct EqualityComparable {
-  int i;
-  constexpr EqualityComparable(int ii) : i(ii) {}
-
-  friend constexpr bool operator==(const EqualityComparable& data, int ii) { return data.i == ii; }
-};
-
-// Test constraint
-template <class T1, class T2>
-concept CanCompare = requires(T1 t1, T2 t2) { t1 == t2; };
-
 #endif // TEST_STD_UTILITIES_EXPECTED_TYPES_H
diff --git a/libcxx/test/support/test_comparisons.h b/libcxx/test/support/test_comparisons.h
index 86cb26e21273d..f4a86774308ac 100644
--- a/libcxx/test/support/test_comparisons.h
+++ b/libcxx/test/support/test_comparisons.h
@@ -270,7 +270,7 @@ struct PartialOrder {
 
 #endif // TEST_STD_VER >= 20
 
-#if TEST_STD_VER >= 26
+#if TEST_STD_VER >= 23
 
 template <typename T1, typename T2 = T1>
 concept HasOperatorEqual = requires(T1 t1, T2 t2) { t1 == t2; };

>From 47b9765978a0bda5cd192df8f9db6b2a4476d461 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Sat, 10 May 2025 10:17:28 +0300
Subject: [PATCH 03/15] Tests + fixes

---
 libcxx/include/optional                       |  2 +-
 .../optional.comp_with_t/equal.pass.cpp       | 22 ++++++
 .../optional.comp_with_t/greater.pass.cpp     | 20 +++++
 .../greater_equal.pass.cpp                    | 20 +++++
 .../optional.comp_with_t/less_equal.pass.cpp  | 20 +++++
 .../optional.comp_with_t/less_than.pass.cpp   | 20 +++++
 .../optional.comp_with_t/not_equal.pass.cpp   | 22 ++++++
 .../optional/optional.relops/equal.pass.cpp   | 14 +++-
 .../optional.relops/greater_equal.pass.cpp    | 13 +++
 .../optional.relops/greater_than.pass.cpp     | 13 +++
 .../optional.relops/less_equal.pass.cpp       | 13 +++
 .../optional.relops/less_than.pass.cpp        | 13 +++
 .../optional.relops/not_equal.pass.cpp        | 15 ++++
 libcxx/test/support/test_comparisons.h        | 79 ++++++-------------
 14 files changed, 227 insertions(+), 59 deletions(-)

diff --git a/libcxx/include/optional b/libcxx/include/optional
index fede9a3e2751f..e52d3675a9182 100644
--- a/libcxx/include/optional
+++ b/libcxx/include/optional
@@ -1342,7 +1342,7 @@ template <
 _LIBCPP_HIDE_FROM_ABI constexpr bool operator<=(const _Tp& __v, const optional<_Up>& __x)
 #    if _LIBCPP_STD_VER >= 26
   requires(!__is_std_optional<_Tp>::value) && requires {
-    { __v <= __x } -> __core_convertible_to<bool>;
+    { __v <= *__x } -> __core_convertible_to<bool>;
   }
 #    endif
 {
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 0636da7bcdf23..ce5c8bc5a7053 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
@@ -14,8 +14,30 @@
 
 #include <optional>
 
+#include "test_comparisons.h"
 #include "test_macros.h"
 
+#if TEST_STD_VER >= 26
+
+// 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(!HasOperatorEqual<NonComparable, std::optional<NonComparable>>);
+static_assert(!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(!HasOperatorEqual<std::optional<NonComparable>,NonComparable>);
+static_assert(!HasOperatorEqual<std::optional<EqualityComparable>, NonComparable>);
+
+#endif
+
 using std::optional;
 
 struct X {
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 2010157a8d011..b63b85b000930 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
@@ -14,8 +14,28 @@
 
 #include <optional>
 
+#include "test_comparisons.h"
 #include "test_macros.h"
 
+#if TEST_STD_VER >= 26
+
+// Test SFINAE.
+static_assert(HasOperatorGreaterThan<std::optional<ThreeWayComparable>, int>);
+static_assert(HasOperatorGreaterThan<std::optional<ThreeWayComparable>, ThreeWayComparable>);
+
+static_assert(!HasOperatorGreaterThan<std::optional<NonComparable>, NonComparable>);
+static_assert(!HasOperatorGreaterThan<std::optional<ThreeWayComparable>, NonComparable>);
+static_assert(!HasOperatorGreaterThan<std::optional<NonComparable>, ThreeWayComparable>);
+
+static_assert(HasOperatorGreaterThan<int, std::optional<ThreeWayComparable>>);
+static_assert(HasOperatorGreaterThan<ThreeWayComparable, std::optional<ThreeWayComparable>>);
+
+static_assert(!HasOperatorGreaterThan<NonComparable, std::optional<NonComparable>>);
+static_assert(!HasOperatorGreaterThan<NonComparable, std::optional<ThreeWayComparable>>);
+static_assert(!HasOperatorGreaterThan<ThreeWayComparable, std::optional<NonComparable>>);
+
+#endif
+
 using std::optional;
 
 struct X {
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 2e1e9b9316111..bb1a8c551d3d5 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
@@ -14,8 +14,28 @@
 
 #include <optional>
 
+#include "test_comparisons.h"
 #include "test_macros.h"
 
+#if TEST_STD_VER >= 26
+
+// Test SFINAE.
+static_assert(HasOperatorGreaterThanEqual<std::optional<ThreeWayComparable>, int>);
+static_assert(HasOperatorGreaterThanEqual<std::optional<ThreeWayComparable>, ThreeWayComparable>);
+
+static_assert(!HasOperatorGreaterThanEqual<std::optional<NonComparable>, NonComparable>);
+static_assert(!HasOperatorGreaterThanEqual<std::optional<ThreeWayComparable>, NonComparable>);
+static_assert(!HasOperatorGreaterThanEqual<std::optional<NonComparable>, ThreeWayComparable>);
+
+static_assert(HasOperatorGreaterThanEqual<int, std::optional<ThreeWayComparable>>);
+static_assert(HasOperatorGreaterThanEqual<ThreeWayComparable, std::optional<ThreeWayComparable>>);
+
+static_assert(!HasOperatorGreaterThanEqual<NonComparable, std::optional<NonComparable>>);
+static_assert(!HasOperatorGreaterThanEqual<NonComparable, std::optional<ThreeWayComparable>>);
+static_assert(!HasOperatorGreaterThanEqual<ThreeWayComparable, std::optional<NonComparable>>);
+
+#endif
+
 using std::optional;
 
 struct X {
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 7026c24de5dbf..8b08ec3deea5a 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
@@ -14,8 +14,28 @@
 
 #include <optional>
 
+#include "test_comparisons.h"
 #include "test_macros.h"
 
+#if TEST_STD_VER >= 26
+
+// Test SFINAE.
+static_assert(HasOperatorLessThanEqual<std::optional<ThreeWayComparable>, int>);
+static_assert(HasOperatorLessThanEqual<std::optional<ThreeWayComparable>, ThreeWayComparable>);
+
+static_assert(!HasOperatorLessThanEqual<std::optional<NonComparable>, NonComparable>);
+static_assert(!HasOperatorLessThanEqual<std::optional<ThreeWayComparable>, NonComparable>);
+static_assert(!HasOperatorLessThanEqual<std::optional<NonComparable>, ThreeWayComparable>);
+
+static_assert(HasOperatorLessThanEqual<int, std::optional<ThreeWayComparable>>);
+static_assert(HasOperatorLessThanEqual<ThreeWayComparable, std::optional<ThreeWayComparable>>);
+
+static_assert(!HasOperatorLessThanEqual<NonComparable, std::optional<NonComparable>>);
+static_assert(!HasOperatorLessThanEqual<NonComparable, std::optional<ThreeWayComparable>>);
+static_assert(!HasOperatorLessThanEqual<ThreeWayComparable, std::optional<NonComparable>>);
+
+#endif
+
 using std::optional;
 
 struct X {
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 b3d98684ba20b..3ef23a3224520 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
@@ -14,8 +14,28 @@
 
 #include <optional>
 
+#include "test_comparisons.h"
 #include "test_macros.h"
 
+#if TEST_STD_VER >= 26
+
+// Test SFINAE.
+static_assert(HasOperatorLessThan<std::optional<ThreeWayComparable>, int>);
+static_assert(HasOperatorLessThan<std::optional<ThreeWayComparable>, ThreeWayComparable>);
+
+static_assert(!HasOperatorLessThan<std::optional<NonComparable>, NonComparable>);
+static_assert(!HasOperatorLessThan<std::optional<ThreeWayComparable>, NonComparable>);
+static_assert(!HasOperatorLessThan<std::optional<NonComparable>, ThreeWayComparable>);
+
+static_assert(HasOperatorLessThan<int, std::optional<ThreeWayComparable>>);
+static_assert(HasOperatorLessThan<ThreeWayComparable, std::optional<ThreeWayComparable>>);
+
+static_assert(!HasOperatorLessThan<NonComparable, std::optional<NonComparable>>);
+static_assert(!HasOperatorLessThan<NonComparable, std::optional<ThreeWayComparable>>);
+static_assert(!HasOperatorLessThan<ThreeWayComparable, std::optional<NonComparable>>);
+
+#endif
+
 using std::optional;
 
 struct X {
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 36bc526e763fe..4c7dff6994fe3 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
@@ -14,8 +14,30 @@
 
 #include <optional>
 
+#include "test_comparisons.h"
 #include "test_macros.h"
 
+#if TEST_STD_VER >= 26
+
+// 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(!HasOperatorNotEqual<NonComparable, std::optional<NonComparable>>);
+static_assert(!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(!HasOperatorNotEqual<std::optional<NonComparable>,NonComparable>);
+static_assert(!HasOperatorNotEqual<std::optional<EqualityComparable>, NonComparable>);
+
+#endif
+
 using std::optional;
 
 struct X {
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 e41c7683053dc..6915b604d4ef4 100644
--- a/libcxx/test/std/utilities/optional/optional.relops/equal.pass.cpp
+++ b/libcxx/test/std/utilities/optional/optional.relops/equal.pass.cpp
@@ -15,13 +15,21 @@
 #include <type_traits>
 #include <cassert>
 
-#include "test_macros.h"
 #include "test_comparisons.h"
+#include "test_macros.h"
+
+#if TEST_STD_VER >= 26
 
 // Test SFINAE.
 
-static_assert(HasOperatorEqual<std::optional<int>, std::optional<int>>);
-static_assert(HasOperatorEqual<std::optional<EqualityComparable>, std::optional<EqualityComparable>>);
+static_assert(HasOperatorEqual<std::optional<int>>);
+static_assert(HasOperatorEqual<std::optional<EqualityComparable>>);
+static_assert(HasOperatorEqual<std::optional<EqualityComparable>, std::optional<int>>);
+
+static_assert(!HasOperatorEqual<std::optional<NonComparable>>);
+static_assert(!HasOperatorEqual<std::optional<EqualityComparable>, std::optional<NonComparable>>);
+
+#endif
 
 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 399823c868b5e..d14e7df6abc80 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
@@ -13,8 +13,21 @@
 
 #include <optional>
 
+#include "test_comparisons.h"
 #include "test_macros.h"
 
+#if TEST_STD_VER >= 26
+
+// 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>>);
+
+#endif
+
 using std::optional;
 
 struct X {
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 6b877c3011cb0..f19ea23e8ae78 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
@@ -13,8 +13,21 @@
 
 #include <optional>
 
+#include "test_comparisons.h"
 #include "test_macros.h"
 
+#if TEST_STD_VER >= 26
+
+// 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>>);
+
+#endif
+
 using std::optional;
 
 struct X {
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 aa605cd3a1e44..bd81a79f1265e 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
@@ -13,8 +13,21 @@
 
 #include <optional>
 
+#include "test_comparisons.h"
 #include "test_macros.h"
 
+#if TEST_STD_VER >= 26
+
+// 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>>);
+
+#endif
+
 using std::optional;
 
 struct X {
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 53474ebc5f0e9..c87bfd6f73e54 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
@@ -13,8 +13,21 @@
 
 #include <optional>
 
+#include "test_comparisons.h"
 #include "test_macros.h"
 
+#if TEST_STD_VER >= 26
+
+// 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>>);
+
+#endif
+
 using std::optional;
 
 struct X {
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 290459d9ed090..0397e6b8f1fc7 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
@@ -15,8 +15,23 @@
 #include <type_traits>
 #include <cassert>
 
+#include "test_comparisons.h"
 #include "test_macros.h"
 
+#if TEST_STD_VER >= 26
+
+// 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(!HasOperatorNotEqual<std::optional<NonComparable>>);
+static_assert(!HasOperatorNotEqual<std::optional<EqualityComparable>, std::optional<NonComparable>>);
+
+#endif
+
+
 using std::optional;
 
 struct X {
diff --git a/libcxx/test/support/test_comparisons.h b/libcxx/test/support/test_comparisons.h
index f4a86774308ac..9cb5a8ed62f58 100644
--- a/libcxx/test/support/test_comparisons.h
+++ b/libcxx/test/support/test_comparisons.h
@@ -279,16 +279,16 @@ template <typename T1, typename T2 = T1>
 concept HasOperatorNotEqual = requires(T1 t1, T2 t2) { t1 != t2; };
 
 template <typename T1, typename T2 = T1>
-concept HasOperatorLessThen = requires(T1 t1, T2 t2) { t1 < t2; };
+concept HasOperatorLessThan = requires(T1 t1, T2 t2) { t1 < t2; };
 
 template <typename T1, typename T2 = T1>
-concept HasOperatorGreaterThen = requires(T1 t1, T2 t2) { t1 > t2; };
+concept HasOperatorGreaterThan = requires(T1 t1, T2 t2) { t1 > t2; };
 
 template <typename T1, typename T2 = T1>
-concept HasOperatorLessThenEqual = requires(T1 t1, T2 t2) { t1 <= t2; };
+concept HasOperatorLessThanEqual = requires(T1 t1, T2 t2) { t1 <= t2; };
 
 template <typename T1, typename T2 = T1>
-concept HasOperatorGreaterThenEqual = requires(T1 t1, T2 t2) { t1 >= t2; };
+concept HasOperatorGreaterThanEqual = requires(T1 t1, T2 t2) { t1 >= t2; };
 
 template <typename T1, typename T2 = T1>
 concept HasOperatorSpaceship = requires(T1 t1, T2 t2) { t1 <=> t2; };
@@ -300,8 +300,8 @@ concept CanCompareWithSpaceship = HasOperatorSpaceship<T1, T2> && requires(T1 t1
 
 template <typename T1, typename T2 = T1>
 concept CanCompare =
-    HasOperatorEqual<T1, T2> && HasOperatorNotEqual<T1, T2> && HasOperatorLessThen<T1, T2> &&
-    HasOperatorGreaterThen<T1, T2> && HasOperatorLessThenEqual<T1, T2> && HasOperatorGreaterThenEqual<T1, T2>;
+    HasOperatorEqual<T1, T2> && HasOperatorNotEqual<T1, T2> && HasOperatorLessThan<T1, T2> &&
+    HasOperatorGreaterThan<T1, T2> && HasOperatorLessThanEqual<T1, T2> && HasOperatorGreaterThanEqual<T1, T2>;
 
 struct NonComparable {};
 
@@ -319,56 +319,25 @@ class EqualityComparable {
 };
 static_assert(std::equality_comparable<EqualityComparable>);
 
-// class NotEqualityComparable {
-// public:
-//   constexpr NotEqualityComparable(int value) : value_{value} {};
-
-//   friend constexpr bool operator!=(const NotEqualityComparable&, const NotEqualityComparable&) noexcept = default;
-
-// private:
-//   int value_;
-// };
-// static_assert(!std::equality_comparable<NotEqualityComparable>);
-
-// class LessThanComparable {
-// public:
-//   constexpr LessThanComparable(int value) : value_{value} {};
-
-//   friend constexpr bool operator<(const LessThanComparable&, const LessThanComparable&) noexcept = default;
-
-// private:
-//   int value_;
-// };
-
-// class GreaterThanComparable {
-// public:
-//   constexpr GreaterThanComparable(int value) : value_{value} {};
-
-//   friend constexpr bool operator>(const GreaterThanComparable&, const GreaterThanComparable&) noexcept = default;
-
-// private:
-//   int value_;
-// };
-
-// class LessThanEqualComparable {
-// public:
-//   constexpr LessThanEqualComparable(int value) : value_{value} {};
-
-//   friend constexpr bool operator<=(const LessThanEqualComparable&, const LessThanEqualComparable&) noexcept = default;
-
-// private:
-//   int value_;
-// };
-// class GreaterThanEqualComparable {
-// public:
-//   constexpr GreaterThanEqualComparable(int value) : value_{value} {};
-
-//   friend constexpr bool
-//   operator>=(const GreaterThanEqualComparable&, const GreaterThanEqualComparable&) noexcept = default;
+class ThreeWayComparable {
+public:
+  constexpr ThreeWayComparable(int value) : value_{value} {};
 
-// private:
-//   int value_;
-// };
+  friend constexpr std::strong_ordering operator<=>(const ThreeWayComparable&, const ThreeWayComparable&) noexcept = default;
+  friend constexpr bool operator==(const ThreeWayComparable&, const ThreeWayComparable&) noexcept = default;
+private:
+  int value_;
+};
+static_assert(std::equality_comparable<ThreeWayComparable>);
+static_assert(HasOperatorEqual<ThreeWayComparable>);
+static_assert(HasOperatorNotEqual<ThreeWayComparable>);
+static_assert(HasOperatorLessThan<ThreeWayComparable>);
+static_assert(HasOperatorGreaterThan<ThreeWayComparable>);
+static_assert(HasOperatorLessThanEqual<ThreeWayComparable>);
+static_assert(HasOperatorGreaterThanEqual<ThreeWayComparable>);
+static_assert(HasOperatorSpaceship<ThreeWayComparable>);
+static_assert(CanCompare<ThreeWayComparable>);
+static_assert(CanCompareWithSpaceship<ThreeWayComparable>);
 
 #endif // TEST_STD_VER >= 26
 

>From 58149a6bd4d73c25643e6095366f060b39f804e4 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Sat, 10 May 2025 10:36:00 +0300
Subject: [PATCH 04/15] Cleanup

---
 .../optional.comp_with_t/equal.pass.cpp       |  1 -
 libcxx/test/support/test_comparisons.h        | 28 +++++++++----------
 2 files changed, 13 insertions(+), 16 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 ce5c8bc5a7053..d7561fff4dbb3 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
@@ -28,7 +28,6 @@ static_assert(HasOperatorEqual<EqualityComparable, std::optional<EqualityCompara
 static_assert(!HasOperatorEqual<NonComparable, std::optional<NonComparable>>);
 static_assert(!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>);
diff --git a/libcxx/test/support/test_comparisons.h b/libcxx/test/support/test_comparisons.h
index 9cb5a8ed62f58..fc20ef1ae607c 100644
--- a/libcxx/test/support/test_comparisons.h
+++ b/libcxx/test/support/test_comparisons.h
@@ -293,20 +293,15 @@ concept HasOperatorGreaterThanEqual = requires(T1 t1, T2 t2) { t1 >= t2; };
 template <typename T1, typename T2 = T1>
 concept HasOperatorSpaceship = requires(T1 t1, T2 t2) { t1 <=> t2; };
 
-template <typename T1, typename T2 = T1>
-concept CanCompareWithSpaceship = HasOperatorSpaceship<T1, T2> && requires(T1 t1, T2 t2) {
-  { t1 <=> t2 } -> std::same_as<std::strong_ordering>;
-};
-
-template <typename T1, typename T2 = T1>
-concept CanCompare =
-    HasOperatorEqual<T1, T2> && HasOperatorNotEqual<T1, T2> && HasOperatorLessThan<T1, T2> &&
-    HasOperatorGreaterThan<T1, T2> && HasOperatorLessThanEqual<T1, T2> && HasOperatorGreaterThanEqual<T1, T2>;
-
 struct NonComparable {};
-
 static_assert(!std::equality_comparable<NonComparable>);
-static_assert(!CanCompare<NonComparable>);
+static_assert(!HasOperatorEqual<NonComparable>);
+static_assert(!HasOperatorNotEqual<NonComparable>);
+static_assert(!HasOperatorLessThan<NonComparable>);
+static_assert(!HasOperatorGreaterThan<NonComparable>);
+static_assert(!HasOperatorLessThanEqual<NonComparable>);
+static_assert(!HasOperatorGreaterThanEqual<NonComparable>);
+static_assert(!HasOperatorSpaceship<NonComparable>);
 
 class EqualityComparable {
 public:
@@ -318,17 +313,22 @@ class EqualityComparable {
   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} {};
 
-  friend constexpr std::strong_ordering operator<=>(const ThreeWayComparable&, const ThreeWayComparable&) noexcept = default;
   friend constexpr bool operator==(const ThreeWayComparable&, const ThreeWayComparable&) noexcept = default;
+  friend constexpr std::strong_ordering
+  operator<=>(const ThreeWayComparable&, const ThreeWayComparable&) noexcept = default;
+
 private:
   int value_;
 };
 static_assert(std::equality_comparable<ThreeWayComparable>);
+static_assert(std::three_way_comparable<ThreeWayComparable>);
 static_assert(HasOperatorEqual<ThreeWayComparable>);
 static_assert(HasOperatorNotEqual<ThreeWayComparable>);
 static_assert(HasOperatorLessThan<ThreeWayComparable>);
@@ -336,8 +336,6 @@ static_assert(HasOperatorGreaterThan<ThreeWayComparable>);
 static_assert(HasOperatorLessThanEqual<ThreeWayComparable>);
 static_assert(HasOperatorGreaterThanEqual<ThreeWayComparable>);
 static_assert(HasOperatorSpaceship<ThreeWayComparable>);
-static_assert(CanCompare<ThreeWayComparable>);
-static_assert(CanCompareWithSpaceship<ThreeWayComparable>);
 
 #endif // TEST_STD_VER >= 26
 

>From 4e3c8c62463091bb9dfef4aff5f606ca825d4123 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Sat, 10 May 2025 12:49:17 +0300
Subject: [PATCH 05/15] Refactorings

---
 libcxx/test/support/test_comparisons.h | 22 +++++++++++-----------
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/libcxx/test/support/test_comparisons.h b/libcxx/test/support/test_comparisons.h
index fc20ef1ae607c..0f15051971f6c 100644
--- a/libcxx/test/support/test_comparisons.h
+++ b/libcxx/test/support/test_comparisons.h
@@ -276,19 +276,19 @@ template <typename T1, typename T2 = T1>
 concept HasOperatorEqual = requires(T1 t1, T2 t2) { t1 == t2; };
 
 template <typename T1, typename T2 = T1>
-concept HasOperatorNotEqual = requires(T1 t1, T2 t2) { t1 != t2; };
+concept HasOperatorGreaterThan = requires(T1 t1, T2 t2) { t1 > t2; };
 
-template <typename T1, typename T2 = T1>
-concept HasOperatorLessThan = requires(T1 t1, T2 t2) { t1 < t2; };
 
 template <typename T1, typename T2 = T1>
-concept HasOperatorGreaterThan = requires(T1 t1, T2 t2) { t1 > t2; };
+concept HasOperatorGreaterThanEqual = requires(T1 t1, T2 t2) { t1 >= t2; };
+template <typename T1, typename T2 = T1>
+concept HasOperatorLessThan = requires(T1 t1, T2 t2) { t1 < t2; };
 
 template <typename T1, typename T2 = T1>
 concept HasOperatorLessThanEqual = requires(T1 t1, T2 t2) { t1 <= t2; };
 
 template <typename T1, typename T2 = T1>
-concept HasOperatorGreaterThanEqual = requires(T1 t1, T2 t2) { t1 >= t2; };
+concept HasOperatorNotEqual = requires(T1 t1, T2 t2) { t1 != t2; };
 
 template <typename T1, typename T2 = T1>
 concept HasOperatorSpaceship = requires(T1 t1, T2 t2) { t1 <=> t2; };
@@ -296,11 +296,11 @@ concept HasOperatorSpaceship = requires(T1 t1, T2 t2) { t1 <=> t2; };
 struct NonComparable {};
 static_assert(!std::equality_comparable<NonComparable>);
 static_assert(!HasOperatorEqual<NonComparable>);
-static_assert(!HasOperatorNotEqual<NonComparable>);
-static_assert(!HasOperatorLessThan<NonComparable>);
 static_assert(!HasOperatorGreaterThan<NonComparable>);
-static_assert(!HasOperatorLessThanEqual<NonComparable>);
 static_assert(!HasOperatorGreaterThanEqual<NonComparable>);
+static_assert(!HasOperatorLessThan<NonComparable>);
+static_assert(!HasOperatorLessThanEqual<NonComparable>);
+static_assert(!HasOperatorNotEqual<NonComparable>);
 static_assert(!HasOperatorSpaceship<NonComparable>);
 
 class EqualityComparable {
@@ -330,11 +330,11 @@ class ThreeWayComparable {
 static_assert(std::equality_comparable<ThreeWayComparable>);
 static_assert(std::three_way_comparable<ThreeWayComparable>);
 static_assert(HasOperatorEqual<ThreeWayComparable>);
-static_assert(HasOperatorNotEqual<ThreeWayComparable>);
-static_assert(HasOperatorLessThan<ThreeWayComparable>);
 static_assert(HasOperatorGreaterThan<ThreeWayComparable>);
-static_assert(HasOperatorLessThanEqual<ThreeWayComparable>);
 static_assert(HasOperatorGreaterThanEqual<ThreeWayComparable>);
+static_assert(HasOperatorLessThan<ThreeWayComparable>);
+static_assert(HasOperatorLessThanEqual<ThreeWayComparable>);
+static_assert(HasOperatorNotEqual<ThreeWayComparable>);
 static_assert(HasOperatorSpaceship<ThreeWayComparable>);
 
 #endif // TEST_STD_VER >= 26

>From e94dd675e62002acad3dffec9d61256b8c519033 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Sat, 10 May 2025 13:06:26 +0300
Subject: [PATCH 06/15] Fixed formatting

---
 libcxx/include/__functional/reference_wrapper.h                | 2 +-
 .../refwrap.comparissons/equal.refwrap.const_ref.pass.cpp      | 1 -
 .../std/utilities/optional/optional.comp_with_t/equal.pass.cpp | 2 +-
 .../utilities/optional/optional.comp_with_t/not_equal.pass.cpp | 3 +--
 .../std/utilities/optional/optional.relops/not_equal.pass.cpp  | 1 -
 libcxx/test/support/test_comparisons.h                         | 1 -
 6 files changed, 3 insertions(+), 7 deletions(-)

diff --git a/libcxx/include/__functional/reference_wrapper.h b/libcxx/include/__functional/reference_wrapper.h
index 4b64b7ce262ef..c46203a4ca9a4 100644
--- a/libcxx/include/__functional/reference_wrapper.h
+++ b/libcxx/include/__functional/reference_wrapper.h
@@ -16,9 +16,9 @@
 #include <__memory/addressof.h>
 #include <__type_traits/desugars_to.h>
 #include <__type_traits/enable_if.h>
-#include <__type_traits/is_core_convertible.h>
 #include <__type_traits/invoke.h>
 #include <__type_traits/is_const.h>
+#include <__type_traits/is_core_convertible.h>
 #include <__type_traits/remove_cvref.h>
 #include <__type_traits/void_t.h>
 #include <__utility/declval.h>
diff --git a/libcxx/test/std/utilities/function.objects/refwrap/refwrap.comparissons/equal.refwrap.const_ref.pass.cpp b/libcxx/test/std/utilities/function.objects/refwrap/refwrap.comparissons/equal.refwrap.const_ref.pass.cpp
index 2e46cf8d1e478..316ff7c303315 100644
--- a/libcxx/test/std/utilities/function.objects/refwrap/refwrap.comparissons/equal.refwrap.const_ref.pass.cpp
+++ b/libcxx/test/std/utilities/function.objects/refwrap/refwrap.comparissons/equal.refwrap.const_ref.pass.cpp
@@ -25,7 +25,6 @@
 
 // Test SFINAE.
 
-
 static_assert(HasOperatorEqual<std::reference_wrapper<EqualityComparable>>);
 static_assert(HasOperatorEqual<std::reference_wrapper<EqualityComparable>, int>);
 
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 d7561fff4dbb3..54965b270dcce 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
@@ -32,7 +32,7 @@ static_assert(HasOperatorEqual<std::optional<int>, int>);
 static_assert(HasOperatorEqual<std::optional<EqualityComparable>, int>);
 static_assert(HasOperatorEqual<std::optional<EqualityComparable>, EqualityComparable>);
 
-static_assert(!HasOperatorEqual<std::optional<NonComparable>,NonComparable>);
+static_assert(!HasOperatorEqual<std::optional<NonComparable>, NonComparable>);
 static_assert(!HasOperatorEqual<std::optional<EqualityComparable>, NonComparable>);
 
 #endif
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 4c7dff6994fe3..97fb8ee447393 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
@@ -28,12 +28,11 @@ static_assert(HasOperatorNotEqual<EqualityComparable, std::optional<EqualityComp
 static_assert(!HasOperatorNotEqual<NonComparable, std::optional<NonComparable>>);
 static_assert(!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(!HasOperatorNotEqual<std::optional<NonComparable>,NonComparable>);
+static_assert(!HasOperatorNotEqual<std::optional<NonComparable>, NonComparable>);
 static_assert(!HasOperatorNotEqual<std::optional<EqualityComparable>, NonComparable>);
 
 #endif
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 0397e6b8f1fc7..1b7d2621c9193 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
@@ -31,7 +31,6 @@ static_assert(!HasOperatorNotEqual<std::optional<EqualityComparable>, std::optio
 
 #endif
 
-
 using std::optional;
 
 struct X {
diff --git a/libcxx/test/support/test_comparisons.h b/libcxx/test/support/test_comparisons.h
index 0f15051971f6c..9add3c4e65f95 100644
--- a/libcxx/test/support/test_comparisons.h
+++ b/libcxx/test/support/test_comparisons.h
@@ -278,7 +278,6 @@ concept HasOperatorEqual = requires(T1 t1, T2 t2) { t1 == t2; };
 template <typename T1, typename T2 = T1>
 concept HasOperatorGreaterThan = requires(T1 t1, T2 t2) { t1 > t2; };
 
-
 template <typename T1, typename T2 = T1>
 concept HasOperatorGreaterThanEqual = requires(T1 t1, T2 t2) { t1 >= t2; };
 template <typename T1, typename T2 = T1>

>From ab801b41215f3ecfb8250fa87bef72f011616ac5 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Sat, 10 May 2025 13:13:40 +0300
Subject: [PATCH 07/15] Include generator script results

---
 libcxx/include/version                        |  6 ++--
 ...bcxxabi.v1.stable.exceptions.nonew.abilist |  7 ++--
 .../expected.version.compile.pass.cpp         | 33 +++++++++++++++++++
 .../optional.version.compile.pass.cpp         |  4 +--
 .../tuple.version.compile.pass.cpp            |  4 +--
 .../utility.version.compile.pass.cpp          |  4 +--
 .../variant.version.compile.pass.cpp          |  4 +--
 .../version.version.compile.pass.cpp          |  4 +--
 8 files changed, 51 insertions(+), 15 deletions(-)

diff --git a/libcxx/include/version b/libcxx/include/version
index 77d97b93adc6c..3a173e30c47ae 100644
--- a/libcxx/include/version
+++ b/libcxx/include/version
@@ -80,8 +80,8 @@ __cpp_lib_constexpr_tuple                               201811L <tuple>
 __cpp_lib_constexpr_typeinfo                            202106L <typeinfo>
 __cpp_lib_constexpr_utility                             201811L <utility>
 __cpp_lib_constexpr_vector                              201907L <vector>
-__cpp_lib_constrained_equality                          202403L <optional> <tuple> <utility>
-                                                                <variant>
+__cpp_lib_constrained_equality                          202411L <expected> <optional> <tuple>
+                                                                <utility> <variant>
 __cpp_lib_containers_ranges                             202202L <deque> <forward_list> <list>
                                                                 <map> <queue> <set>
                                                                 <stack> <string> <unordered_map>
@@ -545,7 +545,7 @@ __cpp_lib_void_t                                        201411L <type_traits>
 # if !defined(_LIBCPP_ABI_VCRUNTIME)
 #   define __cpp_lib_constexpr_new                      202406L
 # endif
-// # define __cpp_lib_constrained_equality                 202403L
+// # define __cpp_lib_constrained_equality                 202411L
 // # define __cpp_lib_copyable_function                    202306L
 // # define __cpp_lib_debugging                            202311L
 // # define __cpp_lib_default_template_type_for_algorithm_values 202403L
diff --git a/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.exceptions.nonew.abilist b/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.exceptions.nonew.abilist
index 679a0626d3268..6b77c421fe13e 100644
--- a/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.exceptions.nonew.abilist
+++ b/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.exceptions.nonew.abilist
@@ -35,6 +35,7 @@
 {'is_defined': False, 'name': '_ZTVSt13runtime_error', 'size': 0, 'type': 'OBJECT'}
 {'is_defined': False, 'name': '_ZTVSt14overflow_error', 'size': 0, 'type': 'OBJECT'}
 {'is_defined': False, 'name': '_ZTVSt16invalid_argument', 'size': 0, 'type': 'OBJECT'}
+{'is_defined': False, 'name': '_ZTVSt9exception', 'size': 0, 'type': 'OBJECT'}
 {'is_defined': False, 'name': '_ZdaPv', 'type': 'FUNC'}
 {'is_defined': False, 'name': '_ZdaPvSt11align_val_t', 'type': 'FUNC'}
 {'is_defined': False, 'name': '_ZdlPv', 'type': 'FUNC'}
@@ -225,6 +226,7 @@
 {'is_defined': True, 'name': '_ZNKSt3__115basic_streambufIwNS_11char_traitsIwEEE6getlocEv', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNKSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strEv', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNKSt3__115error_condition7messageEv', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNKSt3__117bad_function_call4whatEv', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNKSt3__117moneypunct_bynameIcLb0EE11do_groupingEv', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNKSt3__117moneypunct_bynameIcLb0EE13do_neg_formatEv', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNKSt3__117moneypunct_bynameIcLb0EE13do_pos_formatEv', 'type': 'FUNC'}
@@ -773,6 +775,7 @@
 {'is_defined': True, 'name': '_ZNSt3__112system_errorD0Ev', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__112system_errorD1Ev', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__112system_errorD2Ev', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt3__113__hash_memoryEPKvm', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__113basic_filebufIcNS_11char_traitsIcEEE11__read_modeEv', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__113basic_filebufIcNS_11char_traitsIcEEE12__write_modeEv', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__113basic_filebufIcNS_11char_traitsIcEEE4openEPKcj', 'type': 'FUNC'}
@@ -953,7 +956,6 @@
 {'is_defined': True, 'name': '_ZNSt3__113shared_futureIvED1Ev', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__113shared_futureIvED2Ev', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__113shared_futureIvEaSERKS1_', 'type': 'FUNC'}
-{'is_defined': True, 'name': '_ZNSt3__113__hash_memoryEPKvm', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__114__num_get_base10__get_baseERNS_8ios_baseE', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__114__num_get_base5__srcE', 'size': 33, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '_ZNSt3__114__num_put_base12__format_intEPcPKcbj', 'type': 'FUNC'}
@@ -1156,7 +1158,6 @@
 {'is_defined': True, 'name': '_ZNSt3__117bad_function_callD0Ev', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__117bad_function_callD1Ev', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__117bad_function_callD2Ev', 'type': 'FUNC'}
-{'is_defined': True, 'name': '_ZNKSt3__117bad_function_call4whatEv', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__117iostream_categoryEv', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__117moneypunct_bynameIcLb0EE4initEPKc', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__117moneypunct_bynameIcLb1EE4initEPKc', 'type': 'FUNC'}
@@ -1966,6 +1967,8 @@
 {'is_defined': True, 'name': '_ZTVNSt3__120__codecvt_utf8_utf16IDiEE', 'size': 96, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '_ZTVNSt3__120__codecvt_utf8_utf16IDsEE', 'size': 96, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '_ZTVNSt3__120__codecvt_utf8_utf16IwEE', 'size': 96, 'type': 'OBJECT'}
+{'is_defined': True, 'name': '_ZTVNSt3__120__time_get_c_storageIcEE', 'size': 72, 'type': 'OBJECT'}
+{'is_defined': True, 'name': '_ZTVNSt3__120__time_get_c_storageIwEE', 'size': 72, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '_ZTVNSt3__13pmr15memory_resourceE', 'size': 56, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '_ZTVNSt3__13pmr25monotonic_buffer_resourceE', 'size': 56, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '_ZTVNSt3__13pmr26synchronized_pool_resourceE', 'size': 56, 'type': 'OBJECT'}
diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/expected.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/expected.version.compile.pass.cpp
index d58f726f66e2f..9c7a84f145dde 100644
--- a/libcxx/test/std/language.support/support.limits/support.limits.general/expected.version.compile.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/expected.version.compile.pass.cpp
@@ -20,6 +20,10 @@
 
 #if TEST_STD_VER < 14
 
+#  ifdef __cpp_lib_constrained_equality
+#    error "__cpp_lib_constrained_equality should not be defined before c++26"
+#  endif
+
 #  ifdef __cpp_lib_expected
 #    error "__cpp_lib_expected should not be defined before c++23"
 #  endif
@@ -30,6 +34,10 @@
 
 #elif TEST_STD_VER == 14
 
+#  ifdef __cpp_lib_constrained_equality
+#    error "__cpp_lib_constrained_equality should not be defined before c++26"
+#  endif
+
 #  ifdef __cpp_lib_expected
 #    error "__cpp_lib_expected should not be defined before c++23"
 #  endif
@@ -40,6 +48,10 @@
 
 #elif TEST_STD_VER == 17
 
+#  ifdef __cpp_lib_constrained_equality
+#    error "__cpp_lib_constrained_equality should not be defined before c++26"
+#  endif
+
 #  ifdef __cpp_lib_expected
 #    error "__cpp_lib_expected should not be defined before c++23"
 #  endif
@@ -50,6 +62,10 @@
 
 #elif TEST_STD_VER == 20
 
+#  ifdef __cpp_lib_constrained_equality
+#    error "__cpp_lib_constrained_equality should not be defined before c++26"
+#  endif
+
 #  ifdef __cpp_lib_expected
 #    error "__cpp_lib_expected should not be defined before c++23"
 #  endif
@@ -60,6 +76,10 @@
 
 #elif TEST_STD_VER == 23
 
+#  ifdef __cpp_lib_constrained_equality
+#    error "__cpp_lib_constrained_equality should not be defined before c++26"
+#  endif
+
 #  ifndef __cpp_lib_expected
 #    error "__cpp_lib_expected should be defined in c++23"
 #  endif
@@ -73,6 +93,19 @@
 
 #elif TEST_STD_VER > 23
 
+#  if !defined(_LIBCPP_VERSION)
+#    ifndef __cpp_lib_constrained_equality
+#      error "__cpp_lib_constrained_equality should be defined in c++26"
+#    endif
+#    if __cpp_lib_constrained_equality != 202411L
+#      error "__cpp_lib_constrained_equality should have the value 202411L in c++26"
+#    endif
+#  else
+#    ifdef __cpp_lib_constrained_equality
+#      error "__cpp_lib_constrained_equality should not be defined because it is unimplemented in libc++!"
+#    endif
+#  endif
+
 #  ifndef __cpp_lib_expected
 #    error "__cpp_lib_expected should be defined in c++26"
 #  endif
diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/optional.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/optional.version.compile.pass.cpp
index f8ff69f618777..32685972d6019 100644
--- a/libcxx/test/std/language.support/support.limits/support.limits.general/optional.version.compile.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/optional.version.compile.pass.cpp
@@ -123,8 +123,8 @@
 #    ifndef __cpp_lib_constrained_equality
 #      error "__cpp_lib_constrained_equality should be defined in c++26"
 #    endif
-#    if __cpp_lib_constrained_equality != 202403L
-#      error "__cpp_lib_constrained_equality should have the value 202403L in c++26"
+#    if __cpp_lib_constrained_equality != 202411L
+#      error "__cpp_lib_constrained_equality should have the value 202411L in c++26"
 #    endif
 #  else
 #    ifdef __cpp_lib_constrained_equality
diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/tuple.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/tuple.version.compile.pass.cpp
index f4a2fd8b29f45..b583edfc43ad0 100644
--- a/libcxx/test/std/language.support/support.limits/support.limits.general/tuple.version.compile.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/tuple.version.compile.pass.cpp
@@ -274,8 +274,8 @@
 #    ifndef __cpp_lib_constrained_equality
 #      error "__cpp_lib_constrained_equality should be defined in c++26"
 #    endif
-#    if __cpp_lib_constrained_equality != 202403L
-#      error "__cpp_lib_constrained_equality should have the value 202403L in c++26"
+#    if __cpp_lib_constrained_equality != 202411L
+#      error "__cpp_lib_constrained_equality should have the value 202411L in c++26"
 #    endif
 #  else
 #    ifdef __cpp_lib_constrained_equality
diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/utility.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/utility.version.compile.pass.cpp
index e0a83c7813b28..7dd3478576331 100644
--- a/libcxx/test/std/language.support/support.limits/support.limits.general/utility.version.compile.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/utility.version.compile.pass.cpp
@@ -405,8 +405,8 @@
 #    ifndef __cpp_lib_constrained_equality
 #      error "__cpp_lib_constrained_equality should be defined in c++26"
 #    endif
-#    if __cpp_lib_constrained_equality != 202403L
-#      error "__cpp_lib_constrained_equality should have the value 202403L in c++26"
+#    if __cpp_lib_constrained_equality != 202411L
+#      error "__cpp_lib_constrained_equality should have the value 202411L in c++26"
 #    endif
 #  else
 #    ifdef __cpp_lib_constrained_equality
diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/variant.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/variant.version.compile.pass.cpp
index dc4af4d09f9e5..4a7b9f7431a81 100644
--- a/libcxx/test/std/language.support/support.limits/support.limits.general/variant.version.compile.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/variant.version.compile.pass.cpp
@@ -103,8 +103,8 @@
 #    ifndef __cpp_lib_constrained_equality
 #      error "__cpp_lib_constrained_equality should be defined in c++26"
 #    endif
-#    if __cpp_lib_constrained_equality != 202403L
-#      error "__cpp_lib_constrained_equality should have the value 202403L in c++26"
+#    if __cpp_lib_constrained_equality != 202411L
+#      error "__cpp_lib_constrained_equality should have the value 202411L in c++26"
 #    endif
 #  else
 #    ifdef __cpp_lib_constrained_equality
diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
index aa33a2788f1eb..400309b944a1d 100644
--- a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
@@ -6494,8 +6494,8 @@
 #    ifndef __cpp_lib_constrained_equality
 #      error "__cpp_lib_constrained_equality should be defined in c++26"
 #    endif
-#    if __cpp_lib_constrained_equality != 202403L
-#      error "__cpp_lib_constrained_equality should have the value 202403L in c++26"
+#    if __cpp_lib_constrained_equality != 202411L
+#      error "__cpp_lib_constrained_equality should have the value 202411L in c++26"
 #    endif
 #  else
 #    ifdef __cpp_lib_constrained_equality

>From 77fb3600db0dc928fa30a1c4e013d479aeda1040 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Sat, 10 May 2025 13:46:45 +0300
Subject: [PATCH 08/15] Try to fix CI

---
 ...linux-gnu.libcxxabi.v1.stable.exceptions.nonew.abilist | 3 ---
 .../containers/sequences/array/compare.three_way.pass.cpp | 1 -
 .../compare.three_way.refwrap.refwrap.pass.cpp            | 8 ++++----
 3 files changed, 4 insertions(+), 8 deletions(-)

diff --git a/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.exceptions.nonew.abilist b/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.exceptions.nonew.abilist
index 6b77c421fe13e..7e0fa057b42b3 100644
--- a/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.exceptions.nonew.abilist
+++ b/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.exceptions.nonew.abilist
@@ -35,7 +35,6 @@
 {'is_defined': False, 'name': '_ZTVSt13runtime_error', 'size': 0, 'type': 'OBJECT'}
 {'is_defined': False, 'name': '_ZTVSt14overflow_error', 'size': 0, 'type': 'OBJECT'}
 {'is_defined': False, 'name': '_ZTVSt16invalid_argument', 'size': 0, 'type': 'OBJECT'}
-{'is_defined': False, 'name': '_ZTVSt9exception', 'size': 0, 'type': 'OBJECT'}
 {'is_defined': False, 'name': '_ZdaPv', 'type': 'FUNC'}
 {'is_defined': False, 'name': '_ZdaPvSt11align_val_t', 'type': 'FUNC'}
 {'is_defined': False, 'name': '_ZdlPv', 'type': 'FUNC'}
@@ -226,7 +225,6 @@
 {'is_defined': True, 'name': '_ZNKSt3__115basic_streambufIwNS_11char_traitsIwEEE6getlocEv', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNKSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strEv', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNKSt3__115error_condition7messageEv', 'type': 'FUNC'}
-{'is_defined': True, 'name': '_ZNKSt3__117bad_function_call4whatEv', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNKSt3__117moneypunct_bynameIcLb0EE11do_groupingEv', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNKSt3__117moneypunct_bynameIcLb0EE13do_neg_formatEv', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNKSt3__117moneypunct_bynameIcLb0EE13do_pos_formatEv', 'type': 'FUNC'}
@@ -775,7 +773,6 @@
 {'is_defined': True, 'name': '_ZNSt3__112system_errorD0Ev', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__112system_errorD1Ev', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__112system_errorD2Ev', 'type': 'FUNC'}
-{'is_defined': True, 'name': '_ZNSt3__113__hash_memoryEPKvm', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__113basic_filebufIcNS_11char_traitsIcEEE11__read_modeEv', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__113basic_filebufIcNS_11char_traitsIcEEE12__write_modeEv', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__113basic_filebufIcNS_11char_traitsIcEEE4openEPKcj', 'type': 'FUNC'}
diff --git a/libcxx/test/std/containers/sequences/array/compare.three_way.pass.cpp b/libcxx/test/std/containers/sequences/array/compare.three_way.pass.cpp
index 01be1db73041b..671747f89a82e 100644
--- a/libcxx/test/std/containers/sequences/array/compare.three_way.pass.cpp
+++ b/libcxx/test/std/containers/sequences/array/compare.three_way.pass.cpp
@@ -26,7 +26,6 @@ constexpr std::size_t N{1};
 static_assert(std::three_way_comparable<std::array<int, N>>);
 
 // Thanks to SFINAE, the following is not a compiler error but returns `false`
-struct NonComparable {};
 static_assert(!std::three_way_comparable<std::array<NonComparable, N>>);
 
 // Implementation detail of `test_sequence_container_array_spaceship`
diff --git a/libcxx/test/std/utilities/function.objects/refwrap/refwrap.comparissons/compare.three_way.refwrap.refwrap.pass.cpp b/libcxx/test/std/utilities/function.objects/refwrap/refwrap.comparissons/compare.three_way.refwrap.refwrap.pass.cpp
index a4e82d296861f..3d72459bc5a19 100644
--- a/libcxx/test/std/utilities/function.objects/refwrap/refwrap.comparissons/compare.three_way.refwrap.refwrap.pass.cpp
+++ b/libcxx/test/std/utilities/function.objects/refwrap/refwrap.comparissons/compare.three_way.refwrap.refwrap.pass.cpp
@@ -24,11 +24,11 @@
 #include "test_macros.h"
 // Test SFINAE.
 
-static_assert(HasSpaceshipOperator<std::reference_wrapper<StrongOrder>>);
-static_assert(HasSpaceshipOperator<std::reference_wrapper<WeakOrder>>);
-static_assert(HasSpaceshipOperator<std::reference_wrapper<PartialOrder>>);
+static_assert(HasOperatorSpaceship<std::reference_wrapper<StrongOrder>>);
+static_assert(HasOperatorSpaceship<std::reference_wrapper<WeakOrder>>);
+static_assert(HasOperatorSpaceship<std::reference_wrapper<PartialOrder>>);
 
-static_assert(!HasSpaceshipOperator<std::reference_wrapper<NonComparable>>);
+static_assert(!HasOperatorSpaceship<std::reference_wrapper<NonComparable>>);
 
 // Test comparisons.
 

>From f0bfc2b095a566f924ec854f9c106f8fa86e1174 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hristo.goshev.hristov at gmail.com>
Date: Sat, 10 May 2025 13:15:40 +0300
Subject: [PATCH 09/15] Update
 libcxx/test/std/utilities/utility/pairs/pairs.spec/comparison.pass.cpp

---
 .../std/utilities/utility/pairs/pairs.spec/comparison.pass.cpp  | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libcxx/test/std/utilities/utility/pairs/pairs.spec/comparison.pass.cpp b/libcxx/test/std/utilities/utility/pairs/pairs.spec/comparison.pass.cpp
index 650ae970730c1..226a3587a47f4 100644
--- a/libcxx/test/std/utilities/utility/pairs/pairs.spec/comparison.pass.cpp
+++ b/libcxx/test/std/utilities/utility/pairs/pairs.spec/comparison.pass.cpp
@@ -21,8 +21,8 @@
 #include <cassert>
 #include <concepts>
 
-#include "test_macros.h"
 #include "test_comparisons.h"
+#include "test_macros.h"
 
 #if TEST_STD_VER >= 26
 

>From 35c0631c81c9ca22102b6844638fbdb66520e342 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Sat, 10 May 2025 14:06:42 +0300
Subject: [PATCH 10/15] Try to fix CI

---
 ...own-linux-gnu.libcxxabi.v1.stable.exceptions.nonew.abilist | 4 ++--
 libcxx/test/libcxx/algorithms/no_specializations.verify.cpp   | 2 +-
 .../support.initlist.syn/specialization.verify.cpp            | 2 +-
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.exceptions.nonew.abilist b/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.exceptions.nonew.abilist
index 7e0fa057b42b3..679a0626d3268 100644
--- a/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.exceptions.nonew.abilist
+++ b/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.exceptions.nonew.abilist
@@ -953,6 +953,7 @@
 {'is_defined': True, 'name': '_ZNSt3__113shared_futureIvED1Ev', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__113shared_futureIvED2Ev', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__113shared_futureIvEaSERKS1_', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt3__113__hash_memoryEPKvm', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__114__num_get_base10__get_baseERNS_8ios_baseE', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__114__num_get_base5__srcE', 'size': 33, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '_ZNSt3__114__num_put_base12__format_intEPcPKcbj', 'type': 'FUNC'}
@@ -1155,6 +1156,7 @@
 {'is_defined': True, 'name': '_ZNSt3__117bad_function_callD0Ev', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__117bad_function_callD1Ev', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__117bad_function_callD2Ev', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNKSt3__117bad_function_call4whatEv', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__117iostream_categoryEv', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__117moneypunct_bynameIcLb0EE4initEPKc', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__117moneypunct_bynameIcLb1EE4initEPKc', 'type': 'FUNC'}
@@ -1964,8 +1966,6 @@
 {'is_defined': True, 'name': '_ZTVNSt3__120__codecvt_utf8_utf16IDiEE', 'size': 96, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '_ZTVNSt3__120__codecvt_utf8_utf16IDsEE', 'size': 96, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '_ZTVNSt3__120__codecvt_utf8_utf16IwEE', 'size': 96, 'type': 'OBJECT'}
-{'is_defined': True, 'name': '_ZTVNSt3__120__time_get_c_storageIcEE', 'size': 72, 'type': 'OBJECT'}
-{'is_defined': True, 'name': '_ZTVNSt3__120__time_get_c_storageIwEE', 'size': 72, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '_ZTVNSt3__13pmr15memory_resourceE', 'size': 56, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '_ZTVNSt3__13pmr25monotonic_buffer_resourceE', 'size': 56, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '_ZTVNSt3__13pmr26synchronized_pool_resourceE', 'size': 56, 'type': 'OBJECT'}
diff --git a/libcxx/test/libcxx/algorithms/no_specializations.verify.cpp b/libcxx/test/libcxx/algorithms/no_specializations.verify.cpp
index da41a6ee0ec0a..5b2475252b602 100644
--- a/libcxx/test/libcxx/algorithms/no_specializations.verify.cpp
+++ b/libcxx/test/libcxx/algorithms/no_specializations.verify.cpp
@@ -15,7 +15,7 @@
 
 #include <execution>
 
-#if !__has_warning("-Winvalid-specialization")
+#if !__has_warning("-Winvalid-specializations")
 // expected-no-diagnostics
 #else
 struct S {};
diff --git a/libcxx/test/std/language.support/support.initlist/support.initlist.syn/specialization.verify.cpp b/libcxx/test/std/language.support/support.initlist/support.initlist.syn/specialization.verify.cpp
index 54b2f6db41c7e..11807059c71b0 100644
--- a/libcxx/test/std/language.support/support.initlist/support.initlist.syn/specialization.verify.cpp
+++ b/libcxx/test/std/language.support/support.initlist/support.initlist.syn/specialization.verify.cpp
@@ -15,7 +15,7 @@
 
 #include <initializer_list>
 
-#if !__has_warning("-Winvalid-specialization")
+#if !__has_warning("-Winvalid-specializations")
 // expected-no-diagnostics
 #else
 

>From 4f009b58183426392dee1158705ea23b207ce814 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Sat, 10 May 2025 14:11:53 +0300
Subject: [PATCH 11/15] Fix `<optional>`

---
 libcxx/include/optional | 36 ++++++++++++++++++------------------
 1 file changed, 18 insertions(+), 18 deletions(-)

diff --git a/libcxx/include/optional b/libcxx/include/optional
index e52d3675a9182..059ca0156475b 100644
--- a/libcxx/include/optional
+++ b/libcxx/include/optional
@@ -986,7 +986,7 @@ optional(_Tp) -> optional<_Tp>;
 
 // [optional.relops] Relational operators
 
-#    if _LIBCPP_STD_VER < 26
+#    if _LIBCPP_STD_VER >= 26
 template < class _Tp, class _Up>
 #    else
 template <
@@ -1008,7 +1008,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool operator==(const optional<_Tp>& __x, const
   return *__x == *__y;
 }
 
-#    if _LIBCPP_STD_VER < 26
+#    if _LIBCPP_STD_VER >= 26
 template < class _Tp, class _Up>
 #    else
 template <
@@ -1030,7 +1030,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool operator!=(const optional<_Tp>& __x, const
   return *__x != *__y;
 }
 
-#    if _LIBCPP_STD_VER < 26
+#    if _LIBCPP_STD_VER >= 26
 template < class _Tp, class _Up>
 #    else
 template <
@@ -1052,7 +1052,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool operator<(const optional<_Tp>& __x, const o
   return *__x < *__y;
 }
 
-#    if _LIBCPP_STD_VER < 26
+#    if _LIBCPP_STD_VER >= 26
 template < class _Tp, class _Up>
 #    else
 template <
@@ -1074,7 +1074,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool operator>(const optional<_Tp>& __x, const o
   return *__x > *__y;
 }
 
-#    if _LIBCPP_STD_VER < 26
+#    if _LIBCPP_STD_VER >= 26
 template < class _Tp, class _Up>
 #    else
 template <
@@ -1096,7 +1096,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool operator<=(const optional<_Tp>& __x, const
   return *__x <= *__y;
 }
 
-#    if _LIBCPP_STD_VER < 26
+#    if _LIBCPP_STD_VER >= 26
 template < class _Tp, class _Up>
 #    else
 template <
@@ -1205,7 +1205,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr strong_ordering operator<=>(const optional<_Tp>&
 
 // [optional.comp.with.t] Comparison with T
 
-#    if _LIBCPP_STD_VER < 26
+#    if _LIBCPP_STD_VER >= 26
 template < class _Tp, class _Up>
 #    else
 template <
@@ -1223,7 +1223,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool operator==(const optional<_Tp>& __x, const
   return static_cast<bool>(__x) ? *__x == __v : false;
 }
 
-#    if _LIBCPP_STD_VER < 26
+#    if _LIBCPP_STD_VER >= 26
 template < class _Tp, class _Up>
 #    else
 template <
@@ -1241,7 +1241,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool operator==(const _Tp& __v, const optional<_
   return static_cast<bool>(__x) ? __v == *__x : false;
 }
 
-#    if _LIBCPP_STD_VER < 26
+#    if _LIBCPP_STD_VER >= 26
 template < class _Tp, class _Up>
 #    else
 template <
@@ -1259,7 +1259,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool operator!=(const optional<_Tp>& __x, const
   return static_cast<bool>(__x) ? *__x != __v : true;
 }
 
-#    if _LIBCPP_STD_VER < 26
+#    if _LIBCPP_STD_VER >= 26
 template < class _Tp, class _Up>
 #    else
 template <
@@ -1277,7 +1277,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool operator!=(const _Tp& __v, const optional<_
   return static_cast<bool>(__x) ? __v != *__x : true;
 }
 
-#    if _LIBCPP_STD_VER < 26
+#    if _LIBCPP_STD_VER >= 26
 template < class _Tp, class _Up>
 #    else
 template <
@@ -1295,7 +1295,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool operator<(const optional<_Tp>& __x, const _
   return static_cast<bool>(__x) ? *__x < __v : true;
 }
 
-#    if _LIBCPP_STD_VER < 26
+#    if _LIBCPP_STD_VER >= 26
 template < class _Tp, class _Up>
 #    else
 template <
@@ -1313,7 +1313,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool operator<(const _Tp& __v, const optional<_U
   return static_cast<bool>(__x) ? __v < *__x : false;
 }
 
-#    if _LIBCPP_STD_VER < 26
+#    if _LIBCPP_STD_VER >= 26
 template < class _Tp, class _Up>
 #    else
 template <
@@ -1331,7 +1331,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool operator<=(const optional<_Tp>& __x, const
   return static_cast<bool>(__x) ? *__x <= __v : true;
 }
 
-#    if _LIBCPP_STD_VER < 26
+#    if _LIBCPP_STD_VER >= 26
 template < class _Tp, class _Up>
 #    else
 template <
@@ -1349,7 +1349,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool operator<=(const _Tp& __v, const optional<_
   return static_cast<bool>(__x) ? __v <= *__x : false;
 }
 
-#    if _LIBCPP_STD_VER < 26
+#    if _LIBCPP_STD_VER >= 26
 template < class _Tp, class _Up>
 #    else
 template <
@@ -1367,7 +1367,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool operator>(const optional<_Tp>& __x, const _
   return static_cast<bool>(__x) ? *__x > __v : false;
 }
 
-#    if _LIBCPP_STD_VER < 26
+#    if _LIBCPP_STD_VER >= 26
 template < class _Tp, class _Up>
 #    else
 template <
@@ -1385,7 +1385,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool operator>(const _Tp& __v, const optional<_U
   return static_cast<bool>(__x) ? __v > *__x : true;
 }
 
-#    if _LIBCPP_STD_VER < 26
+#    if _LIBCPP_STD_VER >= 26
 template < class _Tp, class _Up>
 #    else
 template <
@@ -1403,7 +1403,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool operator>=(const optional<_Tp>& __x, const
   return static_cast<bool>(__x) ? *__x >= __v : false;
 }
 
-#    if _LIBCPP_STD_VER < 26
+#    if _LIBCPP_STD_VER >= 26
 template < class _Tp, class _Up>
 #    else
 template <

>From f81457f7dcc781c4449ee9f1bfdac20cd3a3a901 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Sat, 10 May 2025 14:45:51 +0300
Subject: [PATCH 12/15] Try to fix CI

---
 libcxx/test/support/test_container_comparisons.h | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/libcxx/test/support/test_container_comparisons.h b/libcxx/test/support/test_container_comparisons.h
index f7bf78e48a1f8..53db5ba99ce47 100644
--- a/libcxx/test/support/test_container_comparisons.h
+++ b/libcxx/test/support/test_container_comparisons.h
@@ -88,7 +88,6 @@ constexpr bool test_sequence_container_spaceship() {
                                               std::weak_ordering>();
 
   // Thanks to SFINAE, the following is not a compiler error but returns `false`
-  struct NonComparable {};
   static_assert(!std::three_way_comparable<Container<NonComparable>>);
 
   return true;
@@ -163,7 +162,6 @@ constexpr void test_sequence_container_adaptor_spaceship_with_type() {
 template <template <typename...> typename ContainerAdaptor, template <typename...> typename Container>
 constexpr bool test_sequence_container_adaptor_spaceship() {
   // Thanks to SFINAE, the following is not a compiler error but returns `false`
-  struct NonComparable {};
   static_assert(!std::three_way_comparable<ContainerAdaptor<NonComparable>>);
 
   // The container should fulfill `std::three_way_comparable`
@@ -301,7 +299,6 @@ constexpr void test_ordered_map_container_spaceship_with_type(Compare comp) {
 template <template <typename...> typename Container>
 constexpr bool test_ordered_map_container_spaceship() {
   // Thanks to SFINAE, the following is not a compiler error but returns `false`
-  struct NonComparable {};
   static_assert(!std::three_way_comparable<Container<int, NonComparable>>);
 
   // The container should fulfill `std::three_way_comparable`
@@ -444,7 +441,6 @@ constexpr void test_ordered_set_spaceship_with_type(Compare comp) {
 template <template <typename...> typename Container>
 constexpr bool test_ordered_set_container_spaceship() {
   // Thanks to SFINAE, the following is not a compiler error but returns `false`
-  struct NonComparable {};
   static_assert(!std::three_way_comparable<Container<NonComparable>>);
 
   // The container should fulfill `std::three_way_comparable`

>From 7181c8cf8aa699be6efe457ffec688860182694f Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Sat, 10 May 2025 14:50:33 +0300
Subject: [PATCH 13/15] More fixes

---
 libcxx/test/support/test_comparisons.h | 6 +-----
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/libcxx/test/support/test_comparisons.h b/libcxx/test/support/test_comparisons.h
index 9add3c4e65f95..e37ab44828c70 100644
--- a/libcxx/test/support/test_comparisons.h
+++ b/libcxx/test/support/test_comparisons.h
@@ -268,10 +268,6 @@ struct PartialOrder {
   }
 };
 
-#endif // TEST_STD_VER >= 20
-
-#if TEST_STD_VER >= 23
-
 template <typename T1, typename T2 = T1>
 concept HasOperatorEqual = requires(T1 t1, T2 t2) { t1 == t2; };
 
@@ -336,6 +332,6 @@ static_assert(HasOperatorLessThanEqual<ThreeWayComparable>);
 static_assert(HasOperatorNotEqual<ThreeWayComparable>);
 static_assert(HasOperatorSpaceship<ThreeWayComparable>);
 
-#endif // TEST_STD_VER >= 26
+#endif // TEST_STD_VER >= 20
 
 #endif // TEST_COMPARISONS_H

>From 4e1e31251560cda75bda97dbc413b00959e3c073 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Wed, 4 Jun 2025 13:36:36 +0300
Subject: [PATCH 14/15] Removed `optional` changes

---
 libcxx/include/optional                       | 226 ++----------------
 .../optional.comp_with_t/equal.pass.cpp       |  21 --
 .../optional.comp_with_t/greater.pass.cpp     |  20 --
 .../greater_equal.pass.cpp                    |  20 --
 .../optional.comp_with_t/less_equal.pass.cpp  |  20 --
 .../optional.comp_with_t/less_than.pass.cpp   |  20 --
 .../optional.comp_with_t/not_equal.pass.cpp   |  21 --
 .../optional/optional.relops/equal.pass.cpp   |  14 --
 .../optional.relops/greater_equal.pass.cpp    |  13 -
 .../optional.relops/greater_than.pass.cpp     |  13 -
 .../optional.relops/less_equal.pass.cpp       |  13 -
 .../optional.relops/less_than.pass.cpp        |  13 -
 .../optional.relops/not_equal.pass.cpp        |  14 --
 libcxx/test/support/test_comparisons.h        |  41 ----
 14 files changed, 21 insertions(+), 448 deletions(-)

diff --git a/libcxx/include/optional b/libcxx/include/optional
index 68053bdfb5df3..fa32d75ef86dd 100644
--- a/libcxx/include/optional
+++ b/libcxx/include/optional
@@ -205,7 +205,6 @@ namespace std {
 #  include <__type_traits/is_assignable.h>
 #  include <__type_traits/is_constructible.h>
 #  include <__type_traits/is_convertible.h>
-#  include <__type_traits/is_core_convertible.h>
 #  include <__type_traits/is_destructible.h>
 #  include <__type_traits/is_nothrow_assignable.h>
 #  include <__type_traits/is_nothrow_constructible.h>
@@ -983,23 +982,12 @@ public:
 template <class _Tp>
 optional(_Tp) -> optional<_Tp>;
 
-// [optional.relops] Relational operators
-
-#    if _LIBCPP_STD_VER >= 26
-template < class _Tp, class _Up>
-#    else
+// Comparisons between optionals
 template <
     class _Tp,
     class _Up,
     enable_if_t<is_convertible_v<decltype(std::declval<const _Tp&>() == std::declval<const _Up&>()), bool>, int> = 0>
-#    endif
-_LIBCPP_HIDE_FROM_ABI constexpr bool operator==(const optional<_Tp>& __x, const optional<_Up>& __y)
-#    if _LIBCPP_STD_VER >= 26
-  requires requires {
-    { *__x == *__y } -> __core_convertible_to<bool>;
-  }
-#    endif
-{
+_LIBCPP_HIDE_FROM_ABI constexpr bool operator==(const optional<_Tp>& __x, const optional<_Up>& __y) {
   if (static_cast<bool>(__x) != static_cast<bool>(__y))
     return false;
   if (!static_cast<bool>(__x))
@@ -1007,21 +995,11 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool operator==(const optional<_Tp>& __x, const
   return *__x == *__y;
 }
 
-#    if _LIBCPP_STD_VER >= 26
-template < class _Tp, class _Up>
-#    else
 template <
     class _Tp,
     class _Up,
     enable_if_t<is_convertible_v<decltype(std::declval<const _Tp&>() != std::declval<const _Up&>()), bool>, int> = 0>
-#    endif
-_LIBCPP_HIDE_FROM_ABI constexpr bool operator!=(const optional<_Tp>& __x, const optional<_Up>& __y)
-#    if _LIBCPP_STD_VER >= 26
-  requires requires {
-    { *__x != *__y } -> __core_convertible_to<bool>;
-  }
-#    endif
-{
+_LIBCPP_HIDE_FROM_ABI constexpr bool operator!=(const optional<_Tp>& __x, const optional<_Up>& __y) {
   if (static_cast<bool>(__x) != static_cast<bool>(__y))
     return true;
   if (!static_cast<bool>(__x))
@@ -1029,21 +1007,11 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool operator!=(const optional<_Tp>& __x, const
   return *__x != *__y;
 }
 
-#    if _LIBCPP_STD_VER >= 26
-template < class _Tp, class _Up>
-#    else
 template <
     class _Tp,
     class _Up,
     enable_if_t<is_convertible_v<decltype(std::declval<const _Tp&>() < std::declval<const _Up&>()), bool>, int> = 0>
-#    endif
-_LIBCPP_HIDE_FROM_ABI constexpr bool operator<(const optional<_Tp>& __x, const optional<_Up>& __y)
-#    if _LIBCPP_STD_VER >= 26
-  requires requires {
-    { *__x < *__y } -> __core_convertible_to<bool>;
-  }
-#    endif
-{
+_LIBCPP_HIDE_FROM_ABI constexpr bool operator<(const optional<_Tp>& __x, const optional<_Up>& __y) {
   if (!static_cast<bool>(__y))
     return false;
   if (!static_cast<bool>(__x))
@@ -1051,21 +1019,11 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool operator<(const optional<_Tp>& __x, const o
   return *__x < *__y;
 }
 
-#    if _LIBCPP_STD_VER >= 26
-template < class _Tp, class _Up>
-#    else
 template <
     class _Tp,
     class _Up,
     enable_if_t<is_convertible_v<decltype(std::declval<const _Tp&>() > std::declval<const _Up&>()), bool>, int> = 0>
-#    endif
-_LIBCPP_HIDE_FROM_ABI constexpr bool operator>(const optional<_Tp>& __x, const optional<_Up>& __y)
-#    if _LIBCPP_STD_VER >= 26
-  requires requires {
-    { *__x > *__y } -> __core_convertible_to<bool>;
-  }
-#    endif
-{
+_LIBCPP_HIDE_FROM_ABI constexpr bool operator>(const optional<_Tp>& __x, const optional<_Up>& __y) {
   if (!static_cast<bool>(__x))
     return false;
   if (!static_cast<bool>(__y))
@@ -1073,21 +1031,11 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool operator>(const optional<_Tp>& __x, const o
   return *__x > *__y;
 }
 
-#    if _LIBCPP_STD_VER >= 26
-template < class _Tp, class _Up>
-#    else
 template <
     class _Tp,
     class _Up,
     enable_if_t<is_convertible_v<decltype(std::declval<const _Tp&>() <= std::declval<const _Up&>()), bool>, int> = 0>
-#    endif
-_LIBCPP_HIDE_FROM_ABI constexpr bool operator<=(const optional<_Tp>& __x, const optional<_Up>& __y)
-#    if _LIBCPP_STD_VER >= 26
-  requires requires {
-    { *__x <= *__y } -> __core_convertible_to<bool>;
-  }
-#    endif
-{
+_LIBCPP_HIDE_FROM_ABI constexpr bool operator<=(const optional<_Tp>& __x, const optional<_Up>& __y) {
   if (!static_cast<bool>(__x))
     return true;
   if (!static_cast<bool>(__y))
@@ -1095,21 +1043,11 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool operator<=(const optional<_Tp>& __x, const
   return *__x <= *__y;
 }
 
-#    if _LIBCPP_STD_VER >= 26
-template < class _Tp, class _Up>
-#    else
 template <
     class _Tp,
     class _Up,
     enable_if_t<is_convertible_v<decltype(std::declval<const _Tp&>() >= std::declval<const _Up&>()), bool>, int> = 0>
-#    endif
-_LIBCPP_HIDE_FROM_ABI constexpr bool operator>=(const optional<_Tp>& __x, const optional<_Up>& __y)
-#    if _LIBCPP_STD_VER >= 26
-  requires requires {
-    { *__x >= *__y } -> __core_convertible_to<bool>;
-  }
-#    endif
-{
+_LIBCPP_HIDE_FROM_ABI constexpr bool operator>=(const optional<_Tp>& __x, const optional<_Up>& __y) {
   if (!static_cast<bool>(__y))
     return true;
   if (!static_cast<bool>(__x))
@@ -1129,8 +1067,7 @@ operator<=>(const optional<_Tp>& __x, const optional<_Up>& __y) {
 
 #    endif // _LIBCPP_STD_VER >= 20
 
-// [optional.nullops] Comparison with nullopt
-
+// Comparisons with nullopt
 template <class _Tp>
 _LIBCPP_HIDE_FROM_ABI constexpr bool operator==(const optional<_Tp>& __x, nullopt_t) noexcept {
   return !static_cast<bool>(__x);
@@ -1202,221 +1139,100 @@ _LIBCPP_HIDE_FROM_ABI constexpr strong_ordering operator<=>(const optional<_Tp>&
 
 #    endif // _LIBCPP_STD_VER <= 17
 
-// [optional.comp.with.t] Comparison with T
-
-#    if _LIBCPP_STD_VER >= 26
-template < class _Tp, class _Up>
-#    else
+// Comparisons with T
 template <
     class _Tp,
     class _Up,
     enable_if_t<is_convertible_v<decltype(std::declval<const _Tp&>() == std::declval<const _Up&>()), bool>, int> = 0>
-#    endif
-_LIBCPP_HIDE_FROM_ABI constexpr bool operator==(const optional<_Tp>& __x, const _Up& __v)
-#    if _LIBCPP_STD_VER >= 26
-  requires(!__is_std_optional<_Up>::value) && requires {
-    { *__x == __v } -> __core_convertible_to<bool>;
-  }
-#    endif
-{
+_LIBCPP_HIDE_FROM_ABI constexpr bool operator==(const optional<_Tp>& __x, const _Up& __v) {
   return static_cast<bool>(__x) ? *__x == __v : false;
 }
 
-#    if _LIBCPP_STD_VER >= 26
-template < class _Tp, class _Up>
-#    else
 template <
     class _Tp,
     class _Up,
     enable_if_t<is_convertible_v<decltype(std::declval<const _Tp&>() == std::declval<const _Up&>()), bool>, int> = 0>
-#    endif
-_LIBCPP_HIDE_FROM_ABI constexpr bool operator==(const _Tp& __v, const optional<_Up>& __x)
-#    if _LIBCPP_STD_VER >= 26
-  requires(!__is_std_optional<_Tp>::value) && requires {
-    { __v == *__x } -> __core_convertible_to<bool>;
-  }
-#    endif
-{
+_LIBCPP_HIDE_FROM_ABI constexpr bool operator==(const _Tp& __v, const optional<_Up>& __x) {
   return static_cast<bool>(__x) ? __v == *__x : false;
 }
 
-#    if _LIBCPP_STD_VER >= 26
-template < class _Tp, class _Up>
-#    else
 template <
     class _Tp,
     class _Up,
     enable_if_t<is_convertible_v<decltype(std::declval<const _Tp&>() != std::declval<const _Up&>()), bool>, int> = 0>
-#    endif
-_LIBCPP_HIDE_FROM_ABI constexpr bool operator!=(const optional<_Tp>& __x, const _Up& __v)
-#    if _LIBCPP_STD_VER >= 26
-  requires(!__is_std_optional<_Up>::value) && requires {
-    { *__x != __v } -> __core_convertible_to<bool>;
-  }
-#    endif
-{
+_LIBCPP_HIDE_FROM_ABI constexpr bool operator!=(const optional<_Tp>& __x, const _Up& __v) {
   return static_cast<bool>(__x) ? *__x != __v : true;
 }
 
-#    if _LIBCPP_STD_VER >= 26
-template < class _Tp, class _Up>
-#    else
 template <
     class _Tp,
     class _Up,
     enable_if_t<is_convertible_v<decltype(std::declval<const _Tp&>() != std::declval<const _Up&>()), bool>, int> = 0>
-#    endif
-_LIBCPP_HIDE_FROM_ABI constexpr bool operator!=(const _Tp& __v, const optional<_Up>& __x)
-#    if _LIBCPP_STD_VER >= 26
-  requires(!__is_std_optional<_Tp>::value) && requires {
-    { __v != *__x } -> __core_convertible_to<bool>;
-  }
-#    endif
-{
+_LIBCPP_HIDE_FROM_ABI constexpr bool operator!=(const _Tp& __v, const optional<_Up>& __x) {
   return static_cast<bool>(__x) ? __v != *__x : true;
 }
 
-#    if _LIBCPP_STD_VER >= 26
-template < class _Tp, class _Up>
-#    else
 template <
     class _Tp,
     class _Up,
     enable_if_t<is_convertible_v<decltype(std::declval<const _Tp&>() < std::declval<const _Up&>()), bool>, int> = 0>
-#    endif
-_LIBCPP_HIDE_FROM_ABI constexpr bool operator<(const optional<_Tp>& __x, const _Up& __v)
-#    if _LIBCPP_STD_VER >= 26
-  requires(!__is_std_optional<_Up>::value) && requires {
-    { *__x < __v } -> __core_convertible_to<bool>;
-  }
-#    endif
-{
+_LIBCPP_HIDE_FROM_ABI constexpr bool operator<(const optional<_Tp>& __x, const _Up& __v) {
   return static_cast<bool>(__x) ? *__x < __v : true;
 }
 
-#    if _LIBCPP_STD_VER >= 26
-template < class _Tp, class _Up>
-#    else
 template <
     class _Tp,
     class _Up,
     enable_if_t<is_convertible_v<decltype(std::declval<const _Tp&>() < std::declval<const _Up&>()), bool>, int> = 0>
-#    endif
-_LIBCPP_HIDE_FROM_ABI constexpr bool operator<(const _Tp& __v, const optional<_Up>& __x)
-#    if _LIBCPP_STD_VER >= 26
-  requires(!__is_std_optional<_Tp>::value) && requires {
-    { __v < *__x } -> __core_convertible_to<bool>;
-  }
-#    endif
-{
+_LIBCPP_HIDE_FROM_ABI constexpr bool operator<(const _Tp& __v, const optional<_Up>& __x) {
   return static_cast<bool>(__x) ? __v < *__x : false;
 }
 
-#    if _LIBCPP_STD_VER >= 26
-template < class _Tp, class _Up>
-#    else
 template <
     class _Tp,
     class _Up,
     enable_if_t<is_convertible_v<decltype(std::declval<const _Tp&>() <= std::declval<const _Up&>()), bool>, int> = 0>
-#    endif
-_LIBCPP_HIDE_FROM_ABI constexpr bool operator<=(const optional<_Tp>& __x, const _Up& __v)
-#    if _LIBCPP_STD_VER >= 26
-  requires(!__is_std_optional<_Up>::value) && requires {
-    { *__x <= __v } -> __core_convertible_to<bool>;
-  }
-#    endif
-{
+_LIBCPP_HIDE_FROM_ABI constexpr bool operator<=(const optional<_Tp>& __x, const _Up& __v) {
   return static_cast<bool>(__x) ? *__x <= __v : true;
 }
 
-#    if _LIBCPP_STD_VER >= 26
-template < class _Tp, class _Up>
-#    else
 template <
     class _Tp,
     class _Up,
     enable_if_t<is_convertible_v<decltype(std::declval<const _Tp&>() <= std::declval<const _Up&>()), bool>, int> = 0>
-#    endif
-_LIBCPP_HIDE_FROM_ABI constexpr bool operator<=(const _Tp& __v, const optional<_Up>& __x)
-#    if _LIBCPP_STD_VER >= 26
-  requires(!__is_std_optional<_Tp>::value) && requires {
-    { __v <= *__x } -> __core_convertible_to<bool>;
-  }
-#    endif
-{
+_LIBCPP_HIDE_FROM_ABI constexpr bool operator<=(const _Tp& __v, const optional<_Up>& __x) {
   return static_cast<bool>(__x) ? __v <= *__x : false;
 }
 
-#    if _LIBCPP_STD_VER >= 26
-template < class _Tp, class _Up>
-#    else
 template <
     class _Tp,
     class _Up,
     enable_if_t<is_convertible_v<decltype(std::declval<const _Tp&>() > std::declval<const _Up&>()), bool>, int> = 0>
-#    endif
-_LIBCPP_HIDE_FROM_ABI constexpr bool operator>(const optional<_Tp>& __x, const _Up& __v)
-#    if _LIBCPP_STD_VER >= 26
-  requires(!__is_std_optional<_Up>::value) && requires {
-    { *__x > __v } -> __core_convertible_to<bool>;
-  }
-#    endif
-{
+_LIBCPP_HIDE_FROM_ABI constexpr bool operator>(const optional<_Tp>& __x, const _Up& __v) {
   return static_cast<bool>(__x) ? *__x > __v : false;
 }
 
-#    if _LIBCPP_STD_VER >= 26
-template < class _Tp, class _Up>
-#    else
 template <
     class _Tp,
     class _Up,
     enable_if_t<is_convertible_v<decltype(std::declval<const _Tp&>() > std::declval<const _Up&>()), bool>, int> = 0>
-#    endif
-_LIBCPP_HIDE_FROM_ABI constexpr bool operator>(const _Tp& __v, const optional<_Up>& __x)
-#    if _LIBCPP_STD_VER >= 26
-  requires(!__is_std_optional<_Tp>::value) && requires {
-    { __v > *__x } -> __core_convertible_to<bool>;
-  }
-#    endif
-{
+_LIBCPP_HIDE_FROM_ABI constexpr bool operator>(const _Tp& __v, const optional<_Up>& __x) {
   return static_cast<bool>(__x) ? __v > *__x : true;
 }
 
-#    if _LIBCPP_STD_VER >= 26
-template < class _Tp, class _Up>
-#    else
 template <
     class _Tp,
     class _Up,
     enable_if_t<is_convertible_v<decltype(std::declval<const _Tp&>() >= std::declval<const _Up&>()), bool>, int> = 0>
-#    endif
-_LIBCPP_HIDE_FROM_ABI constexpr bool operator>=(const optional<_Tp>& __x, const _Up& __v)
-#    if _LIBCPP_STD_VER >= 26
-  requires(!__is_std_optional<_Up>::value) && requires {
-    { *__x >= __v } -> __core_convertible_to<bool>;
-  }
-#    endif
-{
+_LIBCPP_HIDE_FROM_ABI constexpr bool operator>=(const optional<_Tp>& __x, const _Up& __v) {
   return static_cast<bool>(__x) ? *__x >= __v : false;
 }
 
-#    if _LIBCPP_STD_VER >= 26
-template < class _Tp, class _Up>
-#    else
 template <
     class _Tp,
     class _Up,
     enable_if_t<is_convertible_v<decltype(std::declval<const _Tp&>() >= std::declval<const _Up&>()), bool>, int> = 0>
-#    endif
-_LIBCPP_HIDE_FROM_ABI constexpr bool operator>=(const _Tp& __v, const optional<_Up>& __x)
-#    if _LIBCPP_STD_VER >= 26
-  requires(!__is_std_optional<_Tp>::value) && requires {
-    { __v >= *__x } -> __core_convertible_to<bool>;
-  }
-#    endif
-{
+_LIBCPP_HIDE_FROM_ABI constexpr bool operator>=(const _Tp& __v, const optional<_Up>& __x) {
   return static_cast<bool>(__x) ? __v >= *__x : true;
 }
 
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 54965b270dcce..0636da7bcdf23 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
@@ -14,29 +14,8 @@
 
 #include <optional>
 
-#include "test_comparisons.h"
 #include "test_macros.h"
 
-#if TEST_STD_VER >= 26
-
-// 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(!HasOperatorEqual<NonComparable, std::optional<NonComparable>>);
-static_assert(!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(!HasOperatorEqual<std::optional<NonComparable>, NonComparable>);
-static_assert(!HasOperatorEqual<std::optional<EqualityComparable>, NonComparable>);
-
-#endif
-
 using std::optional;
 
 struct X {
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 b63b85b000930..2010157a8d011 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
@@ -14,28 +14,8 @@
 
 #include <optional>
 
-#include "test_comparisons.h"
 #include "test_macros.h"
 
-#if TEST_STD_VER >= 26
-
-// Test SFINAE.
-static_assert(HasOperatorGreaterThan<std::optional<ThreeWayComparable>, int>);
-static_assert(HasOperatorGreaterThan<std::optional<ThreeWayComparable>, ThreeWayComparable>);
-
-static_assert(!HasOperatorGreaterThan<std::optional<NonComparable>, NonComparable>);
-static_assert(!HasOperatorGreaterThan<std::optional<ThreeWayComparable>, NonComparable>);
-static_assert(!HasOperatorGreaterThan<std::optional<NonComparable>, ThreeWayComparable>);
-
-static_assert(HasOperatorGreaterThan<int, std::optional<ThreeWayComparable>>);
-static_assert(HasOperatorGreaterThan<ThreeWayComparable, std::optional<ThreeWayComparable>>);
-
-static_assert(!HasOperatorGreaterThan<NonComparable, std::optional<NonComparable>>);
-static_assert(!HasOperatorGreaterThan<NonComparable, std::optional<ThreeWayComparable>>);
-static_assert(!HasOperatorGreaterThan<ThreeWayComparable, std::optional<NonComparable>>);
-
-#endif
-
 using std::optional;
 
 struct X {
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 bb1a8c551d3d5..2e1e9b9316111 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
@@ -14,28 +14,8 @@
 
 #include <optional>
 
-#include "test_comparisons.h"
 #include "test_macros.h"
 
-#if TEST_STD_VER >= 26
-
-// Test SFINAE.
-static_assert(HasOperatorGreaterThanEqual<std::optional<ThreeWayComparable>, int>);
-static_assert(HasOperatorGreaterThanEqual<std::optional<ThreeWayComparable>, ThreeWayComparable>);
-
-static_assert(!HasOperatorGreaterThanEqual<std::optional<NonComparable>, NonComparable>);
-static_assert(!HasOperatorGreaterThanEqual<std::optional<ThreeWayComparable>, NonComparable>);
-static_assert(!HasOperatorGreaterThanEqual<std::optional<NonComparable>, ThreeWayComparable>);
-
-static_assert(HasOperatorGreaterThanEqual<int, std::optional<ThreeWayComparable>>);
-static_assert(HasOperatorGreaterThanEqual<ThreeWayComparable, std::optional<ThreeWayComparable>>);
-
-static_assert(!HasOperatorGreaterThanEqual<NonComparable, std::optional<NonComparable>>);
-static_assert(!HasOperatorGreaterThanEqual<NonComparable, std::optional<ThreeWayComparable>>);
-static_assert(!HasOperatorGreaterThanEqual<ThreeWayComparable, std::optional<NonComparable>>);
-
-#endif
-
 using std::optional;
 
 struct X {
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 8b08ec3deea5a..7026c24de5dbf 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
@@ -14,28 +14,8 @@
 
 #include <optional>
 
-#include "test_comparisons.h"
 #include "test_macros.h"
 
-#if TEST_STD_VER >= 26
-
-// Test SFINAE.
-static_assert(HasOperatorLessThanEqual<std::optional<ThreeWayComparable>, int>);
-static_assert(HasOperatorLessThanEqual<std::optional<ThreeWayComparable>, ThreeWayComparable>);
-
-static_assert(!HasOperatorLessThanEqual<std::optional<NonComparable>, NonComparable>);
-static_assert(!HasOperatorLessThanEqual<std::optional<ThreeWayComparable>, NonComparable>);
-static_assert(!HasOperatorLessThanEqual<std::optional<NonComparable>, ThreeWayComparable>);
-
-static_assert(HasOperatorLessThanEqual<int, std::optional<ThreeWayComparable>>);
-static_assert(HasOperatorLessThanEqual<ThreeWayComparable, std::optional<ThreeWayComparable>>);
-
-static_assert(!HasOperatorLessThanEqual<NonComparable, std::optional<NonComparable>>);
-static_assert(!HasOperatorLessThanEqual<NonComparable, std::optional<ThreeWayComparable>>);
-static_assert(!HasOperatorLessThanEqual<ThreeWayComparable, std::optional<NonComparable>>);
-
-#endif
-
 using std::optional;
 
 struct X {
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 3ef23a3224520..b3d98684ba20b 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
@@ -14,28 +14,8 @@
 
 #include <optional>
 
-#include "test_comparisons.h"
 #include "test_macros.h"
 
-#if TEST_STD_VER >= 26
-
-// Test SFINAE.
-static_assert(HasOperatorLessThan<std::optional<ThreeWayComparable>, int>);
-static_assert(HasOperatorLessThan<std::optional<ThreeWayComparable>, ThreeWayComparable>);
-
-static_assert(!HasOperatorLessThan<std::optional<NonComparable>, NonComparable>);
-static_assert(!HasOperatorLessThan<std::optional<ThreeWayComparable>, NonComparable>);
-static_assert(!HasOperatorLessThan<std::optional<NonComparable>, ThreeWayComparable>);
-
-static_assert(HasOperatorLessThan<int, std::optional<ThreeWayComparable>>);
-static_assert(HasOperatorLessThan<ThreeWayComparable, std::optional<ThreeWayComparable>>);
-
-static_assert(!HasOperatorLessThan<NonComparable, std::optional<NonComparable>>);
-static_assert(!HasOperatorLessThan<NonComparable, std::optional<ThreeWayComparable>>);
-static_assert(!HasOperatorLessThan<ThreeWayComparable, std::optional<NonComparable>>);
-
-#endif
-
 using std::optional;
 
 struct X {
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 97fb8ee447393..36bc526e763fe 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
@@ -14,29 +14,8 @@
 
 #include <optional>
 
-#include "test_comparisons.h"
 #include "test_macros.h"
 
-#if TEST_STD_VER >= 26
-
-// 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(!HasOperatorNotEqual<NonComparable, std::optional<NonComparable>>);
-static_assert(!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(!HasOperatorNotEqual<std::optional<NonComparable>, NonComparable>);
-static_assert(!HasOperatorNotEqual<std::optional<EqualityComparable>, NonComparable>);
-
-#endif
-
 using std::optional;
 
 struct X {
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..96bda6a5afa26 100644
--- a/libcxx/test/std/utilities/optional/optional.relops/equal.pass.cpp
+++ b/libcxx/test/std/utilities/optional/optional.relops/equal.pass.cpp
@@ -15,22 +15,8 @@
 #include <type_traits>
 #include <cassert>
 
-#include "test_comparisons.h"
 #include "test_macros.h"
 
-#if TEST_STD_VER >= 26
-
-// 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(!HasOperatorEqual<std::optional<NonComparable>>);
-static_assert(!HasOperatorEqual<std::optional<EqualityComparable>, std::optional<NonComparable>>);
-
-#endif
-
 using std::optional;
 
 struct X {
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..399823c868b5e 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
@@ -13,21 +13,8 @@
 
 #include <optional>
 
-#include "test_comparisons.h"
 #include "test_macros.h"
 
-#if TEST_STD_VER >= 26
-
-// 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>>);
-
-#endif
-
 using std::optional;
 
 struct X {
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..6b877c3011cb0 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
@@ -13,21 +13,8 @@
 
 #include <optional>
 
-#include "test_comparisons.h"
 #include "test_macros.h"
 
-#if TEST_STD_VER >= 26
-
-// 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>>);
-
-#endif
-
 using std::optional;
 
 struct X {
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..aa605cd3a1e44 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
@@ -13,21 +13,8 @@
 
 #include <optional>
 
-#include "test_comparisons.h"
 #include "test_macros.h"
 
-#if TEST_STD_VER >= 26
-
-// 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>>);
-
-#endif
-
 using std::optional;
 
 struct X {
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..53474ebc5f0e9 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
@@ -13,21 +13,8 @@
 
 #include <optional>
 
-#include "test_comparisons.h"
 #include "test_macros.h"
 
-#if TEST_STD_VER >= 26
-
-// 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>>);
-
-#endif
-
 using std::optional;
 
 struct X {
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..290459d9ed090 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
@@ -15,22 +15,8 @@
 #include <type_traits>
 #include <cassert>
 
-#include "test_comparisons.h"
 #include "test_macros.h"
 
-#if TEST_STD_VER >= 26
-
-// 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(!HasOperatorNotEqual<std::optional<NonComparable>>);
-static_assert(!HasOperatorNotEqual<std::optional<EqualityComparable>, std::optional<NonComparable>>);
-
-#endif
-
 using std::optional;
 
 struct X {
diff --git a/libcxx/test/support/test_comparisons.h b/libcxx/test/support/test_comparisons.h
index e37ab44828c70..d9729e0451b49 100644
--- a/libcxx/test/support/test_comparisons.h
+++ b/libcxx/test/support/test_comparisons.h
@@ -271,31 +271,12 @@ struct PartialOrder {
 template <typename T1, typename T2 = T1>
 concept HasOperatorEqual = requires(T1 t1, T2 t2) { t1 == t2; };
 
-template <typename T1, typename T2 = T1>
-concept HasOperatorGreaterThan = requires(T1 t1, T2 t2) { t1 > t2; };
-
-template <typename T1, typename T2 = T1>
-concept HasOperatorGreaterThanEqual = requires(T1 t1, T2 t2) { t1 >= t2; };
-template <typename T1, typename T2 = T1>
-concept HasOperatorLessThan = requires(T1 t1, T2 t2) { t1 < t2; };
-
-template <typename T1, typename T2 = T1>
-concept HasOperatorLessThanEqual = requires(T1 t1, T2 t2) { t1 <= t2; };
-
-template <typename T1, typename T2 = T1>
-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 {
@@ -309,28 +290,6 @@ class EqualityComparable {
 };
 static_assert(std::equality_comparable<EqualityComparable>);
 static_assert(HasOperatorEqual<EqualityComparable>);
-static_assert(HasOperatorNotEqual<EqualityComparable>);
-
-class ThreeWayComparable {
-public:
-  constexpr ThreeWayComparable(int value) : value_{value} {};
-
-  friend constexpr bool operator==(const ThreeWayComparable&, const ThreeWayComparable&) noexcept = default;
-  friend constexpr std::strong_ordering
-  operator<=>(const ThreeWayComparable&, const ThreeWayComparable&) noexcept = default;
-
-private:
-  int value_;
-};
-static_assert(std::equality_comparable<ThreeWayComparable>);
-static_assert(std::three_way_comparable<ThreeWayComparable>);
-static_assert(HasOperatorEqual<ThreeWayComparable>);
-static_assert(HasOperatorGreaterThan<ThreeWayComparable>);
-static_assert(HasOperatorGreaterThanEqual<ThreeWayComparable>);
-static_assert(HasOperatorLessThan<ThreeWayComparable>);
-static_assert(HasOperatorLessThanEqual<ThreeWayComparable>);
-static_assert(HasOperatorNotEqual<ThreeWayComparable>);
-static_assert(HasOperatorSpaceship<ThreeWayComparable>);
 
 #endif // TEST_STD_VER >= 20
 

>From e17ef6413068ca60e004ab60cdfa01d98e6f8895 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hristo.goshev.hristov at gmail.com>
Date: Wed, 4 Jun 2025 13:45:49 +0300
Subject: [PATCH 15/15] Update libcxx/docs/Status/Cxx2cPapers.csv

---
 libcxx/docs/Status/Cxx2cPapers.csv | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libcxx/docs/Status/Cxx2cPapers.csv b/libcxx/docs/Status/Cxx2cPapers.csv
index 99fc0b38077ab..fba3ff53e381e 100644
--- a/libcxx/docs/Status/Cxx2cPapers.csv
+++ b/libcxx/docs/Status/Cxx2cPapers.csv
@@ -59,7 +59,7 @@
 "`P2248R8 <https://wg21.link/P2248R8>`__","Enabling list-initialization for algorithms","2024-03 (Tokyo)","","",""
 "`P2810R4 <https://wg21.link/P2810R4>`__","``is_debugger_present`` ``is_replaceable``","2024-03 (Tokyo)","","",""
 "`P1068R11 <https://wg21.link/P1068R11>`__","Vector API for random number generation","2024-03 (Tokyo)","","",""
-"`P2944R3 <https://wg21.link/P2944R3>`__","Comparisons for ``reference_wrapper``","2024-03 (Tokyo)","|Partial|","","Not implemented ``tuple`` and ``variant``"
+"`P2944R3 <https://wg21.link/P2944R3>`__","Comparisons for ``reference_wrapper``","2024-03 (Tokyo)","|Partial|","","Not implemented ``optional``, ``tuple`` and ``variant``"
 "`P2642R6 <https://wg21.link/P2642R6>`__","Padded ``mdspan`` layouts","2024-03 (Tokyo)","","",""
 "`P3029R1 <https://wg21.link/P3029R1>`__","Better ``mdspan``'s CTAD","2024-03 (Tokyo)","|Complete|","19",""
 "","","","","",""



More information about the libcxx-commits mailing list