[libcxx-commits] [libcxx] e63ddcc - [libcxx] adds concepts std::equality_comparable[_with]

Christopher Di Bella via libcxx-commits libcxx-commits at lists.llvm.org
Thu Mar 4 18:24:48 PST 2021


Author: Christopher Di Bella
Date: 2021-03-04T18:24:04-08:00
New Revision: e63ddcccf8dbe5cdd348b791f3beb7afe3a1a71c

URL: https://github.com/llvm/llvm-project/commit/e63ddcccf8dbe5cdd348b791f3beb7afe3a1a71c
DIFF: https://github.com/llvm/llvm-project/commit/e63ddcccf8dbe5cdd348b791f3beb7afe3a1a71c.diff

LOG: [libcxx] adds concepts std::equality_comparable[_with]

Implements parts of:
    - P0898R3 Standard Library Concepts
    - P1754 Rename concepts to standard_case for C++20, while we still can

Depends on D96660

Reviewed By: ldionne, #libc, Quuxplusone

Differential Revision: https://reviews.llvm.org/D97176

Added: 
    libcxx/test/std/concepts/comparison/concepts.equalitycomparable/equality_comparable.compile.pass.cpp
    libcxx/test/std/concepts/comparison/concepts.equalitycomparable/equality_comparable_with.compile.pass.cpp
    libcxx/test/std/concepts/comparison/types.h

Modified: 
    libcxx/include/concepts

Removed: 
    


################################################################################
diff  --git a/libcxx/include/concepts b/libcxx/include/concepts
index 505ade904223..88a18e96bf85 100644
--- a/libcxx/include/concepts
+++ b/libcxx/include/concepts
@@ -243,6 +243,38 @@ template<class _Tp>
 concept move_constructible =
   constructible_from<_Tp, _Tp> && convertible_to<_Tp, _Tp>;
 
+// [concept.booleantestable]
+template<class _Tp>
+concept __boolean_testable_impl = convertible_to<_Tp, bool>;
+
+template<class _Tp>
+concept __boolean_testable = __boolean_testable_impl<_Tp> && requires(_Tp&& __t) {
+  { !std::forward<_Tp>(__t) } -> __boolean_testable_impl;
+};
+
+// [concept.equalitycomparable]
+template<class _Tp, class _Up>
+concept __weakly_equality_comparable_with =
+  requires(const remove_reference_t<_Tp>& __t, const remove_reference_t<_Up>& __u) {
+    { __t == __u } -> __boolean_testable;
+    { __t != __u } -> __boolean_testable;
+    { __u == __t } -> __boolean_testable;
+    { __u != __t } -> __boolean_testable;
+  };
+
+template<class _Tp>
+concept equality_comparable = __weakly_equality_comparable_with<_Tp, _Tp>;
+
+template<class _Tp, class _Up>
+concept equality_comparable_with =
+  equality_comparable<_Tp> && equality_comparable<_Up> &&
+  common_reference_with<const remove_reference_t<_Tp>&, const remove_reference_t<_Up>&> &&
+  equality_comparable<
+    common_reference_t<
+      const remove_reference_t<_Tp>&,
+      const remove_reference_t<_Up>&>> &&
+  __weakly_equality_comparable_with<_Tp, _Up>;
+
 // [concept.copyconstructible]
 template<class _Tp>
 concept copy_constructible =

diff  --git a/libcxx/test/std/concepts/comparison/concepts.equalitycomparable/equality_comparable.compile.pass.cpp b/libcxx/test/std/concepts/comparison/concepts.equalitycomparable/equality_comparable.compile.pass.cpp
new file mode 100644
index 000000000000..93f79a80e542
--- /dev/null
+++ b/libcxx/test/std/concepts/comparison/concepts.equalitycomparable/equality_comparable.compile.pass.cpp
@@ -0,0 +1,143 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+// UNSUPPORTED: libcpp-no-concepts
+
+// template<class T>
+// concept equality_comparable = // see below
+
+#include <concepts>
+
+#include <array>
+#include <deque>
+#include <forward_list>
+#include <list>
+#include <map>
+#include <memory>
+#include <mutex>
+#include <optional>
+#include <set>
+#include <unordered_map>
+#include <unordered_set>
+#include <vector>
+
+#include "../types.h"
+
+namespace fundamentals {
+static_assert(std::equality_comparable<int>);
+static_assert(std::equality_comparable<double>);
+static_assert(std::equality_comparable<void*>);
+static_assert(std::equality_comparable<char*>);
+static_assert(std::equality_comparable<char const*>);
+static_assert(std::equality_comparable<char volatile*>);
+static_assert(std::equality_comparable<char const volatile*>);
+static_assert(std::equality_comparable<wchar_t&>);
+static_assert(std::equality_comparable<char8_t const&>);
+static_assert(std::equality_comparable<char16_t volatile&>);
+static_assert(std::equality_comparable<char32_t const volatile&>);
+static_assert(std::equality_comparable<unsigned char&&>);
+static_assert(std::equality_comparable<unsigned short const&&>);
+static_assert(std::equality_comparable<unsigned int volatile&&>);
+static_assert(std::equality_comparable<unsigned long const volatile&&>);
+static_assert(std::equality_comparable<int[5]>);
+static_assert(std::equality_comparable<int (*)(int)>);
+static_assert(std::equality_comparable<int (&)(int)>);
+static_assert(std::equality_comparable<int (*)(int) noexcept>);
+static_assert(std::equality_comparable<int (&)(int) noexcept>);
+static_assert(std::equality_comparable<std::nullptr_t>);
+
+struct S {};
+static_assert(std::equality_comparable<int S::*>);
+static_assert(std::equality_comparable<int (S::*)()>);
+static_assert(std::equality_comparable<int (S::*)() noexcept>);
+static_assert(std::equality_comparable<int (S::*)() &>);
+static_assert(std::equality_comparable<int (S::*)() & noexcept>);
+static_assert(std::equality_comparable<int (S::*)() &&>);
+static_assert(std::equality_comparable<int (S::*)() && noexcept>);
+static_assert(std::equality_comparable<int (S::*)() const>);
+static_assert(std::equality_comparable<int (S::*)() const noexcept>);
+static_assert(std::equality_comparable<int (S::*)() const&>);
+static_assert(std::equality_comparable<int (S::*)() const & noexcept>);
+static_assert(std::equality_comparable<int (S::*)() const&&>);
+static_assert(std::equality_comparable<int (S::*)() const && noexcept>);
+static_assert(std::equality_comparable<int (S::*)() volatile>);
+static_assert(std::equality_comparable<int (S::*)() volatile noexcept>);
+static_assert(std::equality_comparable<int (S::*)() volatile&>);
+static_assert(std::equality_comparable<int (S::*)() volatile & noexcept>);
+static_assert(std::equality_comparable<int (S::*)() volatile&&>);
+static_assert(std::equality_comparable<int (S::*)() volatile && noexcept>);
+static_assert(std::equality_comparable<int (S::*)() const volatile>);
+static_assert(std::equality_comparable<int (S::*)() const volatile noexcept>);
+static_assert(std::equality_comparable<int (S::*)() const volatile&>);
+static_assert(std::equality_comparable<int (S::*)() const volatile & noexcept>);
+static_assert(std::equality_comparable<int (S::*)() const volatile&&>);
+static_assert(
+    std::equality_comparable<int (S::*)() const volatile && noexcept>);
+
+static_assert(!std::equality_comparable<void>);
+} // namespace fundamentals
+
+namespace standard_types {
+static_assert(std::equality_comparable<std::array<int, 10> >);
+static_assert(std::equality_comparable<std::deque<int> >);
+static_assert(std::equality_comparable<std::forward_list<int> >);
+static_assert(std::equality_comparable<std::list<int> >);
+
+#ifndef _LIBCPP_HAS_NO_THREADS
+static_assert(!std::equality_comparable<std::lock_guard<std::mutex> >);
+static_assert(std::equality_comparable<std::map<int, void*> >);
+static_assert(!std::equality_comparable<std::mutex>);
+static_assert(
+    !std::equality_comparable<std::optional<std::lock_guard<std::mutex> > >);
+static_assert(!std::equality_comparable<std::optional<std::mutex> >);
+#endif
+
+static_assert(std::equality_comparable<std::optional<int> >);
+static_assert(std::equality_comparable<std::set<int> >);
+static_assert(std::equality_comparable<std::unordered_map<int, void*> >);
+static_assert(std::equality_comparable<std::unordered_set<int> >);
+static_assert(std::equality_comparable<std::vector<bool> >);
+static_assert(std::equality_comparable<std::vector<int> >);
+} // namespace standard_types
+
+namespace types_fit_for_purpose {
+static_assert(std::equality_comparable<cxx20_member_eq>);
+static_assert(std::equality_comparable<cxx20_friend_eq>);
+static_assert(std::equality_comparable<member_three_way_comparable>);
+static_assert(std::equality_comparable<friend_three_way_comparable>);
+static_assert(std::equality_comparable<explicit_operators>);
+static_assert(std::equality_comparable<eq_neq_
diff erent_return_types>);
+static_assert(std::equality_comparable<one_member_one_friend>);
+static_assert(std::equality_comparable<equality_comparable_with_ec1>);
+
+static_assert(!std::equality_comparable<no_eq>);
+static_assert(!std::equality_comparable<no_neq>);
+static_assert(!std::equality_comparable<wrong_return_type_eq>);
+static_assert(!std::equality_comparable<wrong_return_type_ne>);
+static_assert(!std::equality_comparable<wrong_return_type>);
+static_assert(
+    !std::equality_comparable<cxx20_member_eq_operator_with_deleted_ne>);
+static_assert(
+    !std::equality_comparable<cxx20_friend_eq_operator_with_deleted_ne>);
+static_assert(
+    !std::equality_comparable<member_three_way_comparable_with_deleted_eq>);
+static_assert(
+    !std::equality_comparable<member_three_way_comparable_with_deleted_ne>);
+static_assert(
+    !std::equality_comparable<friend_three_way_comparable_with_deleted_eq>);
+static_assert(
+    !std::equality_comparable<friend_three_way_comparable_with_deleted_ne>);
+
+static_assert(!std::equality_comparable<returns_explicit_bool>);
+static_assert(std::equality_comparable<returns_true_type>);
+static_assert(std::equality_comparable<returns_false_type>);
+static_assert(std::equality_comparable<returns_int_ptr>);
+} // namespace types_fit_for_purpose
+
+int main(int, char**) { return 0; }

diff  --git a/libcxx/test/std/concepts/comparison/concepts.equalitycomparable/equality_comparable_with.compile.pass.cpp b/libcxx/test/std/concepts/comparison/concepts.equalitycomparable/equality_comparable_with.compile.pass.cpp
new file mode 100644
index 000000000000..4bca901dc5f1
--- /dev/null
+++ b/libcxx/test/std/concepts/comparison/concepts.equalitycomparable/equality_comparable_with.compile.pass.cpp
@@ -0,0 +1,1120 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+// UNSUPPORTED: libcpp-no-concepts
+
+// template<class T, class U>
+// concept equality_comparable_with = // see below
+
+#include <concepts>
+
+#include <array>
+#include <deque>
+#include <forward_list>
+#include <list>
+#include <map>
+#include <memory>
+#include <mutex>
+#include <optional>
+#include <set>
+#include <unordered_map>
+#include <unordered_set>
+#include <vector>
+
+#include "../types.h"
+
+template <class T, class U>
+constexpr bool check_equality_comparable_with() {
+  constexpr bool result = std::equality_comparable_with<T, U>;
+  static_assert(std::equality_comparable_with<U, T> == result);
+  static_assert(std::equality_comparable_with<T, U const> == result);
+  static_assert(std::equality_comparable_with<T const, U const> == result);
+  static_assert(std::equality_comparable_with<T, U const&> == result);
+  static_assert(std::equality_comparable_with<T const, U const&> == result);
+  static_assert(std::equality_comparable_with<T&, U const> == result);
+  static_assert(std::equality_comparable_with<T const&, U const> == result);
+  static_assert(std::equality_comparable_with<T&, U const&> == result);
+  static_assert(std::equality_comparable_with<T const&, U const&> == result);
+  static_assert(std::equality_comparable_with<T, U const&&> == result);
+  static_assert(std::equality_comparable_with<T const, U const&&> == result);
+  static_assert(std::equality_comparable_with<T&, U const&&> == result);
+  static_assert(std::equality_comparable_with<T const&, U const&&> == result);
+  static_assert(std::equality_comparable_with<T&&, U const> == result);
+  static_assert(std::equality_comparable_with<T const&&, U const> == result);
+  static_assert(std::equality_comparable_with<T&&, U const&> == result);
+  static_assert(std::equality_comparable_with<T const&&, U const&> == result);
+  static_assert(std::equality_comparable_with<T&&, U const&&> == result);
+  static_assert(std::equality_comparable_with<T const&&, U const&&> == result);
+  return result;
+}
+
+namespace fundamentals {
+static_assert(check_equality_comparable_with<int, int>());
+static_assert(check_equality_comparable_with<int, bool>());
+static_assert(check_equality_comparable_with<int, char>());
+static_assert(check_equality_comparable_with<int, wchar_t>());
+static_assert(check_equality_comparable_with<int, double>());
+static_assert(!check_equality_comparable_with<int, int*>());
+static_assert(!check_equality_comparable_with<int, int[5]>());
+static_assert(!check_equality_comparable_with<int, int (*)()>());
+static_assert(!check_equality_comparable_with<int, int (&)()>());
+
+struct S {};
+static_assert(!check_equality_comparable_with<int, int S::*>());
+static_assert(!check_equality_comparable_with<int, int (S::*)()>());
+static_assert(!check_equality_comparable_with<int, int (S::*)() noexcept>());
+static_assert(!check_equality_comparable_with<int, int (S::*)() const>());
+static_assert(
+    !check_equality_comparable_with<int, int (S::*)() const noexcept>());
+static_assert(!check_equality_comparable_with<int, int (S::*)() volatile>());
+static_assert(
+    !check_equality_comparable_with<int, int (S::*)() volatile noexcept>());
+static_assert(
+    !check_equality_comparable_with<int, int (S::*)() const volatile>());
+static_assert(!check_equality_comparable_with<
+              int, int (S::*)() const volatile noexcept>());
+static_assert(!check_equality_comparable_with<int, int (S::*)() &>());
+static_assert(!check_equality_comparable_with<int, int (S::*)() & noexcept>());
+static_assert(!check_equality_comparable_with<int, int (S::*)() const&>());
+static_assert(
+    !check_equality_comparable_with<int, int (S::*)() const & noexcept>());
+static_assert(!check_equality_comparable_with<int, int (S::*)() volatile&>());
+static_assert(
+    !check_equality_comparable_with<int, int (S::*)() volatile & noexcept>());
+static_assert(
+    !check_equality_comparable_with<int, int (S::*)() const volatile&>());
+static_assert(!check_equality_comparable_with<int, int (S::*)() const volatile &
+                                                       noexcept>());
+static_assert(!check_equality_comparable_with<int, int (S::*)() &&>());
+static_assert(!check_equality_comparable_with < int,
+              int (S::*)() && noexcept > ());
+static_assert(!check_equality_comparable_with<int, int (S::*)() const&&>());
+static_assert(!check_equality_comparable_with < int,
+              int (S::*)() const&& noexcept > ());
+static_assert(!check_equality_comparable_with<int, int (S::*)() volatile&&>());
+static_assert(!check_equality_comparable_with < int,
+              int (S::*)() volatile&& noexcept > ());
+static_assert(
+    !check_equality_comparable_with<int, int (S::*)() const volatile&&>());
+static_assert(!check_equality_comparable_with < int,
+              int (S::*)() const volatile&& noexcept > ());
+
+static_assert(check_equality_comparable_with<int*, int*>());
+static_assert(check_equality_comparable_with<int*, int[5]>());
+static_assert(!check_equality_comparable_with<int*, int (*)()>());
+static_assert(!check_equality_comparable_with<int*, int (&)()>());
+static_assert(!check_equality_comparable_with<int*, int (S::*)()>());
+static_assert(!check_equality_comparable_with<int*, int (S::*)() noexcept>());
+static_assert(!check_equality_comparable_with<int*, int (S::*)() const>());
+static_assert(
+    !check_equality_comparable_with<int*, int (S::*)() const noexcept>());
+static_assert(!check_equality_comparable_with<int*, int (S::*)() volatile>());
+static_assert(
+    !check_equality_comparable_with<int*, int (S::*)() volatile noexcept>());
+static_assert(
+    !check_equality_comparable_with<int*, int (S::*)() const volatile>());
+static_assert(!check_equality_comparable_with<
+              int*, int (S::*)() const volatile noexcept>());
+static_assert(!check_equality_comparable_with<int*, int (S::*)() &>());
+static_assert(!check_equality_comparable_with<int*, int (S::*)() & noexcept>());
+static_assert(!check_equality_comparable_with<int*, int (S::*)() const&>());
+static_assert(
+    !check_equality_comparable_with<int*, int (S::*)() const & noexcept>());
+static_assert(!check_equality_comparable_with<int*, int (S::*)() volatile&>());
+static_assert(
+    !check_equality_comparable_with<int*, int (S::*)() volatile & noexcept>());
+static_assert(
+    !check_equality_comparable_with<int*, int (S::*)() const volatile&>());
+static_assert(!check_equality_comparable_with<
+              int*, int (S::*)() const volatile & noexcept>());
+static_assert(!check_equality_comparable_with<int*, int (S::*)() &&>());
+static_assert(!check_equality_comparable_with < int*,
+              int (S::*)() && noexcept > ());
+static_assert(!check_equality_comparable_with<int*, int (S::*)() const&&>());
+static_assert(!check_equality_comparable_with < int*,
+              int (S::*)() const&& noexcept > ());
+static_assert(!check_equality_comparable_with<int*, int (S::*)() volatile&&>());
+static_assert(!check_equality_comparable_with < int*,
+              int (S::*)() volatile&& noexcept > ());
+static_assert(
+    !check_equality_comparable_with<int*, int (S::*)() const volatile&&>());
+static_assert(!check_equality_comparable_with < int*,
+              int (S::*)() const volatile&& noexcept > ());
+
+static_assert(check_equality_comparable_with<int[5], int[5]>());
+static_assert(!check_equality_comparable_with<int[5], int (*)()>());
+static_assert(!check_equality_comparable_with<int[5], int (&)()>());
+static_assert(!check_equality_comparable_with<int[5], int (S::*)()>());
+static_assert(!check_equality_comparable_with<int[5], int (S::*)() noexcept>());
+static_assert(!check_equality_comparable_with<int[5], int (S::*)() const>());
+static_assert(
+    !check_equality_comparable_with<int[5], int (S::*)() const noexcept>());
+static_assert(!check_equality_comparable_with<int[5], int (S::*)() volatile>());
+static_assert(
+    !check_equality_comparable_with<int[5], int (S::*)() volatile noexcept>());
+static_assert(
+    !check_equality_comparable_with<int[5], int (S::*)() const volatile>());
+static_assert(!check_equality_comparable_with<
+              int[5], int (S::*)() const volatile noexcept>());
+static_assert(!check_equality_comparable_with<int[5], int (S::*)() &>());
+static_assert(
+    !check_equality_comparable_with<int[5], int (S::*)() & noexcept>());
+static_assert(!check_equality_comparable_with<int[5], int (S::*)() const&>());
+static_assert(
+    !check_equality_comparable_with<int[5], int (S::*)() const & noexcept>());
+static_assert(
+    !check_equality_comparable_with<int[5], int (S::*)() volatile&>());
+static_assert(!check_equality_comparable_with<int[5], int (S::*)() volatile &
+                                                          noexcept>());
+static_assert(
+    !check_equality_comparable_with<int[5], int (S::*)() const volatile&>());
+static_assert(!check_equality_comparable_with<
+              int[5], int (S::*)() const volatile & noexcept>());
+static_assert(!check_equality_comparable_with<int[5], int (S::*)() &&>());
+static_assert(!check_equality_comparable_with < int[5],
+              int (S::*)() && noexcept > ());
+static_assert(!check_equality_comparable_with<int[5], int (S::*)() const&&>());
+static_assert(!check_equality_comparable_with < int[5],
+              int (S::*)() const&& noexcept > ());
+static_assert(
+    !check_equality_comparable_with<int[5], int (S::*)() volatile&&>());
+static_assert(!check_equality_comparable_with < int[5],
+              int (S::*)() volatile&& noexcept > ());
+static_assert(
+    !check_equality_comparable_with<int[5], int (S::*)() const volatile&&>());
+static_assert(!check_equality_comparable_with < int[5],
+              int (S::*)() const volatile&& noexcept > ());
+
+static_assert(check_equality_comparable_with<int (*)(), int (*)()>());
+static_assert(check_equality_comparable_with<int (*)(), int (&)()>());
+static_assert(!check_equality_comparable_with<int (*)(), int (S::*)()>());
+static_assert(
+    !check_equality_comparable_with<int (*)(), int (S::*)() noexcept>());
+static_assert(!check_equality_comparable_with<int (*)(), int (S::*)() const>());
+static_assert(
+    !check_equality_comparable_with<int (*)(), int (S::*)() const noexcept>());
+static_assert(
+    !check_equality_comparable_with<int (*)(), int (S::*)() volatile>());
+static_assert(!check_equality_comparable_with<
+              int (*)(), int (S::*)() volatile noexcept>());
+static_assert(
+    !check_equality_comparable_with<int (*)(), int (S::*)() const volatile>());
+static_assert(!check_equality_comparable_with<
+              int (*)(), int (S::*)() const volatile noexcept>());
+static_assert(!check_equality_comparable_with<int (*)(), int (S::*)() &>());
+static_assert(
+    !check_equality_comparable_with<int (*)(), int (S::*)() & noexcept>());
+static_assert(
+    !check_equality_comparable_with<int (*)(), int (S::*)() const&>());
+static_assert(!check_equality_comparable_with<int (*)(),
+                                              int (S::*)() const & noexcept>());
+static_assert(
+    !check_equality_comparable_with<int (*)(), int (S::*)() volatile&>());
+static_assert(!check_equality_comparable_with<int (*)(), int (S::*)() volatile &
+                                                             noexcept>());
+static_assert(
+    !check_equality_comparable_with<int (*)(), int (S::*)() const volatile&>());
+static_assert(!check_equality_comparable_with<
+              int (*)(), int (S::*)() const volatile & noexcept>());
+static_assert(!check_equality_comparable_with<int (*)(), int (S::*)() &&>());
+static_assert(!check_equality_comparable_with < int (*)(),
+              int (S::*)() && noexcept > ());
+static_assert(
+    !check_equality_comparable_with<int (*)(), int (S::*)() const&&>());
+static_assert(!check_equality_comparable_with < int (*)(),
+              int (S::*)() const&& noexcept > ());
+static_assert(
+    !check_equality_comparable_with<int (*)(), int (S::*)() volatile&&>());
+static_assert(!check_equality_comparable_with < int (*)(),
+              int (S::*)() volatile&& noexcept > ());
+static_assert(!check_equality_comparable_with<int (*)(),
+                                              int (S::*)() const volatile&&>());
+static_assert(!check_equality_comparable_with < int (*)(),
+              int (S::*)() const volatile&& noexcept > ());
+
+static_assert(check_equality_comparable_with<int (&)(), int (&)()>());
+static_assert(!check_equality_comparable_with<int (&)(), int (S::*)()>());
+static_assert(
+    !check_equality_comparable_with<int (&)(), int (S::*)() noexcept>());
+static_assert(!check_equality_comparable_with<int (&)(), int (S::*)() const>());
+static_assert(
+    !check_equality_comparable_with<int (&)(), int (S::*)() const noexcept>());
+static_assert(
+    !check_equality_comparable_with<int (&)(), int (S::*)() volatile>());
+static_assert(!check_equality_comparable_with<
+              int (&)(), int (S::*)() volatile noexcept>());
+static_assert(
+    !check_equality_comparable_with<int (&)(), int (S::*)() const volatile>());
+static_assert(!check_equality_comparable_with<
+              int (&)(), int (S::*)() const volatile noexcept>());
+static_assert(!check_equality_comparable_with<int (&)(), int (S::*)() &>());
+static_assert(
+    !check_equality_comparable_with<int (&)(), int (S::*)() & noexcept>());
+static_assert(
+    !check_equality_comparable_with<int (&)(), int (S::*)() const&>());
+static_assert(!check_equality_comparable_with<int (&)(),
+                                              int (S::*)() const & noexcept>());
+static_assert(
+    !check_equality_comparable_with<int (&)(), int (S::*)() volatile&>());
+static_assert(!check_equality_comparable_with<int (&)(), int (S::*)() volatile &
+                                                             noexcept>());
+static_assert(
+    !check_equality_comparable_with<int (&)(), int (S::*)() const volatile&>());
+static_assert(!check_equality_comparable_with<
+              int (&)(), int (S::*)() const volatile & noexcept>());
+static_assert(!check_equality_comparable_with<int (&)(), int (S::*)() &&>());
+static_assert(!check_equality_comparable_with < int (&)(),
+              int (S::*)() && noexcept > ());
+static_assert(
+    !check_equality_comparable_with<int (&)(), int (S::*)() const&&>());
+static_assert(!check_equality_comparable_with < int (&)(),
+              int (S::*)() const&& noexcept > ());
+static_assert(
+    !check_equality_comparable_with<int (&)(), int (S::*)() volatile&&>());
+static_assert(!check_equality_comparable_with < int (&)(),
+              int (S::*)() volatile&& noexcept > ());
+static_assert(!check_equality_comparable_with<int (&)(),
+                                              int (S::*)() const volatile&&>());
+static_assert(!check_equality_comparable_with < int (&)(),
+              int (S::*)() const volatile&& noexcept > ());
+
+static_assert(check_equality_comparable_with<int (S::*)(), int (S::*)()>());
+static_assert(
+    check_equality_comparable_with<int (S::*)(), int (S::*)() noexcept>());
+static_assert(
+    !check_equality_comparable_with<int (S::*)(), int (S::*)() const>());
+static_assert(!check_equality_comparable_with<int (S::*)(),
+                                              int (S::*)() const noexcept>());
+static_assert(
+    !check_equality_comparable_with<int (S::*)(), int (S::*)() volatile>());
+static_assert(!check_equality_comparable_with<
+              int (S::*)(), int (S::*)() volatile noexcept>());
+static_assert(!check_equality_comparable_with<int (S::*)(),
+                                              int (S::*)() const volatile>());
+static_assert(!check_equality_comparable_with<
+              int (S::*)(), int (S::*)() const volatile noexcept>());
+static_assert(!check_equality_comparable_with<int (S::*)(), int (S::*)() &>());
+static_assert(
+    !check_equality_comparable_with<int (S::*)(), int (S::*)() & noexcept>());
+static_assert(
+    !check_equality_comparable_with<int (S::*)(), int (S::*)() const&>());
+static_assert(!check_equality_comparable_with<int (S::*)(),
+                                              int (S::*)() const & noexcept>());
+static_assert(
+    !check_equality_comparable_with<int (S::*)(), int (S::*)() volatile&>());
+static_assert(!check_equality_comparable_with<
+              int (S::*)(), int (S::*)() volatile & noexcept>());
+static_assert(!check_equality_comparable_with<int (S::*)(),
+                                              int (S::*)() const volatile&>());
+static_assert(!check_equality_comparable_with<
+              int (S::*)(), int (S::*)() const volatile & noexcept>());
+static_assert(!check_equality_comparable_with<int (S::*)(), int (S::*)() &&>());
+static_assert(!check_equality_comparable_with < int (S::*)(),
+              int (S::*)() && noexcept > ());
+static_assert(
+    !check_equality_comparable_with<int (S::*)(), int (S::*)() const&&>());
+static_assert(!check_equality_comparable_with < int (S::*)(),
+              int (S::*)() const&& noexcept > ());
+static_assert(
+    !check_equality_comparable_with<int (S::*)(), int (S::*)() volatile&&>());
+static_assert(!check_equality_comparable_with < int (S::*)(),
+              int (S::*)() volatile&& noexcept > ());
+static_assert(!check_equality_comparable_with<int (S::*)(),
+                                              int (S::*)() const volatile&&>());
+static_assert(!check_equality_comparable_with < int (S::*)(),
+              int (S::*)() const volatile&& noexcept > ());
+
+static_assert(check_equality_comparable_with<int (S::*)() noexcept,
+                                             int (S::*)() noexcept>());
+static_assert(!check_equality_comparable_with<int (S::*)() noexcept,
+                                              int (S::*)() const>());
+static_assert(!check_equality_comparable_with<int (S::*)() noexcept,
+                                              int (S::*)() const noexcept>());
+static_assert(!check_equality_comparable_with<int (S::*)() noexcept,
+                                              int (S::*)() volatile>());
+static_assert(!check_equality_comparable_with<
+              int (S::*)() noexcept, int (S::*)() volatile noexcept>());
+static_assert(!check_equality_comparable_with<int (S::*)() noexcept,
+                                              int (S::*)() const volatile>());
+static_assert(!check_equality_comparable_with<
+              int (S::*)() noexcept, int (S::*)() const volatile noexcept>());
+static_assert(
+    !check_equality_comparable_with<int (S::*)() noexcept, int (S::*)() &>());
+static_assert(!check_equality_comparable_with<int (S::*)() noexcept,
+                                              int (S::*)() & noexcept>());
+static_assert(!check_equality_comparable_with<int (S::*)() noexcept,
+                                              int (S::*)() const&>());
+static_assert(!check_equality_comparable_with<int (S::*)() noexcept,
+                                              int (S::*)() const & noexcept>());
+static_assert(!check_equality_comparable_with<int (S::*)() noexcept,
+                                              int (S::*)() volatile&>());
+static_assert(!check_equality_comparable_with<
+              int (S::*)() noexcept, int (S::*)() volatile & noexcept>());
+static_assert(!check_equality_comparable_with<int (S::*)() noexcept,
+                                              int (S::*)() const volatile&>());
+static_assert(!check_equality_comparable_with<
+              int (S::*)() noexcept, int (S::*)() const volatile & noexcept>());
+static_assert(
+    !check_equality_comparable_with<int (S::*)() noexcept, int (S::*)() &&>());
+static_assert(!check_equality_comparable_with < int (S::*)() noexcept,
+              int (S::*)() && noexcept > ());
+static_assert(!check_equality_comparable_with<int (S::*)() noexcept,
+                                              int (S::*)() const&&>());
+static_assert(!check_equality_comparable_with < int (S::*)() noexcept,
+              int (S::*)() const&& noexcept > ());
+static_assert(!check_equality_comparable_with<int (S::*)() noexcept,
+                                              int (S::*)() volatile&&>());
+static_assert(!check_equality_comparable_with < int (S::*)() noexcept,
+              int (S::*)() volatile&& noexcept > ());
+static_assert(!check_equality_comparable_with<int (S::*)() noexcept,
+                                              int (S::*)() const volatile&&>());
+static_assert(!check_equality_comparable_with < int (S::*)() noexcept,
+              int (S::*)() const volatile&& noexcept > ());
+
+static_assert(
+    check_equality_comparable_with<int (S::*)() const, int (S::*)() const>());
+static_assert(check_equality_comparable_with<int (S::*)() const,
+                                             int (S::*)() const noexcept>());
+static_assert(!check_equality_comparable_with<int (S::*)() const,
+                                              int (S::*)() volatile>());
+static_assert(!check_equality_comparable_with<
+              int (S::*)() const, int (S::*)() volatile noexcept>());
+static_assert(!check_equality_comparable_with<int (S::*)() const,
+                                              int (S::*)() const volatile>());
+static_assert(!check_equality_comparable_with<
+              int (S::*)() const, int (S::*)() const volatile noexcept>());
+static_assert(
+    !check_equality_comparable_with<int (S::*)() const, int (S::*)() &>());
+static_assert(!check_equality_comparable_with<int (S::*)() const,
+                                              int (S::*)() & noexcept>());
+static_assert(
+    !check_equality_comparable_with<int (S::*)() const, int (S::*)() const&>());
+static_assert(!check_equality_comparable_with<int (S::*)() const,
+                                              int (S::*)() const & noexcept>());
+static_assert(!check_equality_comparable_with<int (S::*)() const,
+                                              int (S::*)() volatile&>());
+static_assert(!check_equality_comparable_with<
+              int (S::*)() const, int (S::*)() volatile & noexcept>());
+static_assert(!check_equality_comparable_with<int (S::*)() const,
+                                              int (S::*)() const volatile&>());
+static_assert(!check_equality_comparable_with<
+              int (S::*)() const, int (S::*)() const volatile & noexcept>());
+static_assert(
+    !check_equality_comparable_with<int (S::*)() const, int (S::*)() &&>());
+static_assert(!check_equality_comparable_with < int (S::*)() const,
+              int (S::*)() && noexcept > ());
+static_assert(!check_equality_comparable_with<int (S::*)() const,
+                                              int (S::*)() const&&>());
+static_assert(!check_equality_comparable_with < int (S::*)() const,
+              int (S::*)() const&& noexcept > ());
+static_assert(!check_equality_comparable_with<int (S::*)() const,
+                                              int (S::*)() volatile&&>());
+static_assert(!check_equality_comparable_with < int (S::*)() const,
+              int (S::*)() volatile&& noexcept > ());
+static_assert(!check_equality_comparable_with<int (S::*)() const,
+                                              int (S::*)() const volatile&&>());
+static_assert(!check_equality_comparable_with < int (S::*)() const,
+              int (S::*)() const volatile&& noexcept > ());
+
+static_assert(check_equality_comparable_with<int (S::*)() const noexcept,
+                                             int (S::*)() const noexcept>());
+static_assert(!check_equality_comparable_with<int (S::*)() const noexcept,
+                                              int (S::*)() volatile>());
+static_assert(!check_equality_comparable_with<
+              int (S::*)() const noexcept, int (S::*)() volatile noexcept>());
+static_assert(!check_equality_comparable_with<int (S::*)() const noexcept,
+                                              int (S::*)() const volatile>());
+static_assert(
+    !check_equality_comparable_with<int (S::*)() const noexcept,
+                                    int (S::*)() const volatile noexcept>());
+static_assert(!check_equality_comparable_with<int (S::*)() const noexcept,
+                                              int (S::*)() &>());
+static_assert(!check_equality_comparable_with<int (S::*)() const noexcept,
+                                              int (S::*)() & noexcept>());
+static_assert(!check_equality_comparable_with<int (S::*)() const noexcept,
+                                              int (S::*)() const&>());
+static_assert(!check_equality_comparable_with<int (S::*)() const noexcept,
+                                              int (S::*)() const & noexcept>());
+static_assert(!check_equality_comparable_with<int (S::*)() const noexcept,
+                                              int (S::*)() volatile&>());
+static_assert(!check_equality_comparable_with<
+              int (S::*)() const noexcept, int (S::*)() volatile & noexcept>());
+static_assert(!check_equality_comparable_with<int (S::*)() const noexcept,
+                                              int (S::*)() const volatile&>());
+static_assert(
+    !check_equality_comparable_with<int (S::*)() const noexcept,
+                                    int (S::*)() const volatile & noexcept>());
+static_assert(!check_equality_comparable_with<int (S::*)() const noexcept,
+                                              int (S::*)() &&>());
+static_assert(!check_equality_comparable_with < int (S::*)() const noexcept,
+              int (S::*)() && noexcept > ());
+static_assert(!check_equality_comparable_with<int (S::*)() const noexcept,
+                                              int (S::*)() const&&>());
+static_assert(!check_equality_comparable_with < int (S::*)() const noexcept,
+              int (S::*)() const&& noexcept > ());
+static_assert(!check_equality_comparable_with<int (S::*)() const noexcept,
+                                              int (S::*)() volatile&&>());
+static_assert(!check_equality_comparable_with < int (S::*)() const noexcept,
+              int (S::*)() volatile&& noexcept > ());
+static_assert(!check_equality_comparable_with<int (S::*)() const noexcept,
+                                              int (S::*)() const volatile&&>());
+static_assert(!check_equality_comparable_with < int (S::*)() const noexcept,
+              int (S::*)() const volatile&& noexcept > ());
+
+static_assert(check_equality_comparable_with<int (S::*)() volatile,
+                                             int (S::*)() volatile>());
+static_assert(check_equality_comparable_with<int (S::*)() volatile,
+                                             int (S::*)() volatile noexcept>());
+static_assert(!check_equality_comparable_with<int (S::*)() volatile,
+                                              int (S::*)() const volatile>());
+static_assert(!check_equality_comparable_with<
+              int (S::*)() volatile, int (S::*)() const volatile noexcept>());
+static_assert(
+    !check_equality_comparable_with<int (S::*)() volatile, int (S::*)() &>());
+static_assert(!check_equality_comparable_with<int (S::*)() volatile,
+                                              int (S::*)() & noexcept>());
+static_assert(!check_equality_comparable_with<int (S::*)() volatile,
+                                              int (S::*)() const&>());
+static_assert(!check_equality_comparable_with<int (S::*)() volatile,
+                                              int (S::*)() const & noexcept>());
+static_assert(!check_equality_comparable_with<int (S::*)() volatile,
+                                              int (S::*)() volatile&>());
+static_assert(!check_equality_comparable_with<
+              int (S::*)() volatile, int (S::*)() volatile & noexcept>());
+static_assert(!check_equality_comparable_with<int (S::*)() volatile,
+                                              int (S::*)() const volatile&>());
+static_assert(!check_equality_comparable_with<
+              int (S::*)() volatile, int (S::*)() const volatile & noexcept>());
+static_assert(
+    !check_equality_comparable_with<int (S::*)() volatile, int (S::*)() &&>());
+static_assert(!check_equality_comparable_with < int (S::*)() volatile,
+              int (S::*)() && noexcept > ());
+static_assert(!check_equality_comparable_with<int (S::*)() volatile,
+                                              int (S::*)() const&&>());
+static_assert(!check_equality_comparable_with < int (S::*)() volatile,
+              int (S::*)() const&& noexcept > ());
+static_assert(!check_equality_comparable_with<int (S::*)() volatile,
+                                              int (S::*)() volatile&&>());
+static_assert(!check_equality_comparable_with < int (S::*)() volatile,
+              int (S::*)() volatile&& noexcept > ());
+static_assert(!check_equality_comparable_with<int (S::*)() volatile,
+                                              int (S::*)() const volatile&&>());
+static_assert(!check_equality_comparable_with < int (S::*)() volatile,
+              int (S::*)() const volatile&& noexcept > ());
+
+static_assert(check_equality_comparable_with<int (S::*)() volatile noexcept,
+                                             int (S::*)() volatile noexcept>());
+static_assert(!check_equality_comparable_with<int (S::*)() volatile noexcept,
+                                              int (S::*)() const volatile>());
+static_assert(
+    !check_equality_comparable_with<int (S::*)() volatile noexcept,
+                                    int (S::*)() const volatile noexcept>());
+static_assert(!check_equality_comparable_with<int (S::*)() volatile noexcept,
+                                              int (S::*)() &>());
+static_assert(!check_equality_comparable_with<int (S::*)() volatile noexcept,
+                                              int (S::*)() & noexcept>());
+static_assert(!check_equality_comparable_with<int (S::*)() volatile noexcept,
+                                              int (S::*)() const&>());
+static_assert(!check_equality_comparable_with<int (S::*)() volatile noexcept,
+                                              int (S::*)() const & noexcept>());
+static_assert(!check_equality_comparable_with<int (S::*)() volatile noexcept,
+                                              int (S::*)() volatile&>());
+static_assert(
+    !check_equality_comparable_with<int (S::*)() volatile noexcept,
+                                    int (S::*)() volatile & noexcept>());
+static_assert(!check_equality_comparable_with<int (S::*)() volatile noexcept,
+                                              int (S::*)() const volatile&>());
+static_assert(
+    !check_equality_comparable_with<int (S::*)() volatile noexcept,
+                                    int (S::*)() const volatile & noexcept>());
+static_assert(!check_equality_comparable_with<int (S::*)() volatile noexcept,
+                                              int (S::*)() &&>());
+static_assert(!check_equality_comparable_with < int (S::*)() volatile noexcept,
+              int (S::*)() && noexcept > ());
+static_assert(!check_equality_comparable_with<int (S::*)() volatile noexcept,
+                                              int (S::*)() const&&>());
+static_assert(!check_equality_comparable_with < int (S::*)() volatile noexcept,
+              int (S::*)() const&& noexcept > ());
+static_assert(!check_equality_comparable_with<int (S::*)() volatile noexcept,
+                                              int (S::*)() volatile&&>());
+static_assert(!check_equality_comparable_with < int (S::*)() volatile noexcept,
+              int (S::*)() volatile&& noexcept > ());
+static_assert(!check_equality_comparable_with<int (S::*)() volatile noexcept,
+                                              int (S::*)() const volatile&&>());
+static_assert(!check_equality_comparable_with < int (S::*)() volatile noexcept,
+              int (S::*)() const volatile&& noexcept > ());
+
+static_assert(check_equality_comparable_with<int (S::*)() const volatile,
+                                             int (S::*)() const volatile>());
+static_assert(
+    check_equality_comparable_with<int (S::*)() const volatile,
+                                   int (S::*)() const volatile noexcept>());
+static_assert(!check_equality_comparable_with<int (S::*)() const volatile,
+                                              int (S::*)() &>());
+static_assert(!check_equality_comparable_with<int (S::*)() const volatile,
+                                              int (S::*)() & noexcept>());
+static_assert(!check_equality_comparable_with<int (S::*)() const volatile,
+                                              int (S::*)() const&>());
+static_assert(!check_equality_comparable_with<int (S::*)() const volatile,
+                                              int (S::*)() const & noexcept>());
+static_assert(!check_equality_comparable_with<int (S::*)() const volatile,
+                                              int (S::*)() volatile&>());
+static_assert(!check_equality_comparable_with<
+              int (S::*)() const volatile, int (S::*)() volatile & noexcept>());
+static_assert(!check_equality_comparable_with<int (S::*)() const volatile,
+                                              int (S::*)() const volatile&>());
+static_assert(
+    !check_equality_comparable_with<int (S::*)() const volatile,
+                                    int (S::*)() const volatile & noexcept>());
+static_assert(!check_equality_comparable_with<int (S::*)() const volatile,
+                                              int (S::*)() &&>());
+static_assert(!check_equality_comparable_with < int (S::*)() const volatile,
+              int (S::*)() && noexcept > ());
+static_assert(!check_equality_comparable_with<int (S::*)() const volatile,
+                                              int (S::*)() const&&>());
+static_assert(!check_equality_comparable_with < int (S::*)() const volatile,
+              int (S::*)() const&& noexcept > ());
+static_assert(!check_equality_comparable_with<int (S::*)() const volatile,
+                                              int (S::*)() volatile&&>());
+static_assert(!check_equality_comparable_with < int (S::*)() const volatile,
+              int (S::*)() volatile&& noexcept > ());
+static_assert(!check_equality_comparable_with<int (S::*)() const volatile,
+                                              int (S::*)() const volatile&&>());
+static_assert(!check_equality_comparable_with < int (S::*)() const volatile,
+              int (S::*)() const volatile&& noexcept > ());
+
+static_assert(
+    check_equality_comparable_with<int (S::*)() const volatile noexcept,
+                                   int (S::*)() const volatile noexcept>());
+static_assert(!check_equality_comparable_with<
+              int (S::*)() const volatile noexcept, int (S::*)() &>());
+static_assert(!check_equality_comparable_with<
+              int (S::*)() const volatile noexcept, int (S::*)() & noexcept>());
+static_assert(!check_equality_comparable_with<
+              int (S::*)() const volatile noexcept, int (S::*)() const&>());
+static_assert(
+    !check_equality_comparable_with<int (S::*)() const volatile noexcept,
+                                    int (S::*)() const & noexcept>());
+static_assert(!check_equality_comparable_with<
+              int (S::*)() const volatile noexcept, int (S::*)() volatile&>());
+static_assert(
+    !check_equality_comparable_with<int (S::*)() const volatile noexcept,
+                                    int (S::*)() volatile & noexcept>());
+static_assert(
+    !check_equality_comparable_with<int (S::*)() const volatile noexcept,
+                                    int (S::*)() const volatile&>());
+static_assert(
+    !check_equality_comparable_with<int (S::*)() const volatile noexcept,
+                                    int (S::*)() const volatile & noexcept>());
+static_assert(!check_equality_comparable_with<
+              int (S::*)() const volatile noexcept, int (S::*)() &&>());
+static_assert(!check_equality_comparable_with < int (S::*)()
+                                                    const volatile noexcept,
+              int (S::*)() && noexcept > ());
+static_assert(!check_equality_comparable_with<
+              int (S::*)() const volatile noexcept, int (S::*)() const&&>());
+static_assert(!check_equality_comparable_with < int (S::*)()
+                                                    const volatile noexcept,
+              int (S::*)() const&& noexcept > ());
+static_assert(!check_equality_comparable_with<
+              int (S::*)() const volatile noexcept, int (S::*)() volatile&&>());
+static_assert(!check_equality_comparable_with < int (S::*)()
+                                                    const volatile noexcept,
+              int (S::*)() volatile&& noexcept > ());
+static_assert(
+    !check_equality_comparable_with<int (S::*)() const volatile noexcept,
+                                    int (S::*)() const volatile&&>());
+static_assert(!check_equality_comparable_with < int (S::*)()
+                                                    const volatile noexcept,
+              int (S::*)() const volatile&& noexcept > ());
+
+static_assert(check_equality_comparable_with<int (S::*)() &, int (S::*)() &>());
+static_assert(
+    check_equality_comparable_with<int (S::*)() &, int (S::*)() & noexcept>());
+static_assert(
+    !check_equality_comparable_with<int (S::*)() &, int (S::*)() const&>());
+static_assert(!check_equality_comparable_with<int (S::*)() &,
+                                              int (S::*)() const & noexcept>());
+static_assert(
+    !check_equality_comparable_with<int (S::*)() &, int (S::*)() volatile&>());
+static_assert(!check_equality_comparable_with<
+              int (S::*)() &, int (S::*)() volatile & noexcept>());
+static_assert(!check_equality_comparable_with<int (S::*)() &,
+                                              int (S::*)() const volatile&>());
+static_assert(!check_equality_comparable_with<
+              int (S::*)() &, int (S::*)() const volatile & noexcept>());
+static_assert(
+    !check_equality_comparable_with<int (S::*)() &, int (S::*)() &&>());
+static_assert(!check_equality_comparable_with < int (S::*)() &,
+              int (S::*)() && noexcept > ());
+static_assert(
+    !check_equality_comparable_with<int (S::*)() &, int (S::*)() const&&>());
+static_assert(!check_equality_comparable_with < int (S::*)() &,
+              int (S::*)() const&& noexcept > ());
+static_assert(
+    !check_equality_comparable_with<int (S::*)() &, int (S::*)() volatile&&>());
+static_assert(!check_equality_comparable_with < int (S::*)() &,
+              int (S::*)() volatile&& noexcept > ());
+static_assert(!check_equality_comparable_with<int (S::*)() &,
+                                              int (S::*)() const volatile&&>());
+static_assert(!check_equality_comparable_with < int (S::*)() &,
+              int (S::*)() const volatile&& noexcept > ());
+
+static_assert(check_equality_comparable_with<int (S::*)() & noexcept,
+                                             int (S::*)() & noexcept>());
+static_assert(!check_equality_comparable_with<int (S::*)() & noexcept,
+                                              int (S::*)() const&>());
+static_assert(!check_equality_comparable_with<int (S::*)() & noexcept,
+                                              int (S::*)() const & noexcept>());
+static_assert(!check_equality_comparable_with<int (S::*)() & noexcept,
+                                              int (S::*)() volatile&>());
+static_assert(!check_equality_comparable_with<
+              int (S::*)() & noexcept, int (S::*)() volatile & noexcept>());
+static_assert(!check_equality_comparable_with<int (S::*)() & noexcept,
+                                              int (S::*)() const volatile&>());
+static_assert(
+    !check_equality_comparable_with<int (S::*)() & noexcept,
+                                    int (S::*)() const volatile & noexcept>());
+static_assert(!check_equality_comparable_with<int (S::*)() & noexcept,
+                                              int (S::*)() &&>());
+static_assert(!check_equality_comparable_with < int (S::*)() & noexcept,
+              int (S::*)() && noexcept > ());
+static_assert(!check_equality_comparable_with<int (S::*)() & noexcept,
+                                              int (S::*)() const&&>());
+static_assert(!check_equality_comparable_with < int (S::*)() & noexcept,
+              int (S::*)() const&& noexcept > ());
+static_assert(!check_equality_comparable_with<int (S::*)() & noexcept,
+                                              int (S::*)() volatile&&>());
+static_assert(!check_equality_comparable_with < int (S::*)() & noexcept,
+              int (S::*)() volatile&& noexcept > ());
+static_assert(!check_equality_comparable_with<int (S::*)() & noexcept,
+                                              int (S::*)() const volatile&&>());
+static_assert(!check_equality_comparable_with < int (S::*)() & noexcept,
+              int (S::*)() const volatile&& noexcept > ());
+
+static_assert(
+    check_equality_comparable_with<int (S::*)() const&, int (S::*)() const&>());
+static_assert(check_equality_comparable_with<int (S::*)() const&,
+                                             int (S::*)() const & noexcept>());
+static_assert(!check_equality_comparable_with<int (S::*)() const&,
+                                              int (S::*)() volatile&>());
+static_assert(!check_equality_comparable_with<
+              int (S::*)() const&, int (S::*)() volatile & noexcept>());
+static_assert(!check_equality_comparable_with<int (S::*)() const&,
+                                              int (S::*)() const volatile&>());
+static_assert(!check_equality_comparable_with<
+              int (S::*)() const&, int (S::*)() const volatile & noexcept>());
+static_assert(
+    !check_equality_comparable_with<int (S::*)() const&, int (S::*)() &&>());
+static_assert(!check_equality_comparable_with < int (S::*)() const&,
+              int (S::*)() && noexcept > ());
+static_assert(!check_equality_comparable_with<int (S::*)() const&,
+                                              int (S::*)() const&&>());
+static_assert(!check_equality_comparable_with < int (S::*)() const&,
+              int (S::*)() const&& noexcept > ());
+static_assert(!check_equality_comparable_with<int (S::*)() const&,
+                                              int (S::*)() volatile&&>());
+static_assert(!check_equality_comparable_with < int (S::*)() const&,
+              int (S::*)() volatile&& noexcept > ());
+static_assert(!check_equality_comparable_with<int (S::*)() const&,
+                                              int (S::*)() const volatile&&>());
+static_assert(!check_equality_comparable_with < int (S::*)() const&,
+              int (S::*)() const volatile&& noexcept > ());
+
+static_assert(check_equality_comparable_with<int (S::*)() const & noexcept,
+                                             int (S::*)() const & noexcept>());
+static_assert(!check_equality_comparable_with<int (S::*)() const & noexcept,
+                                              int (S::*)() volatile&>());
+static_assert(
+    !check_equality_comparable_with<int (S::*)() const & noexcept,
+                                    int (S::*)() volatile & noexcept>());
+static_assert(!check_equality_comparable_with<int (S::*)() const & noexcept,
+                                              int (S::*)() const volatile&>());
+static_assert(
+    !check_equality_comparable_with<int (S::*)() const & noexcept,
+                                    int (S::*)() const volatile & noexcept>());
+static_assert(!check_equality_comparable_with<int (S::*)() const & noexcept,
+                                              int (S::*)() &&>());
+static_assert(!check_equality_comparable_with < int (S::*)() const& noexcept,
+              int (S::*)() && noexcept > ());
+static_assert(!check_equality_comparable_with<int (S::*)() const & noexcept,
+                                              int (S::*)() const&&>());
+static_assert(!check_equality_comparable_with < int (S::*)() const& noexcept,
+              int (S::*)() const&& noexcept > ());
+static_assert(!check_equality_comparable_with<int (S::*)() const & noexcept,
+                                              int (S::*)() volatile&&>());
+static_assert(!check_equality_comparable_with < int (S::*)() const& noexcept,
+              int (S::*)() volatile&& noexcept > ());
+static_assert(!check_equality_comparable_with<int (S::*)() const & noexcept,
+                                              int (S::*)() const volatile&&>());
+static_assert(!check_equality_comparable_with < int (S::*)() const& noexcept,
+              int (S::*)() const volatile&& noexcept > ());
+
+static_assert(check_equality_comparable_with<int (S::*)() volatile&,
+                                             int (S::*)() volatile&>());
+static_assert(check_equality_comparable_with<
+              int (S::*)() volatile&, int (S::*)() volatile & noexcept>());
+static_assert(!check_equality_comparable_with<int (S::*)() volatile&,
+                                              int (S::*)() const volatile&>());
+static_assert(
+    !check_equality_comparable_with<int (S::*)() volatile&,
+                                    int (S::*)() const volatile & noexcept>());
+static_assert(
+    !check_equality_comparable_with<int (S::*)() volatile&, int (S::*)() &&>());
+static_assert(!check_equality_comparable_with < int (S::*)() volatile&,
+              int (S::*)() && noexcept > ());
+static_assert(!check_equality_comparable_with<int (S::*)() volatile&,
+                                              int (S::*)() const&&>());
+static_assert(!check_equality_comparable_with < int (S::*)() volatile&,
+              int (S::*)() const&& noexcept > ());
+static_assert(!check_equality_comparable_with<int (S::*)() volatile&,
+                                              int (S::*)() volatile&&>());
+static_assert(!check_equality_comparable_with < int (S::*)() volatile&,
+              int (S::*)() volatile&& noexcept > ());
+static_assert(!check_equality_comparable_with<int (S::*)() volatile&,
+                                              int (S::*)() const volatile&&>());
+static_assert(!check_equality_comparable_with < int (S::*)() volatile&,
+              int (S::*)() const volatile&& noexcept > ());
+
+static_assert(
+    check_equality_comparable_with<int (S::*)() volatile & noexcept,
+                                   int (S::*)() volatile & noexcept>());
+static_assert(!check_equality_comparable_with<int (S::*)() volatile & noexcept,
+                                              int (S::*)() const volatile&>());
+static_assert(
+    !check_equality_comparable_with<int (S::*)() volatile & noexcept,
+                                    int (S::*)() const volatile & noexcept>());
+static_assert(!check_equality_comparable_with<int (S::*)() volatile & noexcept,
+                                              int (S::*)() &&>());
+static_assert(!check_equality_comparable_with < int (S::*)() volatile& noexcept,
+              int (S::*)() && noexcept > ());
+static_assert(!check_equality_comparable_with<int (S::*)() volatile & noexcept,
+                                              int (S::*)() const&&>());
+static_assert(!check_equality_comparable_with < int (S::*)() volatile& noexcept,
+              int (S::*)() const&& noexcept > ());
+static_assert(!check_equality_comparable_with<int (S::*)() volatile & noexcept,
+                                              int (S::*)() volatile&&>());
+static_assert(!check_equality_comparable_with < int (S::*)() volatile& noexcept,
+              int (S::*)() volatile&& noexcept > ());
+static_assert(!check_equality_comparable_with<int (S::*)() volatile & noexcept,
+                                              int (S::*)() const volatile&&>());
+static_assert(!check_equality_comparable_with < int (S::*)() volatile& noexcept,
+              int (S::*)() const volatile&& noexcept > ());
+
+static_assert(check_equality_comparable_with<int (S::*)() const volatile&,
+                                             int (S::*)() const volatile&>());
+static_assert(
+    check_equality_comparable_with<int (S::*)() const volatile&,
+                                   int (S::*)() const volatile & noexcept>());
+static_assert(!check_equality_comparable_with<int (S::*)() const volatile&,
+                                              int (S::*)() &&>());
+static_assert(!check_equality_comparable_with < int (S::*)() const volatile&,
+              int (S::*)() && noexcept > ());
+static_assert(!check_equality_comparable_with<int (S::*)() const volatile&,
+                                              int (S::*)() const&&>());
+static_assert(!check_equality_comparable_with < int (S::*)() const volatile&,
+              int (S::*)() const&& noexcept > ());
+static_assert(!check_equality_comparable_with<int (S::*)() const volatile&,
+                                              int (S::*)() volatile&&>());
+static_assert(!check_equality_comparable_with < int (S::*)() const volatile&,
+              int (S::*)() volatile&& noexcept > ());
+static_assert(!check_equality_comparable_with<int (S::*)() const volatile&,
+                                              int (S::*)() const volatile&&>());
+static_assert(!check_equality_comparable_with < int (S::*)() const volatile&,
+              int (S::*)() const volatile&& noexcept > ());
+
+static_assert(
+    check_equality_comparable_with<int (S::*)() const volatile & noexcept,
+                                   int (S::*)() const volatile & noexcept>());
+static_assert(!check_equality_comparable_with<
+              int (S::*)() const volatile & noexcept, int (S::*)() &&>());
+static_assert(!check_equality_comparable_with < int (S::*)()
+                                                    const volatile& noexcept,
+              int (S::*)() && noexcept > ());
+static_assert(!check_equality_comparable_with<
+              int (S::*)() const volatile & noexcept, int (S::*)() const&&>());
+static_assert(!check_equality_comparable_with < int (S::*)()
+                                                    const volatile& noexcept,
+              int (S::*)() const&& noexcept > ());
+static_assert(
+    !check_equality_comparable_with<int (S::*)() const volatile & noexcept,
+                                    int (S::*)() volatile&&>());
+static_assert(!check_equality_comparable_with < int (S::*)()
+                                                    const volatile& noexcept,
+              int (S::*)() volatile&& noexcept > ());
+static_assert(
+    !check_equality_comparable_with<int (S::*)() const volatile & noexcept,
+                                    int (S::*)() const volatile&&>());
+static_assert(!check_equality_comparable_with < int (S::*)()
+                                                    const volatile& noexcept,
+              int (S::*)() const volatile&& noexcept > ());
+
+static_assert(
+    check_equality_comparable_with<int (S::*)() &&, int (S::*)() &&>());
+static_assert(check_equality_comparable_with<int (S::*)() &&,
+                                             int (S::*)() && noexcept>());
+static_assert(
+    !check_equality_comparable_with<int (S::*)() &&, int (S::*)() const&&>());
+static_assert(!check_equality_comparable_with < int (S::*)() &&,
+              int (S::*)() const&& noexcept > ());
+static_assert(!check_equality_comparable_with<int (S::*)() &&,
+                                              int (S::*)() volatile&&>());
+static_assert(!check_equality_comparable_with < int (S::*)() &&,
+              int (S::*)() volatile&& noexcept > ());
+static_assert(!check_equality_comparable_with<int (S::*)() &&,
+                                              int (S::*)() const volatile&&>());
+static_assert(!check_equality_comparable_with < int (S::*)() &&,
+              int (S::*)() const volatile&& noexcept > ());
+
+static_assert(check_equality_comparable_with<int (S::*)() && noexcept,
+                                             int (S::*)() && noexcept>());
+static_assert(!check_equality_comparable_with < int (S::*)() && noexcept,
+              int (S::*)() const&& > ());
+static_assert(!check_equality_comparable_with < int (S::*)() && noexcept,
+              int (S::*)() const&& noexcept > ());
+static_assert(!check_equality_comparable_with < int (S::*)() && noexcept,
+              int (S::*)() volatile&& > ());
+static_assert(!check_equality_comparable_with < int (S::*)() && noexcept,
+              int (S::*)() volatile&& noexcept > ());
+static_assert(!check_equality_comparable_with < int (S::*)() && noexcept,
+              int (S::*)() const volatile&& > ());
+static_assert(!check_equality_comparable_with < int (S::*)() && noexcept,
+              int (S::*)() const volatile&& noexcept > ());
+
+static_assert(check_equality_comparable_with<int (S::*)() const&&,
+                                             int (S::*)() const&&>());
+static_assert(check_equality_comparable_with<int (S::*)() const&&,
+                                             int (S::*)() const && noexcept>());
+static_assert(!check_equality_comparable_with<int (S::*)() const&&,
+                                              int (S::*)() volatile&&>());
+static_assert(!check_equality_comparable_with < int (S::*)() const&&,
+              int (S::*)() volatile&& noexcept > ());
+static_assert(!check_equality_comparable_with<int (S::*)() const&&,
+                                              int (S::*)() const volatile&&>());
+static_assert(!check_equality_comparable_with < int (S::*)() const&&,
+              int (S::*)() const volatile&& noexcept > ());
+
+static_assert(check_equality_comparable_with<int (S::*)() const && noexcept,
+                                             int (S::*)() const && noexcept>());
+static_assert(!check_equality_comparable_with < int (S::*)() const&& noexcept,
+              int (S::*)() volatile&& > ());
+static_assert(!check_equality_comparable_with < int (S::*)() const&& noexcept,
+              int (S::*)() volatile&& noexcept > ());
+static_assert(!check_equality_comparable_with < int (S::*)() const&& noexcept,
+              int (S::*)() const volatile&& > ());
+static_assert(!check_equality_comparable_with < int (S::*)() const&& noexcept,
+              int (S::*)() const volatile&& noexcept > ());
+
+static_assert(check_equality_comparable_with<int (S::*)() volatile&&,
+                                             int (S::*)() volatile&&>());
+static_assert(check_equality_comparable_with<
+              int (S::*)() volatile&&, int (S::*)() volatile && noexcept>());
+static_assert(!check_equality_comparable_with<int (S::*)() volatile&&,
+                                              int (S::*)() const volatile&&>());
+static_assert(!check_equality_comparable_with < int (S::*)() volatile&&,
+              int (S::*)() const volatile&& noexcept > ());
+
+static_assert(
+    check_equality_comparable_with<int (S::*)() volatile && noexcept,
+                                   int (S::*)() volatile && noexcept>());
+static_assert(!check_equality_comparable_with <
+                  int (S::*)() volatile&& noexcept,
+              int (S::*)() const volatile&& > ());
+static_assert(!check_equality_comparable_with <
+                  int (S::*)() volatile&& noexcept,
+              int (S::*)() const volatile&& noexcept > ());
+
+static_assert(check_equality_comparable_with<int (S::*)() const volatile&&,
+                                             int (S::*)() const volatile&&>());
+static_assert(
+    check_equality_comparable_with<int (S::*)() const volatile&&,
+                                   int (S::*)() const volatile && noexcept>());
+static_assert(
+    check_equality_comparable_with<int (S::*)() const volatile && noexcept,
+                                   int (S::*)() const volatile && noexcept>());
+
+static_assert(!check_equality_comparable_with<std::nullptr_t, int>());
+static_assert(check_equality_comparable_with<std::nullptr_t, int*>());
+static_assert(check_equality_comparable_with<std::nullptr_t, int[5]>());
+static_assert(check_equality_comparable_with<std::nullptr_t, int (*)()>());
+static_assert(check_equality_comparable_with<std::nullptr_t, int (&)()>());
+static_assert(check_equality_comparable_with<std::nullptr_t, int (S::*)()>());
+static_assert(
+    check_equality_comparable_with<std::nullptr_t, int (S::*)() noexcept>());
+static_assert(
+    check_equality_comparable_with<std::nullptr_t, int (S::*)() const>());
+static_assert(check_equality_comparable_with<std::nullptr_t,
+                                             int (S::*)() const noexcept>());
+static_assert(
+    check_equality_comparable_with<std::nullptr_t, int (S::*)() volatile>());
+static_assert(check_equality_comparable_with<std::nullptr_t,
+                                             int (S::*)() volatile noexcept>());
+static_assert(check_equality_comparable_with<std::nullptr_t,
+                                             int (S::*)() const volatile>());
+static_assert(check_equality_comparable_with<
+              std::nullptr_t, int (S::*)() const volatile noexcept>());
+static_assert(check_equality_comparable_with<std::nullptr_t, int (S::*)() &>());
+static_assert(
+    check_equality_comparable_with<std::nullptr_t, int (S::*)() & noexcept>());
+static_assert(
+    check_equality_comparable_with<std::nullptr_t, int (S::*)() const&>());
+static_assert(check_equality_comparable_with<std::nullptr_t,
+                                             int (S::*)() const & noexcept>());
+static_assert(
+    check_equality_comparable_with<std::nullptr_t, int (S::*)() volatile&>());
+static_assert(check_equality_comparable_with<
+              std::nullptr_t, int (S::*)() volatile & noexcept>());
+static_assert(check_equality_comparable_with<std::nullptr_t,
+                                             int (S::*)() const volatile&>());
+static_assert(check_equality_comparable_with<
+              std::nullptr_t, int (S::*)() const volatile & noexcept>());
+static_assert(
+    check_equality_comparable_with<std::nullptr_t, int (S::*)() &&>());
+static_assert(
+    check_equality_comparable_with<std::nullptr_t, int (S::*)() && noexcept>());
+static_assert(
+    check_equality_comparable_with<std::nullptr_t, int (S::*)() const&&>());
+static_assert(check_equality_comparable_with<std::nullptr_t,
+                                             int (S::*)() const && noexcept>());
+static_assert(
+    check_equality_comparable_with<std::nullptr_t, int (S::*)() volatile&&>());
+static_assert(check_equality_comparable_with<
+              std::nullptr_t, int (S::*)() volatile && noexcept>());
+static_assert(check_equality_comparable_with<std::nullptr_t,
+                                             int (S::*)() const volatile&&>());
+static_assert(check_equality_comparable_with<
+              std::nullptr_t, int (S::*)() const volatile && noexcept>());
+
+static_assert(!std::equality_comparable_with<void, int>);
+static_assert(!std::equality_comparable_with<void, int*>);
+static_assert(!std::equality_comparable_with<void, std::nullptr_t>);
+static_assert(!std::equality_comparable_with<void, int[5]>);
+static_assert(!std::equality_comparable_with<void, int (*)()>);
+static_assert(!std::equality_comparable_with<void, int (&)()>);
+static_assert(!std::equality_comparable_with<void, int S::*>);
+static_assert(!std::equality_comparable_with<void, int (S::*)()>);
+static_assert(!std::equality_comparable_with<void, int (S::*)() noexcept>);
+static_assert(!std::equality_comparable_with<void, int (S::*)() const>);
+static_assert(
+    !std::equality_comparable_with<void, int (S::*)() const noexcept>);
+static_assert(!std::equality_comparable_with<void, int (S::*)() volatile>);
+static_assert(
+    !std::equality_comparable_with<void, int (S::*)() volatile noexcept>);
+static_assert(
+    !std::equality_comparable_with<void, int (S::*)() const volatile>);
+static_assert(
+    !std::equality_comparable_with<void, int (S::*)() const volatile noexcept>);
+static_assert(!std::equality_comparable_with<void, int (S::*)() &>);
+static_assert(!std::equality_comparable_with<void, int (S::*)() & noexcept>);
+static_assert(!std::equality_comparable_with<void, int (S::*)() const&>);
+static_assert(
+    !std::equality_comparable_with<void, int (S::*)() const & noexcept>);
+static_assert(!std::equality_comparable_with<void, int (S::*)() volatile&>);
+static_assert(
+    !std::equality_comparable_with<void, int (S::*)() volatile & noexcept>);
+static_assert(
+    !std::equality_comparable_with<void, int (S::*)() const volatile&>);
+static_assert(!std::equality_comparable_with<void, int (S::*)() const volatile &
+                                                       noexcept>);
+static_assert(!std::equality_comparable_with<void, int (S::*)() &&>);
+static_assert(!std::equality_comparable_with < void,
+              int (S::*)() && noexcept >);
+static_assert(!std::equality_comparable_with<void, int (S::*)() const&&>);
+static_assert(!std::equality_comparable_with < void,
+              int (S::*)() const&& noexcept >);
+static_assert(!std::equality_comparable_with<void, int (S::*)() volatile&&>);
+static_assert(!std::equality_comparable_with < void,
+              int (S::*)() volatile&& noexcept >);
+static_assert(
+    !std::equality_comparable_with<void, int (S::*)() const volatile&&>);
+static_assert(!std::equality_comparable_with < void,
+              int (S::*)() const volatile&& noexcept >);
+} // namespace fundamentals
+
+namespace standard_types {
+static_assert(check_equality_comparable_with<std::array<int, 10>,
+                                             std::array<int, 10> >());
+static_assert(!check_equality_comparable_with<std::array<int, 10>,
+                                              std::array<double, 10> >());
+static_assert(
+    check_equality_comparable_with<std::deque<int>, std::deque<int> >());
+static_assert(
+    !check_equality_comparable_with<std::deque<int>, std::vector<int> >());
+static_assert(check_equality_comparable_with<std::forward_list<int>,
+                                             std::forward_list<int> >());
+static_assert(!check_equality_comparable_with<std::forward_list<int>,
+                                              std::vector<int> >());
+static_assert(
+    check_equality_comparable_with<std::list<int>, std::list<int> >());
+static_assert(
+    !check_equality_comparable_with<std::list<int>, std::vector<int> >());
+
+#ifndef _LIBCPP_HAS_NO_THREADS
+static_assert(!check_equality_comparable_with<std::lock_guard<std::mutex>,
+                                              std::lock_guard<std::mutex> >());
+static_assert(!check_equality_comparable_with<std::lock_guard<std::mutex>,
+                                              std::vector<int> >());
+static_assert(!check_equality_comparable_with<std::mutex, std::mutex>());
+static_assert(!check_equality_comparable_with<std::mutex, std::vector<int> >());
+#endif
+
+static_assert(check_equality_comparable_with<std::map<int, void*>,
+                                             std::map<int, void*> >());
+static_assert(
+    !check_equality_comparable_with<std::map<int, void*>, std::vector<int> >());
+static_assert(
+    check_equality_comparable_with<std::optional<std::vector<int> >,
+                                   std::optional<std::vector<int> > >());
+static_assert(check_equality_comparable_with<std::optional<std::vector<int> >,
+                                             std::vector<int> >());
+static_assert(
+    check_equality_comparable_with<std::vector<int>, std::vector<int> >());
+static_assert(!check_equality_comparable_with<std::vector<int>, int>());
+} // namespace standard_types
+
+namespace types_fit_for_purpose {
+static_assert(
+    check_equality_comparable_with<cxx20_member_eq, cxx20_member_eq>());
+static_assert(
+    check_equality_comparable_with<cxx20_friend_eq, cxx20_friend_eq>());
+static_assert(
+    !check_equality_comparable_with<cxx20_member_eq, cxx20_friend_eq>());
+
+static_assert(check_equality_comparable_with<member_three_way_comparable,
+                                             member_three_way_comparable>());
+static_assert(check_equality_comparable_with<friend_three_way_comparable,
+                                             friend_three_way_comparable>());
+static_assert(!check_equality_comparable_with<member_three_way_comparable,
+                                              friend_three_way_comparable>());
+
+static_assert(
+    check_equality_comparable_with<explicit_operators, explicit_operators>());
+static_assert(check_equality_comparable_with<equality_comparable_with_ec1,
+                                             equality_comparable_with_ec1>());
+static_assert(check_equality_comparable_with<eq_neq_
diff erent_return_types,
+                                             eq_neq_
diff erent_return_types>());
+static_assert(check_equality_comparable_with<explicit_operators,
+                                             equality_comparable_with_ec1>());
+static_assert(check_equality_comparable_with<explicit_operators,
+                                             eq_neq_
diff erent_return_types>());
+
+static_assert(check_equality_comparable_with<one_way_eq, one_way_eq>());
+static_assert(
+    std::common_reference_with<one_way_eq const&, explicit_operators const&>);
+static_assert(
+    !check_equality_comparable_with<one_way_eq, explicit_operators>());
+
+static_assert(check_equality_comparable_with<one_way_ne, one_way_ne>());
+static_assert(
+    std::common_reference_with<one_way_ne const&, explicit_operators const&>);
+static_assert(
+    !check_equality_comparable_with<one_way_ne, explicit_operators>());
+} // namespace types_fit_for_purpose
+
+int main(int, char**) { return 0; }

diff  --git a/libcxx/test/std/concepts/comparison/types.h b/libcxx/test/std/concepts/comparison/types.h
new file mode 100644
index 000000000000..281305324979
--- /dev/null
+++ b/libcxx/test/std/concepts/comparison/types.h
@@ -0,0 +1,200 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_CONCEPTS_COMPARISON_EQUALITYCOMPARABLE_H
+#define TEST_STD_CONCEPTS_COMPARISON_EQUALITYCOMPARABLE_H
+
+#include <compare>
+#include <concepts>
+#include <type_traits>
+
+// `noexcept` specifiers deliberately imperfect since not all programmers bother to put the
+// specifiers on their overloads.
+
+struct equality_comparable_with_ec1;
+struct no_neq;
+
+struct cxx20_member_eq {
+  bool operator==(cxx20_member_eq const&) const = default;
+};
+
+struct cxx20_friend_eq {
+  friend bool operator==(cxx20_friend_eq const&,
+                         cxx20_friend_eq const&) = default;
+};
+
+struct member_three_way_comparable {
+  auto operator<=>(member_three_way_comparable const&) const = default;
+};
+
+struct friend_three_way_comparable {
+  friend auto operator<=>(friend_three_way_comparable const&,
+                          friend_three_way_comparable const&) = default;
+};
+
+struct explicit_operators {
+  friend bool operator==(explicit_operators, explicit_operators) noexcept;
+  friend bool operator!=(explicit_operators, explicit_operators) noexcept;
+
+  friend bool operator==(explicit_operators const&,
+                         equality_comparable_with_ec1 const&) noexcept;
+  friend bool operator==(equality_comparable_with_ec1 const&,
+                         explicit_operators const&) noexcept;
+  friend bool operator!=(explicit_operators const&,
+                         equality_comparable_with_ec1 const&) noexcept;
+  friend bool operator!=(equality_comparable_with_ec1 const&,
+                         explicit_operators const&) noexcept;
+};
+
+struct eq_neq_
diff erent_return_types {
+  int operator==(eq_neq_
diff erent_return_types) const noexcept;
+  friend long operator!=(eq_neq_
diff erent_return_types,
+                         eq_neq_
diff erent_return_types) noexcept;
+
+  friend int operator==(explicit_operators, eq_neq_
diff erent_return_types);
+  friend int operator==(eq_neq_
diff erent_return_types, explicit_operators);
+  friend long operator!=(explicit_operators, eq_neq_
diff erent_return_types);
+  friend long operator!=(eq_neq_
diff erent_return_types, explicit_operators);
+
+  operator explicit_operators() const;
+};
+
+struct boolean {
+  operator bool() const noexcept;
+};
+
+struct one_member_one_friend {
+  friend boolean operator==(one_member_one_friend,
+                            one_member_one_friend) noexcept;
+  boolean operator!=(one_member_one_friend) const noexcept;
+
+  operator explicit_operators() const noexcept;
+  operator eq_neq_
diff erent_return_types() const noexcept;
+};
+
+struct equality_comparable_with_ec1 {
+  bool operator==(equality_comparable_with_ec1) const noexcept;
+  bool operator!=(equality_comparable_with_ec1) const noexcept;
+  operator explicit_operators() const noexcept;
+};
+
+struct no_eq {
+  friend bool operator!=(no_eq, no_eq) noexcept;
+};
+
+struct no_neq {
+  friend bool operator==(no_neq, no_neq) noexcept;
+  friend bool operator!=(no_neq, no_neq) = delete;
+};
+
+struct wrong_return_type_eq {
+  void operator==(wrong_return_type_eq) const noexcept;
+  bool operator!=(wrong_return_type_eq) const noexcept;
+};
+
+struct wrong_return_type_ne {
+  bool operator==(wrong_return_type_ne) const noexcept;
+  void operator!=(wrong_return_type_ne) const noexcept;
+};
+
+struct wrong_return_type {
+  void operator==(wrong_return_type) const noexcept;
+  void operator!=(wrong_return_type) const noexcept;
+};
+
+struct cxx20_member_eq_operator_with_deleted_ne {
+  bool
+  operator==(cxx20_member_eq_operator_with_deleted_ne const&) const = default;
+  bool
+  operator!=(cxx20_member_eq_operator_with_deleted_ne const&) const = delete;
+};
+
+struct cxx20_friend_eq_operator_with_deleted_ne {
+  friend bool
+  operator==(cxx20_friend_eq_operator_with_deleted_ne const&,
+             cxx20_friend_eq_operator_with_deleted_ne const&) = default;
+  friend bool
+  operator!=(cxx20_friend_eq_operator_with_deleted_ne const&,
+             cxx20_friend_eq_operator_with_deleted_ne const&) = delete;
+};
+
+struct member_three_way_comparable_with_deleted_eq {
+  auto operator<=>(member_three_way_comparable_with_deleted_eq const&) const =
+      default;
+  auto
+  operator==(member_three_way_comparable_with_deleted_eq const&) const = delete;
+};
+
+struct member_three_way_comparable_with_deleted_ne {
+  auto operator<=>(member_three_way_comparable_with_deleted_ne const&) const =
+      default;
+  auto
+  operator!=(member_three_way_comparable_with_deleted_ne const&) const = delete;
+};
+
+struct friend_three_way_comparable_with_deleted_eq {
+  friend auto
+  operator<=>(friend_three_way_comparable_with_deleted_eq const&,
+              friend_three_way_comparable_with_deleted_eq const&) = default;
+  friend auto
+  operator==(friend_three_way_comparable_with_deleted_eq const&,
+             friend_three_way_comparable_with_deleted_eq const&) = delete;
+};
+
+struct friend_three_way_comparable_with_deleted_ne {
+  friend auto
+  operator<=>(friend_three_way_comparable_with_deleted_ne const&,
+              friend_three_way_comparable_with_deleted_ne const&) = default;
+  friend auto
+  operator!=(friend_three_way_comparable_with_deleted_ne const&,
+             friend_three_way_comparable_with_deleted_ne const&) = delete;
+};
+
+struct one_way_eq {
+  bool operator==(one_way_eq const&) const = default;
+  friend bool operator==(one_way_eq, explicit_operators);
+  friend bool operator==(explicit_operators, one_way_eq) = delete;
+
+  operator explicit_operators() const;
+};
+
+struct one_way_ne {
+  bool operator==(one_way_ne const&) const = default;
+  friend bool operator==(one_way_ne, explicit_operators);
+  friend bool operator!=(one_way_ne, explicit_operators) = delete;
+
+  operator explicit_operators() const;
+};
+static_assert(requires(explicit_operators const x, one_way_ne const y) {
+  x != y;
+});
+
+struct explicit_bool {
+  explicit operator bool() const noexcept;
+};
+
+struct returns_explicit_bool {
+  friend explicit_bool operator==(returns_explicit_bool, returns_explicit_bool);
+  friend explicit_bool operator!=(returns_explicit_bool, returns_explicit_bool);
+};
+
+struct returns_true_type {
+  friend std::true_type operator==(returns_true_type, returns_true_type);
+  friend std::true_type operator!=(returns_true_type, returns_true_type);
+};
+
+struct returns_false_type {
+  friend std::false_type operator==(returns_false_type, returns_false_type);
+  friend std::false_type operator!=(returns_false_type, returns_false_type);
+};
+
+struct returns_int_ptr {
+  friend int* operator==(returns_int_ptr, returns_int_ptr);
+  friend int* operator!=(returns_int_ptr, returns_int_ptr);
+};
+
+#endif // TEST_STD_CONCEPTS_COMPARISON_EQUALITYCOMPARABLE_H


        


More information about the libcxx-commits mailing list