aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'libcxx/test/std/concepts')
-rw-r--r--libcxx/test/std/concepts/callable/functions.h40
-rw-r--r--libcxx/test/std/concepts/callable/invocable.compile.pass.cpp117
-rw-r--r--libcxx/test/std/concepts/callable/regularinvocable.compile.pass.cpp116
-rw-r--r--libcxx/test/std/concepts/comparison/types.h200
-rw-r--r--libcxx/test/std/concepts/concepts.callable/concept.equiv/equivalence_relation.compile.pass.cpp59
-rw-r--r--libcxx/test/std/concepts/concepts.callable/concept.equiv/equivalence_relation.pass.cpp61
-rw-r--r--libcxx/test/std/concepts/concepts.callable/concept.equiv/equivalence_relation.subsumption.compile.pass.cpp85
-rw-r--r--libcxx/test/std/concepts/concepts.callable/concept.equiv/equivalence_relation.subsumption.pass.cpp61
-rw-r--r--libcxx/test/std/concepts/concepts.callable/concept.invocable/invocable.compile.pass.cpp428
-rw-r--r--libcxx/test/std/concepts/concepts.callable/concept.predicate/predicate.compile.pass.cpp63
-rw-r--r--libcxx/test/std/concepts/concepts.callable/concept.predicate/predicate.pass.cpp65
-rw-r--r--libcxx/test/std/concepts/concepts.callable/concept.predicate/predicate.subsumption.compile.pass.cpp31
-rw-r--r--libcxx/test/std/concepts/concepts.callable/concept.predicate/predicate.subsumption.pass.cpp33
-rw-r--r--libcxx/test/std/concepts/concepts.callable/concept.regularinvocable/regular_invocable.pass.cpp469
-rw-r--r--libcxx/test/std/concepts/concepts.callable/concept.relation/relation.compile.pass.cpp57
-rw-r--r--libcxx/test/std/concepts/concepts.callable/concept.relation/relation.pass.cpp59
-rw-r--r--libcxx/test/std/concepts/concepts.callable/concept.relation/relation.subsumption.compile.pass.cpp64
-rw-r--r--libcxx/test/std/concepts/concepts.callable/concept.relation/relation.subsumption.pass.cpp41
-rw-r--r--libcxx/test/std/concepts/concepts.callable/concept.strictweakorder/strict_weak_order.compile.pass.cpp58
-rw-r--r--libcxx/test/std/concepts/concepts.callable/concept.strictweakorder/strict_weak_order.pass.cpp60
-rw-r--r--libcxx/test/std/concepts/concepts.callable/concept.strictweakorder/strict_weak_order.subsumption.compile.pass.cpp85
-rw-r--r--libcxx/test/std/concepts/concepts.callable/concept.strictweakorder/strict_weak_order.subsumption.pass.cpp40
-rw-r--r--libcxx/test/std/concepts/concepts.compare/concept.equalitycomparable/equality_comparable.compile.pass.cpp (renamed from libcxx/test/std/concepts/comparison/concepts.equalitycomparable/equality_comparable.compile.pass.cpp)19
-rw-r--r--libcxx/test/std/concepts/concepts.compare/concept.equalitycomparable/equality_comparable_with.compile.pass.cpp (renamed from libcxx/test/std/concepts/comparison/concepts.equalitycomparable/equality_comparable_with.compile.pass.cpp)6
-rw-r--r--libcxx/test/std/concepts/concepts.compare/concepts.totallyordered/totally_ordered.pass.cpp175
-rw-r--r--libcxx/test/std/concepts/concepts.compare/concepts.totallyordered/totally_ordered_with.pass.cpp1142
-rw-r--r--libcxx/test/std/concepts/concepts.compare/types.h573
-rw-r--r--libcxx/test/std/concepts/concepts.lang/concept.assignable/assignable_from.compile.pass.cpp (renamed from libcxx/test/std/concepts/lang/assignable.compile.pass.cpp)0
-rw-r--r--libcxx/test/std/concepts/concepts.lang/concept.common/common_with.compile.pass.cpp (renamed from libcxx/test/std/concepts/lang/common.compile.pass.cpp)0
-rw-r--r--libcxx/test/std/concepts/concepts.lang/concept.commonref/common_reference.compile.pass.cpp (renamed from libcxx/test/std/concepts/lang/commonreference.compile.pass.cpp)0
-rw-r--r--libcxx/test/std/concepts/concepts.lang/concept.constructible/constructible_from.compile.pass.cpp (renamed from libcxx/test/std/concepts/concept.constructible/constructible_from.compile.pass.cpp)2
-rw-r--r--libcxx/test/std/concepts/concepts.lang/concept.convertible/convertible_to.pass.cpp (renamed from libcxx/test/std/concepts/lang/convertible.compile.pass.cpp)0
-rw-r--r--libcxx/test/std/concepts/concepts.lang/concept.copyconstructible/copy_constructible.compile.pass.cpp (renamed from libcxx/test/std/concepts/lang/copyconstructible.compile.pass.cpp)0
-rw-r--r--libcxx/test/std/concepts/concepts.lang/concept.default.init/default_initializable.compile.pass.cpp (renamed from libcxx/test/std/concepts/concept.default.init/default_initializable.compile.pass.cpp)0
-rw-r--r--libcxx/test/std/concepts/concepts.lang/concept.default.init/default_initializable.verify.cpp (renamed from libcxx/test/std/concepts/concept.default.init/default_initializable.verify.cpp)0
-rw-r--r--libcxx/test/std/concepts/concepts.lang/concept.derived/derived_from.pass.cpp (renamed from libcxx/test/std/concepts/lang/derived.compile.pass.cpp)0
-rw-r--r--libcxx/test/std/concepts/concepts.lang/concept.destructible/destructible.compile.pass.cpp (renamed from libcxx/test/std/concepts/concept.destructible/destructible.compile.pass.cpp)0
-rw-r--r--libcxx/test/std/concepts/concepts.lang/concept.moveconstructible/move_constructible.compile.pass.cpp (renamed from libcxx/test/std/concepts/lang/moveconstructible.compile.pass.cpp)0
-rw-r--r--libcxx/test/std/concepts/concepts.lang/concept.same/same_as.pass.cpp (renamed from libcxx/test/std/concepts/lang/same_as.pass.cpp)0
-rw-r--r--libcxx/test/std/concepts/concepts.lang/concept.swappable/swappable.pass.cpp (renamed from libcxx/test/std/concepts/lang/swappable.pass.cpp)0
-rw-r--r--libcxx/test/std/concepts/concepts.lang/concept.swappable/swappable_with.compile.pass.cpp (renamed from libcxx/test/std/concepts/lang/swappable_with.compile.pass.cpp)45
-rw-r--r--libcxx/test/std/concepts/concepts.lang/concepts.arithmetic/arithmetic.h37
-rw-r--r--libcxx/test/std/concepts/concepts.lang/concepts.arithmetic/floating_point.pass.cpp79
-rw-r--r--libcxx/test/std/concepts/concepts.lang/concepts.arithmetic/integral.pass.cpp92
-rw-r--r--libcxx/test/std/concepts/concepts.lang/concepts.arithmetic/signed_integral.pass.cpp96
-rw-r--r--libcxx/test/std/concepts/concepts.lang/concepts.arithmetic/unsigned_integral.pass.cpp97
-rw-r--r--libcxx/test/std/concepts/concepts.object/copyable.compile.pass.cpp (renamed from libcxx/test/std/concepts/object/copyable.compile.pass.cpp)0
-rw-r--r--libcxx/test/std/concepts/concepts.object/movable.compile.pass.cpp (renamed from libcxx/test/std/concepts/object/movable.compile.pass.cpp)0
-rw-r--r--libcxx/test/std/concepts/concepts.object/regular.compile.pass.cpp (renamed from libcxx/test/std/concepts/object/regular.compile.pass.cpp)0
-rw-r--r--libcxx/test/std/concepts/concepts.object/semiregular.compile.pass.cpp (renamed from libcxx/test/std/concepts/object/semiregular.compile.pass.cpp)0
-rw-r--r--libcxx/test/std/concepts/lang/arithmetic.pass.cpp346
51 files changed, 4173 insertions, 828 deletions
diff --git a/libcxx/test/std/concepts/callable/functions.h b/libcxx/test/std/concepts/callable/functions.h
deleted file mode 100644
index bf77e44f15da..000000000000
--- a/libcxx/test/std/concepts/callable/functions.h
+++ /dev/null
@@ -1,40 +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 CALLABLE_FUNCTIONS_H
-#define CALLABLE_FUNCTIONS_H
-
-namespace RegularInvocable {
-struct A {
- int I = 13;
- constexpr int F() const noexcept { return 42; }
- constexpr int G(int X) { return 2 * X + 1; }
- constexpr int H(int J) && { return I * J; }
-};
-
-constexpr int F() noexcept { return 13; }
-constexpr int G(int I) { return 2 * I + 1; }
-} // namespace RegularInvocable
-
-namespace Predicate {
-struct L2rSorted {
- template <class T>
- constexpr bool operator()(T const& A, T const& B, T const& C) const noexcept {
- return A <= B && B <= C;
- }
-};
-
-struct NotAPredicate {
- void operator()() const noexcept {}
-};
-} // namespace Predicate
-
-namespace Relation {
-int Greater(int X, int Y) noexcept { return X > Y; }
-} // namespace Relation
-
-#endif // CALLABLE_FUNCTIONS_H
diff --git a/libcxx/test/std/concepts/callable/invocable.compile.pass.cpp b/libcxx/test/std/concepts/callable/invocable.compile.pass.cpp
deleted file mode 100644
index cd415d8d0998..000000000000
--- a/libcxx/test/std/concepts/callable/invocable.compile.pass.cpp
+++ /dev/null
@@ -1,117 +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
-//
-//===----------------------------------------------------------------------===//
-
-// UNSUPPORTED: c++03, c++11, c++14, c++17
-// UNSUPPORTED: libcpp-no-concepts
-
-// template<class T, class U>
-// concept invocable;
-
-#include <chrono>
-#include <concepts>
-#include <memory>
-#include <random>
-#include <type_traits>
-
-#include "functions.h"
-
-template <class F, class... Args>
-requires std::invocable<F, Args...> constexpr void
-ModelsInvocable(F, Args&&...) noexcept{};
-
-template <class F, class... Args>
-requires(!std::invocable<F, Args...>) constexpr
- void NotInvocable(F, Args&&...) noexcept {}
-
-static_assert(!std::invocable<void>);
-static_assert(!std::invocable<void*>);
-static_assert(!std::invocable<int>);
-static_assert(!std::invocable<int&>);
-static_assert(!std::invocable<int&&>);
-
-int main(int, char**) {
- {
- using namespace RegularInvocable;
-
- ModelsInvocable(F);
- NotInvocable(F, 0);
-
- ModelsInvocable(G, 2);
- NotInvocable(G);
- NotInvocable(G, 3, 0);
-
- NotInvocable(&A::I);
- NotInvocable(&A::F);
-
- {
- A X;
- ModelsInvocable(&A::I, X);
- ModelsInvocable(&A::F, X);
- ModelsInvocable(&A::G, X, 0);
- NotInvocable(&A::G, X);
- NotInvocable(&A::G, 0);
- NotInvocable(&A::H);
-
- A const& Y = X;
- ModelsInvocable(&A::I, Y);
- ModelsInvocable(&A::F, Y);
- NotInvocable(&A::G, Y, 0);
- NotInvocable(&A::H, Y, 0);
- }
-
- ModelsInvocable(&A::I, A{});
- ModelsInvocable(&A::F, A{});
- ModelsInvocable(&A::G, A{}, 0);
- ModelsInvocable(&A::H, A{}, 0);
-
- {
- auto Up = std::make_unique<A>();
- ModelsInvocable(&A::I, Up);
- ModelsInvocable(&A::F, Up);
- ModelsInvocable(&A::G, Up, 0);
- NotInvocable(&A::H, Up, 0);
- }
- {
- auto Sp = std::make_shared<A>();
- ModelsInvocable(&A::I, Sp);
- ModelsInvocable(&A::F, Sp);
- ModelsInvocable(&A::G, Sp, 0);
- NotInvocable(&A::H, Sp, 0);
- }
- }
- {
- using namespace Predicate;
- {
- ModelsInvocable(L2rSorted{}, 0, 1, 2);
- NotInvocable(L2rSorted{});
- NotInvocable(L2rSorted{}, 0);
- NotInvocable(L2rSorted{}, 0, 1);
- }
- {
- auto Up = std::make_unique<L2rSorted>();
- ModelsInvocable(&L2rSorted::operator()<int>, Up, 0, 1, 2);
- NotInvocable(&L2rSorted::operator()<int>, Up);
- NotInvocable(&L2rSorted::operator()<int>, Up, 0);
- NotInvocable(&L2rSorted::operator()<int>, Up, 0, 1);
- }
- {
- auto Sp = std::make_shared<L2rSorted>();
- ModelsInvocable(&L2rSorted::operator()<int>, Sp, 0, 1, 2);
- NotInvocable(&L2rSorted::operator()<int>, Sp);
- NotInvocable(&L2rSorted::operator()<int>, Sp, 0);
- NotInvocable(&L2rSorted::operator()<int>, Sp, 0, 1);
- }
- }
- {
- auto G = std::mt19937_64(
- std::chrono::high_resolution_clock().now().time_since_epoch().count());
- auto D = std::uniform_int_distribution<>();
- ModelsInvocable(D, G);
- }
- return 0;
-}
diff --git a/libcxx/test/std/concepts/callable/regularinvocable.compile.pass.cpp b/libcxx/test/std/concepts/callable/regularinvocable.compile.pass.cpp
deleted file mode 100644
index b085b7e50022..000000000000
--- a/libcxx/test/std/concepts/callable/regularinvocable.compile.pass.cpp
+++ /dev/null
@@ -1,116 +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
-//
-//===----------------------------------------------------------------------===//
-
-// UNSUPPORTED: c++03, c++11, c++14, c++17
-// UNSUPPORTED: libcpp-no-concepts
-
-// template<class T, class U>
-// concept regular_invocable;
-
-#include <concepts>
-#include <memory>
-#include <random>
-#include <type_traits>
-
-#include "functions.h"
-
-template <class F, class... Args>
-requires std::invocable<F, Args...> constexpr void
-ModelsRegularInvocable(F, Args&&...) noexcept{};
-
-template <class F, class... Args>
-requires(!std::invocable<F, Args...>) constexpr
- void NotRegularInvocable(F, Args&&...) noexcept {}
-
-static_assert(!std::invocable<void>);
-static_assert(!std::invocable<void*>);
-static_assert(!std::invocable<int>);
-static_assert(!std::invocable<int&>);
-static_assert(!std::invocable<int&&>);
-
-int main(int, char**) {
- {
- using namespace RegularInvocable;
-
- ModelsRegularInvocable(F);
- NotRegularInvocable(F, 0);
-
- ModelsRegularInvocable(G, 2);
- NotRegularInvocable(G);
- NotRegularInvocable(G, 3, 0);
-
- NotRegularInvocable(&A::I);
- NotRegularInvocable(&A::F);
-
- {
- A X;
- ModelsRegularInvocable(&A::I, X);
- ModelsRegularInvocable(&A::F, X);
- ModelsRegularInvocable(&A::G, X, 0);
- NotRegularInvocable(&A::G, X);
- NotRegularInvocable(&A::G, 0);
- NotRegularInvocable(&A::H);
-
- A const& Y = X;
- ModelsRegularInvocable(&A::I, Y);
- ModelsRegularInvocable(&A::F, Y);
- NotRegularInvocable(&A::G, Y, 0);
- NotRegularInvocable(&A::H, Y, 0);
- }
-
- ModelsRegularInvocable(&A::I, A{});
- ModelsRegularInvocable(&A::F, A{});
- ModelsRegularInvocable(&A::G, A{}, 0);
- ModelsRegularInvocable(&A::H, A{}, 0);
-
- {
- auto Up = std::make_unique<A>();
- ModelsRegularInvocable(&A::I, Up);
- ModelsRegularInvocable(&A::F, Up);
- ModelsRegularInvocable(&A::G, Up, 0);
- NotRegularInvocable(&A::H, Up, 0);
- }
- {
- auto Sp = std::make_shared<A>();
- ModelsRegularInvocable(&A::I, Sp);
- ModelsRegularInvocable(&A::F, Sp);
- ModelsRegularInvocable(&A::G, Sp, 0);
- NotRegularInvocable(&A::H, Sp, 0);
- }
- }
- {
- using namespace Predicate;
- {
- ModelsRegularInvocable(L2rSorted{}, 0, 1, 2);
- NotRegularInvocable(L2rSorted{});
- NotRegularInvocable(L2rSorted{}, 0);
- NotRegularInvocable(L2rSorted{}, 0, 1);
- }
- {
- auto Up = std::make_unique<L2rSorted>();
- ModelsRegularInvocable(&L2rSorted::operator()<int>, Up, 0, 1, 2);
- NotRegularInvocable(&L2rSorted::operator()<int>, Up);
- NotRegularInvocable(&L2rSorted::operator()<int>, Up, 0);
- NotRegularInvocable(&L2rSorted::operator()<int>, Up, 0, 1);
- }
- {
- auto Sp = std::make_shared<L2rSorted>();
- ModelsRegularInvocable(&L2rSorted::operator()<int>, Sp, 0, 1, 2);
- NotRegularInvocable(&L2rSorted::operator()<int>, Sp);
- NotRegularInvocable(&L2rSorted::operator()<int>, Sp, 0);
- NotRegularInvocable(&L2rSorted::operator()<int>, Sp, 0, 1);
- }
- }
- // {
- // RNG doesn't model regular_invocable, left here for documentation
- // auto G = std::mt19937_64(std::random_device()());
- // auto D = std::uniform_int_distribution<>();
- // models_invocable(D, G);
- // }
- return 0;
-}
diff --git a/libcxx/test/std/concepts/comparison/types.h b/libcxx/test/std/concepts/comparison/types.h
deleted file mode 100644
index 6f7689e22c61..000000000000
--- a/libcxx/test/std/concepts/comparison/types.h
+++ /dev/null
@@ -1,200 +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_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_different_return_types {
- int operator==(eq_neq_different_return_types) const noexcept;
- friend long operator!=(eq_neq_different_return_types,
- eq_neq_different_return_types) noexcept;
-
- friend int operator==(explicit_operators, eq_neq_different_return_types);
- friend int operator==(eq_neq_different_return_types, explicit_operators);
- friend long operator!=(explicit_operators, eq_neq_different_return_types);
- friend long operator!=(eq_neq_different_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_different_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;
- bool
- 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;
- bool
- 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 bool
- 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 bool
- 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
diff --git a/libcxx/test/std/concepts/concepts.callable/concept.equiv/equivalence_relation.compile.pass.cpp b/libcxx/test/std/concepts/concepts.callable/concept.equiv/equivalence_relation.compile.pass.cpp
new file mode 100644
index 000000000000..f16024f4e182
--- /dev/null
+++ b/libcxx/test/std/concepts/concepts.callable/concept.equiv/equivalence_relation.compile.pass.cpp
@@ -0,0 +1,59 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 F, class... Args>
+// concept equivalence_relation;
+
+#include <concepts>
+
+static_assert(std::equivalence_relation<bool(int, int), int, int>);
+static_assert(std::equivalence_relation<bool(int, int), double, double>);
+static_assert(std::equivalence_relation<bool(int, double), double, double>);
+
+static_assert(!std::equivalence_relation<bool (*)(), int, double>);
+static_assert(!std::equivalence_relation<bool (*)(int), int, double>);
+static_assert(!std::equivalence_relation<bool (*)(double), int, double>);
+
+static_assert(
+ !std::equivalence_relation<bool(double, double*), double, double*>);
+static_assert(!std::equivalence_relation<bool(int&, int&), double&, double&>);
+
+struct S1 {};
+static_assert(std::relation<bool (S1::*)(S1*), S1*, S1*>);
+static_assert(std::relation<bool (S1::*)(S1&), S1&, S1&>);
+
+struct S2 {};
+
+struct P1 {
+ bool operator()(S1, S1) const;
+};
+static_assert(std::equivalence_relation<P1, S1, S1>);
+
+struct P2 {
+ bool operator()(S1, S1) const;
+ bool operator()(S1, S2) const;
+};
+static_assert(!std::equivalence_relation<P2, S1, S2>);
+
+struct P3 {
+ bool operator()(S1, S1) const;
+ bool operator()(S1, S2) const;
+ bool operator()(S2, S1) const;
+};
+static_assert(!std::equivalence_relation<P3, S1, S2>);
+
+struct P4 {
+ bool operator()(S1, S1) const;
+ bool operator()(S1, S2) const;
+ bool operator()(S2, S1) const;
+ bool operator()(S2, S2) const;
+};
+static_assert(std::equivalence_relation<P4, S1, S2>);
diff --git a/libcxx/test/std/concepts/concepts.callable/concept.equiv/equivalence_relation.pass.cpp b/libcxx/test/std/concepts/concepts.callable/concept.equiv/equivalence_relation.pass.cpp
new file mode 100644
index 000000000000..f925eb5f75ed
--- /dev/null
+++ b/libcxx/test/std/concepts/concepts.callable/concept.equiv/equivalence_relation.pass.cpp
@@ -0,0 +1,61 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 F, class... Args>
+// concept equivalence_relation;
+
+#include <concepts>
+
+static_assert(std::equivalence_relation<bool(int, int), int, int>);
+static_assert(std::equivalence_relation<bool(int, int), double, double>);
+static_assert(std::equivalence_relation<bool(int, double), double, double>);
+
+static_assert(!std::equivalence_relation<bool (*)(), int, double>);
+static_assert(!std::equivalence_relation<bool (*)(int), int, double>);
+static_assert(!std::equivalence_relation<bool (*)(double), int, double>);
+
+static_assert(
+ !std::equivalence_relation<bool(double, double*), double, double*>);
+static_assert(!std::equivalence_relation<bool(int&, int&), double&, double&>);
+
+struct S1 {};
+static_assert(std::relation<bool (S1::*)(S1*), S1*, S1*>);
+static_assert(std::relation<bool (S1::*)(S1&), S1&, S1&>);
+
+struct S2 {};
+
+struct P1 {
+ bool operator()(S1, S1) const;
+};
+static_assert(std::equivalence_relation<P1, S1, S1>);
+
+struct P2 {
+ bool operator()(S1, S1) const;
+ bool operator()(S1, S2) const;
+};
+static_assert(!std::equivalence_relation<P2, S1, S2>);
+
+struct P3 {
+ bool operator()(S1, S1) const;
+ bool operator()(S1, S2) const;
+ bool operator()(S2, S1) const;
+};
+static_assert(!std::equivalence_relation<P3, S1, S2>);
+
+struct P4 {
+ bool operator()(S1, S1) const;
+ bool operator()(S1, S2) const;
+ bool operator()(S2, S1) const;
+ bool operator()(S2, S2) const;
+};
+static_assert(std::equivalence_relation<P4, S1, S2>);
+
+int main(int, char**) { return 0; }
diff --git a/libcxx/test/std/concepts/concepts.callable/concept.equiv/equivalence_relation.subsumption.compile.pass.cpp b/libcxx/test/std/concepts/concepts.callable/concept.equiv/equivalence_relation.subsumption.compile.pass.cpp
new file mode 100644
index 000000000000..7619c8ce2217
--- /dev/null
+++ b/libcxx/test/std/concepts/concepts.callable/concept.equiv/equivalence_relation.subsumption.compile.pass.cpp
@@ -0,0 +1,85 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 F, class... Args>
+// concept equivalence_relation;
+
+#include <concepts>
+
+struct S1 {};
+struct S2 {};
+
+struct R {
+ bool operator()(S1, S1) const;
+ bool operator()(S1, S2) const;
+ bool operator()(S2, S1) const;
+ bool operator()(S2, S2) const;
+};
+
+// clang-format off
+template<class F, class T, class U>
+requires std::relation<F, T, U>
+[[nodiscard]] constexpr bool check_equivalence_relation_subsumes_relation() {
+ return false;
+}
+
+template<class F, class T, class U>
+requires std::equivalence_relation<F, T, U> && true
+[[nodiscard]] constexpr bool check_equivalence_relation_subsumes_relation() {
+ return true;
+}
+// clang-format on
+
+static_assert(check_equivalence_relation_subsumes_relation<int (*)(int, int),
+ int, int>());
+static_assert(check_equivalence_relation_subsumes_relation<int (*)(int, double),
+ int, double>());
+static_assert(check_equivalence_relation_subsumes_relation<R, S1, S1>());
+static_assert(check_equivalence_relation_subsumes_relation<R, S1, S2>());
+
+// clang-format off
+template<class F, class T, class U>
+requires std::relation<F, T, U> && true
+[[nodiscard]] constexpr bool check_relation_subsumes_equivalence_relation() {
+ return true;
+}
+
+template<class F, class T, class U>
+requires std::equivalence_relation<F, T, U>
+[[nodiscard]] constexpr bool check_relation_subsumes_equivalence_relation() {
+ return false;
+}
+// clang-format on
+
+static_assert(check_relation_subsumes_equivalence_relation<int (*)(int, int),
+ int, int>());
+static_assert(check_relation_subsumes_equivalence_relation<int (*)(int, double),
+ int, double>());
+static_assert(check_relation_subsumes_equivalence_relation<R, S1, S1>());
+static_assert(check_relation_subsumes_equivalence_relation<R, S1, S2>());
+
+// clang-format off
+template<class F, class T, class U>
+requires std::equivalence_relation<F, T, T> && std::equivalence_relation<F, U, U>
+[[nodiscard]] constexpr bool check_equivalence_relation_subsumes_itself() {
+ return false;
+}
+
+template<class F, class T, class U>
+requires std::equivalence_relation<F, T, U>
+[[nodiscard]] constexpr bool check_equivalence_relation_subsumes_itself() {
+ return true;
+}
+// clang-format on
+
+static_assert(
+ check_equivalence_relation_subsumes_itself<int (*)(int, int), int, int>());
+static_assert(check_equivalence_relation_subsumes_itself<R, S1, S1>());
diff --git a/libcxx/test/std/concepts/concepts.callable/concept.equiv/equivalence_relation.subsumption.pass.cpp b/libcxx/test/std/concepts/concepts.callable/concept.equiv/equivalence_relation.subsumption.pass.cpp
new file mode 100644
index 000000000000..0aad734fa654
--- /dev/null
+++ b/libcxx/test/std/concepts/concepts.callable/concept.equiv/equivalence_relation.subsumption.pass.cpp
@@ -0,0 +1,61 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 F, class... Args>
+// concept equivalence_relation;
+
+#include <concepts>
+
+// clang-format off
+template<class F, class T, class U>
+requires std::relation<F, T, U>
+[[nodiscard]] constexpr bool check_subsumption() { return false; }
+
+template<class F, class T>
+requires std::equivalence_relation<F, T, T> && true
+[[nodiscard]] constexpr bool check_subsumption() { return false; }
+
+template<class F, class T, class U>
+requires std::equivalence_relation<F, T, U> && true
+[[nodiscard]] constexpr bool check_subsumption() { return true; }
+// clang-format on
+
+static_assert(check_subsumption<int (*)(int, int), int, int>());
+static_assert(check_subsumption<int (*)(int, double), int, double>());
+
+struct S1 {};
+struct S2 {};
+
+struct R {
+ bool operator()(S1, S1) const;
+ bool operator()(S1, S2) const;
+ bool operator()(S2, S1) const;
+ bool operator()(S2, S2) const;
+};
+static_assert(check_subsumption<R, S1, S1>());
+static_assert(check_subsumption<R, S1, S2>());
+
+// clang-format off
+template<class F, class T, class U>
+requires std::relation<F, T, U> && true
+[[nodiscard]] constexpr bool check_reverse_subsumption() { return true; }
+
+template<class F, class T, class U>
+requires std::equivalence_relation<F, T, U>
+[[nodiscard]] constexpr bool check_no_subsumption() { return false; }
+// clang-format on
+
+static_assert(check_reverse_subsumption<int (*)(int, int), int, int>());
+static_assert(check_reverse_subsumption<int (*)(int, double), int, double>());
+static_assert(check_reverse_subsumption<R, S1, S1>());
+static_assert(check_reverse_subsumption<R, S1, S2>());
+
+int main(int, char**) { return 0; }
diff --git a/libcxx/test/std/concepts/concepts.callable/concept.invocable/invocable.compile.pass.cpp b/libcxx/test/std/concepts/concepts.callable/concept.invocable/invocable.compile.pass.cpp
new file mode 100644
index 000000000000..ffad6d6d41b3
--- /dev/null
+++ b/libcxx/test/std/concepts/concepts.callable/concept.invocable/invocable.compile.pass.cpp
@@ -0,0 +1,428 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 invocable;
+
+#include <chrono>
+#include <concepts>
+#include <memory>
+#include <random>
+#include <type_traits>
+
+template <class R, class... Args>
+[[nodiscard]] constexpr bool check_invocable() {
+ constexpr bool result = std::invocable<R(Args...), Args...>;
+ static_assert(std::invocable<R(Args...) noexcept, Args...> == result);
+ static_assert(std::invocable<R (*)(Args...), Args...> == result);
+ static_assert(std::invocable<R (*)(Args...) noexcept, Args...> == result);
+ static_assert(std::invocable<R (&)(Args...), Args...> == result);
+ static_assert(std::invocable<R (&)(Args...) noexcept, Args...> == result);
+
+ return result;
+}
+
+static_assert(check_invocable<void>());
+static_assert(check_invocable<void, int>());
+static_assert(check_invocable<void, int&>());
+static_assert(check_invocable<void, int*, double>());
+static_assert(check_invocable<int>());
+static_assert(check_invocable<int, int[]>());
+
+struct S;
+static_assert(check_invocable<int, int S::*, std::nullptr_t>());
+static_assert(check_invocable<int, int (S::*)(), int (S::*)(int), int>());
+static_assert(std::invocable<void (*)(int const&), int&>);
+static_assert(std::invocable<void (*)(int const&), int&&>);
+static_assert(std::invocable<void (*)(int volatile&), int&>);
+static_assert(std::invocable<void (*)(int const volatile&), int&>);
+
+static_assert(!std::invocable<void(), int>);
+static_assert(!std::invocable<void(int)>);
+static_assert(!std::invocable<void(int*), double*>);
+static_assert(!std::invocable<void (*)(int&), double*>);
+static_assert(std::invocable<int S::*, std::unique_ptr<S> >);
+static_assert(std::invocable<int S::*, std::shared_ptr<S> >);
+static_assert(!std::invocable<void (*)(int&&), int&>);
+static_assert(!std::invocable<void (*)(int&&), int const&>);
+
+static_assert(!std::invocable<void>);
+static_assert(!std::invocable<void*>);
+static_assert(!std::invocable<int>);
+static_assert(!std::invocable<int&>);
+static_assert(!std::invocable<int&&>);
+
+namespace function_objects {
+struct function_object {
+ void operator()();
+};
+static_assert(std::invocable<function_object>);
+static_assert(!std::invocable<function_object const>);
+static_assert(!std::invocable<function_object volatile>);
+static_assert(!std::invocable<function_object const volatile>);
+static_assert(std::invocable<function_object&>);
+static_assert(!std::invocable<function_object const&>);
+static_assert(!std::invocable<function_object volatile&>);
+static_assert(!std::invocable<function_object const volatile&>);
+
+struct const_function_object {
+ void operator()(int) const;
+};
+static_assert(std::invocable<const_function_object, int>);
+static_assert(std::invocable<const_function_object const, int>);
+static_assert(!std::invocable<const_function_object volatile, int>);
+static_assert(!std::invocable<const_function_object const volatile, int>);
+static_assert(std::invocable<const_function_object&, int>);
+static_assert(std::invocable<const_function_object const&, int>);
+static_assert(!std::invocable<const_function_object volatile&, int>);
+static_assert(!std::invocable<const_function_object const volatile&, int>);
+
+struct volatile_function_object {
+ void operator()(int, int) volatile;
+};
+static_assert(std::invocable<volatile_function_object, int, int>);
+static_assert(!std::invocable<volatile_function_object const, int, int>);
+static_assert(std::invocable<volatile_function_object volatile, int, int>);
+static_assert(
+ !std::invocable<volatile_function_object const volatile, int, int>);
+static_assert(std::invocable<volatile_function_object&, int, int>);
+static_assert(!std::invocable<volatile_function_object const&, int, int>);
+static_assert(std::invocable<volatile_function_object volatile&, int, int>);
+static_assert(
+ !std::invocable<volatile_function_object const volatile&, int, int>);
+
+struct cv_function_object {
+ void operator()(int[]) const volatile;
+};
+static_assert(std::invocable<cv_function_object, int*>);
+static_assert(std::invocable<cv_function_object const, int*>);
+static_assert(std::invocable<cv_function_object volatile, int*>);
+static_assert(std::invocable<cv_function_object const volatile, int*>);
+static_assert(std::invocable<cv_function_object&, int*>);
+static_assert(std::invocable<cv_function_object const&, int*>);
+static_assert(std::invocable<cv_function_object volatile&, int*>);
+static_assert(std::invocable<cv_function_object const volatile&, int*>);
+
+struct lvalue_function_object {
+ void operator()() &;
+};
+static_assert(!std::invocable<lvalue_function_object>);
+static_assert(!std::invocable<lvalue_function_object const>);
+static_assert(!std::invocable<lvalue_function_object volatile>);
+static_assert(!std::invocable<lvalue_function_object const volatile>);
+static_assert(std::invocable<lvalue_function_object&>);
+static_assert(!std::invocable<lvalue_function_object const&>);
+static_assert(!std::invocable<lvalue_function_object volatile&>);
+static_assert(!std::invocable<lvalue_function_object const volatile&>);
+
+struct lvalue_const_function_object {
+ void operator()(int) const&;
+};
+static_assert(std::invocable<lvalue_const_function_object, int>);
+static_assert(std::invocable<lvalue_const_function_object const, int>);
+static_assert(!std::invocable<lvalue_const_function_object volatile, int>);
+static_assert(
+ !std::invocable<lvalue_const_function_object const volatile, int>);
+static_assert(std::invocable<lvalue_const_function_object&, int>);
+static_assert(std::invocable<lvalue_const_function_object const&, int>);
+static_assert(!std::invocable<lvalue_const_function_object volatile&, int>);
+static_assert(
+ !std::invocable<lvalue_const_function_object const volatile&, int>);
+
+struct lvalue_volatile_function_object {
+ void operator()(int, int) volatile&;
+};
+static_assert(!std::invocable<lvalue_volatile_function_object, int, int>);
+static_assert(!std::invocable<lvalue_volatile_function_object const, int, int>);
+static_assert(
+ !std::invocable<lvalue_volatile_function_object volatile, int, int>);
+static_assert(
+ !std::invocable<lvalue_volatile_function_object const volatile, int, int>);
+static_assert(std::invocable<lvalue_volatile_function_object&, int, int>);
+static_assert(
+ !std::invocable<lvalue_volatile_function_object const&, int, int>);
+static_assert(
+ std::invocable<lvalue_volatile_function_object volatile&, int, int>);
+static_assert(
+ !std::invocable<lvalue_volatile_function_object const volatile&, int, int>);
+
+struct lvalue_cv_function_object {
+ void operator()(int[]) const volatile&;
+};
+static_assert(!std::invocable<lvalue_cv_function_object, int*>);
+static_assert(!std::invocable<lvalue_cv_function_object const, int*>);
+static_assert(!std::invocable<lvalue_cv_function_object volatile, int*>);
+static_assert(!std::invocable<lvalue_cv_function_object const volatile, int*>);
+static_assert(std::invocable<lvalue_cv_function_object&, int*>);
+static_assert(std::invocable<lvalue_cv_function_object const&, int*>);
+static_assert(std::invocable<lvalue_cv_function_object volatile&, int*>);
+static_assert(std::invocable<lvalue_cv_function_object const volatile&, int*>);
+//
+struct rvalue_function_object {
+ void operator()() &&;
+};
+static_assert(std::invocable<rvalue_function_object>);
+static_assert(!std::invocable<rvalue_function_object const>);
+static_assert(!std::invocable<rvalue_function_object volatile>);
+static_assert(!std::invocable<rvalue_function_object const volatile>);
+static_assert(!std::invocable<rvalue_function_object&>);
+static_assert(!std::invocable<rvalue_function_object const&>);
+static_assert(!std::invocable<rvalue_function_object volatile&>);
+static_assert(!std::invocable<rvalue_function_object const volatile&>);
+
+struct rvalue_const_function_object {
+ void operator()(int) const&&;
+};
+static_assert(std::invocable<rvalue_const_function_object, int>);
+static_assert(std::invocable<rvalue_const_function_object const, int>);
+static_assert(!std::invocable<rvalue_const_function_object volatile, int>);
+static_assert(
+ !std::invocable<rvalue_const_function_object const volatile, int>);
+static_assert(!std::invocable<rvalue_const_function_object&, int>);
+static_assert(!std::invocable<rvalue_const_function_object const&, int>);
+static_assert(!std::invocable<rvalue_const_function_object volatile&, int>);
+static_assert(
+ !std::invocable<rvalue_const_function_object const volatile&, int>);
+
+struct rvalue_volatile_function_object {
+ void operator()(int, int) volatile&&;
+};
+static_assert(std::invocable<rvalue_volatile_function_object, int, int>);
+static_assert(!std::invocable<rvalue_volatile_function_object const, int, int>);
+static_assert(
+ std::invocable<rvalue_volatile_function_object volatile, int, int>);
+static_assert(
+ !std::invocable<rvalue_volatile_function_object const volatile, int, int>);
+static_assert(!std::invocable<rvalue_volatile_function_object&, int, int>);
+static_assert(
+ !std::invocable<rvalue_volatile_function_object const&, int, int>);
+static_assert(
+ !std::invocable<rvalue_volatile_function_object volatile&, int, int>);
+static_assert(
+ !std::invocable<rvalue_volatile_function_object const volatile&, int, int>);
+
+struct rvalue_cv_function_object {
+ void operator()(int[]) const volatile&&;
+};
+static_assert(std::invocable<rvalue_cv_function_object, int*>);
+static_assert(std::invocable<rvalue_cv_function_object const, int*>);
+static_assert(std::invocable<rvalue_cv_function_object volatile, int*>);
+static_assert(std::invocable<rvalue_cv_function_object const volatile, int*>);
+static_assert(!std::invocable<rvalue_cv_function_object&, int*>);
+static_assert(!std::invocable<rvalue_cv_function_object const&, int*>);
+static_assert(!std::invocable<rvalue_cv_function_object volatile&, int*>);
+static_assert(!std::invocable<rvalue_cv_function_object const volatile&, int*>);
+
+struct multiple_overloads {
+ struct A {};
+ struct B { B(int); };
+ struct AB : A, B {};
+ struct O {};
+ void operator()(A) const;
+ void operator()(B) const;
+};
+static_assert(std::invocable<multiple_overloads, multiple_overloads::A>);
+static_assert(std::invocable<multiple_overloads, multiple_overloads::B>);
+static_assert(std::invocable<multiple_overloads, int>);
+static_assert(!std::invocable<multiple_overloads, multiple_overloads::AB>);
+static_assert(!std::invocable<multiple_overloads, multiple_overloads::O>);
+} // namespace function_objects
+
+namespace pointer_to_member_functions {
+// clang-format off
+ template<class Member, class T, class... Args>
+ [[nodiscard]] constexpr bool check_member_is_invocable()
+ {
+ constexpr bool result = std::invocable<Member, T, Args...>;
+ using uncv_t = std::remove_cvref_t<T>;
+ static_assert(std::invocable<Member, uncv_t*, Args...> == result);
+ static_assert(std::invocable<Member, std::unique_ptr<uncv_t>, Args...> == result);
+ static_assert(std::invocable<Member, std::reference_wrapper<uncv_t>, Args...> == result);
+ static_assert(!std::invocable<Member, std::nullptr_t, Args...>);
+ static_assert(!std::invocable<Member, int, Args...>);
+ static_assert(!std::invocable<Member, int*, Args...>);
+ static_assert(!std::invocable<Member, double*, Args...>);
+ struct S2 {};
+ static_assert(!std::invocable<Member, S2*, Args...>);
+ return result;
+ }
+// clang-format on
+
+static_assert(check_member_is_invocable<int S::*, S>());
+static_assert(std::invocable<int S::*, S&>);
+static_assert(std::invocable<int S::*, S const&>);
+static_assert(std::invocable<int S::*, S volatile&>);
+static_assert(std::invocable<int S::*, S const volatile&>);
+static_assert(std::invocable<int S::*, S&&>);
+static_assert(std::invocable<int S::*, S const&&>);
+static_assert(std::invocable<int S::*, S volatile&&>);
+static_assert(std::invocable<int S::*, S const volatile&&>);
+
+static_assert(check_member_is_invocable<int (S::*)(int), S, int>());
+static_assert(!check_member_is_invocable<int (S::*)(int), S>());
+using unqualified = void (S::*)();
+static_assert(std::invocable<unqualified, S&>);
+static_assert(!std::invocable<unqualified, S const&>);
+static_assert(!std::invocable<unqualified, S volatile&>);
+static_assert(!std::invocable<unqualified, S const volatile&>);
+static_assert(std::invocable<unqualified, S&&>);
+static_assert(!std::invocable<unqualified, S const&&>);
+static_assert(!std::invocable<unqualified, S volatile&&>);
+static_assert(!std::invocable<unqualified, S const volatile&&>);
+
+static_assert(check_member_is_invocable<int (S::*)(double) const, S, double>());
+using const_qualified = void (S::*)() const;
+static_assert(std::invocable<const_qualified, S&>);
+static_assert(std::invocable<const_qualified, S const&>);
+static_assert(!std::invocable<const_qualified, S volatile&>);
+static_assert(!std::invocable<const_qualified, S const volatile&>);
+static_assert(std::invocable<const_qualified, S&&>);
+static_assert(std::invocable<const_qualified, S const&&>);
+static_assert(!std::invocable<const_qualified, S volatile&&>);
+static_assert(!std::invocable<const_qualified, S const volatile&&>);
+
+static_assert(
+ check_member_is_invocable<int (S::*)(double[]) volatile, S, double*>());
+using volatile_qualified = void (S::*)() volatile;
+static_assert(std::invocable<volatile_qualified, S&>);
+static_assert(!std::invocable<volatile_qualified, S const&>);
+static_assert(std::invocable<volatile_qualified, S volatile&>);
+static_assert(!std::invocable<volatile_qualified, S const volatile&>);
+static_assert(std::invocable<volatile_qualified, S&&>);
+static_assert(!std::invocable<volatile_qualified, S const&&>);
+static_assert(std::invocable<volatile_qualified, S volatile&&>);
+static_assert(!std::invocable<volatile_qualified, S const volatile&&>);
+
+static_assert(check_member_is_invocable<int (S::*)(int, S&) const volatile, S,
+ int, S&>());
+using cv_qualified = void (S::*)() const volatile;
+static_assert(std::invocable<cv_qualified, S&>);
+static_assert(std::invocable<cv_qualified, S const&>);
+static_assert(std::invocable<cv_qualified, S volatile&>);
+static_assert(std::invocable<cv_qualified, S const volatile&>);
+static_assert(std::invocable<cv_qualified, S&&>);
+static_assert(std::invocable<cv_qualified, S const&&>);
+static_assert(std::invocable<cv_qualified, S volatile&&>);
+static_assert(std::invocable<cv_qualified, S const volatile&&>);
+
+static_assert(check_member_is_invocable<int (S::*)() &, S&>());
+using lvalue_qualified = void (S::*)() &;
+static_assert(std::invocable<lvalue_qualified, S&>);
+static_assert(!std::invocable<lvalue_qualified, S const&>);
+static_assert(!std::invocable<lvalue_qualified, S volatile&>);
+static_assert(!std::invocable<lvalue_qualified, S const volatile&>);
+static_assert(!std::invocable<lvalue_qualified, S&&>);
+static_assert(!std::invocable<lvalue_qualified, S const&&>);
+static_assert(!std::invocable<lvalue_qualified, S volatile&&>);
+static_assert(!std::invocable<lvalue_qualified, S const volatile&&>);
+
+static_assert(check_member_is_invocable<int (S::*)() const&, S>());
+using lvalue_const_qualified = void (S::*)() const&;
+static_assert(std::invocable<lvalue_const_qualified, S&>);
+static_assert(std::invocable<lvalue_const_qualified, S const&>);
+static_assert(!std::invocable<lvalue_const_qualified, S volatile&>);
+static_assert(!std::invocable<lvalue_const_qualified, S const volatile&>);
+static_assert(std::invocable<lvalue_const_qualified, S&&>);
+static_assert(std::invocable<lvalue_const_qualified, S const&&>);
+static_assert(!std::invocable<lvalue_const_qualified, S volatile&&>);
+static_assert(!std::invocable<lvalue_const_qualified, S const volatile&&>);
+
+static_assert(check_member_is_invocable<int (S::*)() volatile&, S&>());
+using lvalue_volatile_qualified = void (S::*)() volatile&;
+static_assert(std::invocable<lvalue_volatile_qualified, S&>);
+static_assert(!std::invocable<lvalue_volatile_qualified, S const&>);
+static_assert(std::invocable<lvalue_volatile_qualified, S volatile&>);
+static_assert(!std::invocable<lvalue_volatile_qualified, S const volatile&>);
+static_assert(!std::invocable<lvalue_volatile_qualified, S&&>);
+static_assert(!std::invocable<lvalue_volatile_qualified, S const&&>);
+static_assert(!std::invocable<lvalue_volatile_qualified, S volatile&&>);
+static_assert(!std::invocable<lvalue_volatile_qualified, S const volatile&&>);
+
+static_assert(check_member_is_invocable<int (S::*)() const volatile&, S&>());
+using lvalue_cv_qualified = void (S::*)() const volatile&;
+static_assert(std::invocable<lvalue_cv_qualified, S&>);
+static_assert(std::invocable<lvalue_cv_qualified, S const&>);
+static_assert(std::invocable<lvalue_cv_qualified, S volatile&>);
+static_assert(std::invocable<lvalue_cv_qualified, S const volatile&>);
+static_assert(!std::invocable<lvalue_cv_qualified, S&&>);
+static_assert(!std::invocable<lvalue_cv_qualified, S const&&>);
+static_assert(!std::invocable<lvalue_cv_qualified, S volatile&&>);
+static_assert(!std::invocable<lvalue_cv_qualified, S const volatile&&>);
+
+using rvalue_unqualified = void (S::*)() &&;
+static_assert(!std::invocable<rvalue_unqualified, S&>);
+static_assert(!std::invocable<rvalue_unqualified, S const&>);
+static_assert(!std::invocable<rvalue_unqualified, S volatile&>);
+static_assert(!std::invocable<rvalue_unqualified, S const volatile&>);
+static_assert(std::invocable<rvalue_unqualified, S&&>);
+static_assert(!std::invocable<rvalue_unqualified, S const&&>);
+static_assert(!std::invocable<rvalue_unqualified, S volatile&&>);
+static_assert(!std::invocable<rvalue_unqualified, S const volatile&&>);
+
+using rvalue_const_unqualified = void (S::*)() const&&;
+static_assert(!std::invocable<rvalue_const_unqualified, S&>);
+static_assert(!std::invocable<rvalue_const_unqualified, S const&>);
+static_assert(!std::invocable<rvalue_const_unqualified, S volatile&>);
+static_assert(!std::invocable<rvalue_const_unqualified, S const volatile&>);
+static_assert(std::invocable<rvalue_const_unqualified, S&&>);
+static_assert(std::invocable<rvalue_const_unqualified, S const&&>);
+static_assert(!std::invocable<rvalue_const_unqualified, S volatile&&>);
+static_assert(!std::invocable<rvalue_const_unqualified, S const volatile&&>);
+
+using rvalue_volatile_unqualified = void (S::*)() volatile&&;
+static_assert(!std::invocable<rvalue_volatile_unqualified, S&>);
+static_assert(!std::invocable<rvalue_volatile_unqualified, S const&>);
+static_assert(!std::invocable<rvalue_volatile_unqualified, S volatile&>);
+static_assert(!std::invocable<rvalue_volatile_unqualified, S const volatile&>);
+static_assert(std::invocable<rvalue_volatile_unqualified, S&&>);
+static_assert(!std::invocable<rvalue_volatile_unqualified, S const&&>);
+static_assert(std::invocable<rvalue_volatile_unqualified, S volatile&&>);
+static_assert(!std::invocable<rvalue_volatile_unqualified, S const volatile&&>);
+
+using rvalue_cv_unqualified = void (S::*)() const volatile&&;
+static_assert(!std::invocable<rvalue_cv_unqualified, S&>);
+static_assert(!std::invocable<rvalue_cv_unqualified, S const&>);
+static_assert(!std::invocable<rvalue_cv_unqualified, S volatile&>);
+static_assert(!std::invocable<rvalue_cv_unqualified, S const volatile&>);
+static_assert(std::invocable<rvalue_cv_unqualified, S&&>);
+static_assert(std::invocable<rvalue_cv_unqualified, S const&&>);
+static_assert(std::invocable<rvalue_cv_unqualified, S volatile&&>);
+static_assert(std::invocable<rvalue_cv_unqualified, S const volatile&&>);
+} // namespace pointer_to_member_functions
+
+// std::invocable-specific
+static_assert(
+ std::invocable<std::uniform_int_distribution<>, std::mt19937_64&>);
+
+[[nodiscard]] constexpr bool check_lambda(auto, auto...) { return false; }
+
+// clang-format off
+template<class F, class... Args>
+requires std::invocable<F, Args...>
+[[nodiscard]] constexpr bool check_lambda(F, Args&&...)
+{
+ return true;
+}
+// clang-format on
+
+[[nodiscard]] constexpr bool check_lambdas() {
+ static_assert(check_lambda([] {}));
+ static_assert(check_lambda([](int) {}, 0));
+ static_assert(check_lambda([](int) {}, 0L));
+ static_assert(!check_lambda([](int) {}, nullptr));
+
+ int i = 0;
+ return check_lambda([](int&) {}, i);
+}
+
+static_assert(check_lambdas());
+
+int main(int, char**) { return 0; }
diff --git a/libcxx/test/std/concepts/concepts.callable/concept.predicate/predicate.compile.pass.cpp b/libcxx/test/std/concepts/concepts.callable/concept.predicate/predicate.compile.pass.cpp
new file mode 100644
index 000000000000..5ad5985d8fa4
--- /dev/null
+++ b/libcxx/test/std/concepts/concepts.callable/concept.predicate/predicate.compile.pass.cpp
@@ -0,0 +1,63 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 F, class... Args>
+// concept predicate;
+
+#include <concepts>
+
+static_assert(std::predicate<bool()>);
+static_assert(std::predicate<bool (*)()>);
+static_assert(std::predicate<bool (&)()>);
+
+static_assert(!std::predicate<void()>);
+static_assert(!std::predicate<void (*)()>);
+static_assert(!std::predicate<void (&)()>);
+
+struct S {};
+
+static_assert(!std::predicate<S(int), int>);
+static_assert(!std::predicate<S(double), double>);
+static_assert(std::predicate<int S::*, S*>);
+static_assert(std::predicate<int (S::*)(), S*>);
+static_assert(std::predicate<int (S::*)(), S&>);
+static_assert(!std::predicate<void (S::*)(), S*>);
+static_assert(!std::predicate<void (S::*)(), S&>);
+
+static_assert(!std::predicate<bool(S)>);
+static_assert(!std::predicate<bool(S&), S>);
+static_assert(!std::predicate<bool(S&), S const&>);
+static_assert(std::predicate<bool(S&), S&>);
+
+struct Predicate {
+ bool operator()(int, double, char);
+};
+static_assert(std::predicate<Predicate, int, double, char>);
+static_assert(std::predicate<Predicate&, int, double, char>);
+static_assert(!std::predicate<const Predicate, int, double, char>);
+static_assert(!std::predicate<const Predicate&, int, double, char>);
+
+[[nodiscard]] constexpr bool check_lambda(auto) { return false; }
+
+[[nodiscard]] constexpr bool check_lambda(std::predicate auto) { return true; }
+
+static_assert(check_lambda([] { return std::true_type(); }));
+static_assert(check_lambda([]() -> int* { return nullptr; }));
+
+struct boolean {
+ operator bool() const noexcept;
+};
+static_assert(check_lambda([] { return boolean(); }));
+
+struct explicit_bool {
+ explicit operator bool() const noexcept;
+};
+static_assert(!check_lambda([] { return explicit_bool(); }));
diff --git a/libcxx/test/std/concepts/concepts.callable/concept.predicate/predicate.pass.cpp b/libcxx/test/std/concepts/concepts.callable/concept.predicate/predicate.pass.cpp
new file mode 100644
index 000000000000..111f89cd1614
--- /dev/null
+++ b/libcxx/test/std/concepts/concepts.callable/concept.predicate/predicate.pass.cpp
@@ -0,0 +1,65 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 F, class... Args>
+// concept predicate;
+
+#include <concepts>
+
+static_assert(std::predicate<bool()>);
+static_assert(std::predicate<bool (*)()>);
+static_assert(std::predicate<bool (&)()>);
+
+static_assert(!std::predicate<void()>);
+static_assert(!std::predicate<void (*)()>);
+static_assert(!std::predicate<void (&)()>);
+
+struct S {};
+
+static_assert(!std::predicate<S(int), int>);
+static_assert(!std::predicate<S(double), double>);
+static_assert(std::predicate<int S::*, S*>);
+static_assert(std::predicate<int (S::*)(), S*>);
+static_assert(std::predicate<int (S::*)(), S&>);
+static_assert(!std::predicate<void (S::*)(), S*>);
+static_assert(!std::predicate<void (S::*)(), S&>);
+
+static_assert(!std::predicate<bool(S)>);
+static_assert(!std::predicate<bool(S&), S>);
+static_assert(!std::predicate<bool(S&), S const&>);
+static_assert(std::predicate<bool(S&), S&>);
+
+struct Predicate {
+ bool operator()(int, double, char);
+};
+static_assert(std::predicate<Predicate, int, double, char>);
+static_assert(std::predicate<Predicate&, int, double, char>);
+static_assert(!std::predicate<const Predicate, int, double, char>);
+static_assert(!std::predicate<const Predicate&, int, double, char>);
+
+[[nodiscard]] constexpr bool check_lambda(auto) { return false; }
+
+[[nodiscard]] constexpr bool check_lambda(std::predicate auto) { return true; }
+
+static_assert(check_lambda([] { return std::true_type(); }));
+static_assert(check_lambda([]() -> int* { return nullptr; }));
+
+struct boolean {
+ operator bool() const noexcept;
+};
+static_assert(check_lambda([] { return boolean(); }));
+
+struct explicit_bool {
+ explicit operator bool() const noexcept;
+};
+static_assert(!check_lambda([] { return explicit_bool(); }));
+
+int main(int, char**) { return 0; }
diff --git a/libcxx/test/std/concepts/concepts.callable/concept.predicate/predicate.subsumption.compile.pass.cpp b/libcxx/test/std/concepts/concepts.callable/concept.predicate/predicate.subsumption.compile.pass.cpp
new file mode 100644
index 000000000000..3ac652626edf
--- /dev/null
+++ b/libcxx/test/std/concepts/concepts.callable/concept.predicate/predicate.subsumption.compile.pass.cpp
@@ -0,0 +1,31 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 F, class... Args>
+// concept predicate;
+
+#include <concepts>
+
+[[nodiscard]] constexpr bool check_subsumption(std::regular_invocable auto) {
+ return false;
+}
+
+// clang-format off
+template<class F>
+requires std::predicate<F> && true
+[[nodiscard]] constexpr bool check_subsumption(F)
+{
+ return true;
+}
+// clang-format on
+
+static_assert(!check_subsumption([] {}));
+static_assert(check_subsumption([] { return true; }));
diff --git a/libcxx/test/std/concepts/concepts.callable/concept.predicate/predicate.subsumption.pass.cpp b/libcxx/test/std/concepts/concepts.callable/concept.predicate/predicate.subsumption.pass.cpp
new file mode 100644
index 000000000000..86c79f008ad6
--- /dev/null
+++ b/libcxx/test/std/concepts/concepts.callable/concept.predicate/predicate.subsumption.pass.cpp
@@ -0,0 +1,33 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 F, class... Args>
+// concept predicate;
+
+#include <concepts>
+
+[[nodiscard]] constexpr bool check_subsumption(std::regular_invocable auto) {
+ return false;
+}
+
+// clang-format off
+template<class F>
+requires std::predicate<F> && true
+[[nodiscard]] constexpr bool check_subsumption(F)
+{
+ return true;
+}
+// clang-format on
+
+static_assert(!check_subsumption([] {}));
+static_assert(check_subsumption([] { return true; }));
+
+int main(int, char**) { return 0; }
diff --git a/libcxx/test/std/concepts/concepts.callable/concept.regularinvocable/regular_invocable.pass.cpp b/libcxx/test/std/concepts/concepts.callable/concept.regularinvocable/regular_invocable.pass.cpp
new file mode 100644
index 000000000000..0e0570f1c14a
--- /dev/null
+++ b/libcxx/test/std/concepts/concepts.callable/concept.regularinvocable/regular_invocable.pass.cpp
@@ -0,0 +1,469 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 regular_invocable;
+
+#include <chrono>
+#include <concepts>
+#include <memory>
+#include <random>
+#include <type_traits>
+
+template <class R, class... Args>
+[[nodiscard]] constexpr bool check_invocable() {
+ constexpr bool result = std::regular_invocable<R(Args...), Args...>;
+ static_assert(std::regular_invocable<R(Args...) noexcept, Args...> == result);
+ static_assert(std::regular_invocable<R (*)(Args...), Args...> == result);
+ static_assert(std::regular_invocable<R (*)(Args...) noexcept, Args...> ==
+ result);
+ static_assert(std::regular_invocable<R (&)(Args...), Args...> == result);
+ static_assert(std::regular_invocable<R (&)(Args...) noexcept, Args...> ==
+ result);
+
+ return result;
+}
+
+static_assert(check_invocable<void>());
+static_assert(check_invocable<void, int>());
+static_assert(check_invocable<void, int&>());
+static_assert(check_invocable<void, int*, double>());
+static_assert(check_invocable<int>());
+static_assert(check_invocable<int, int[]>());
+
+struct S;
+static_assert(check_invocable<int, int S::*, std::nullptr_t>());
+static_assert(check_invocable<int, int (S::*)(), int (S::*)(int), int>());
+static_assert(std::regular_invocable<void (*)(int const&), int&>);
+static_assert(std::regular_invocable<void (*)(int const&), int&&>);
+static_assert(std::regular_invocable<void (*)(int volatile&), int&>);
+static_assert(std::regular_invocable<void (*)(int const volatile&), int&>);
+
+static_assert(!std::regular_invocable<void(), int>);
+static_assert(!std::regular_invocable<void(int)>);
+static_assert(!std::regular_invocable<void(int*), double*>);
+static_assert(!std::regular_invocable<void (*)(int&), double*>);
+static_assert(std::regular_invocable<int S::*, std::unique_ptr<S> >);
+static_assert(std::regular_invocable<int S::*, std::shared_ptr<S> >);
+static_assert(!std::regular_invocable<void (*)(int&&), int&>);
+static_assert(!std::regular_invocable<void (*)(int&&), int const&>);
+
+static_assert(!std::regular_invocable<void>);
+static_assert(!std::regular_invocable<void*>);
+static_assert(!std::regular_invocable<int>);
+static_assert(!std::regular_invocable<int&>);
+static_assert(!std::regular_invocable<int&&>);
+
+namespace function_objects {
+struct function_object {
+ void operator()();
+};
+static_assert(std::regular_invocable<function_object>);
+static_assert(!std::regular_invocable<function_object const>);
+static_assert(!std::regular_invocable<function_object volatile>);
+static_assert(!std::regular_invocable<function_object const volatile>);
+static_assert(std::regular_invocable<function_object&>);
+static_assert(!std::regular_invocable<function_object const&>);
+static_assert(!std::regular_invocable<function_object volatile&>);
+static_assert(!std::regular_invocable<function_object const volatile&>);
+
+struct const_function_object {
+ void operator()(int) const;
+};
+static_assert(std::regular_invocable<const_function_object, int>);
+static_assert(std::regular_invocable<const_function_object const, int>);
+static_assert(!std::regular_invocable<const_function_object volatile, int>);
+static_assert(
+ !std::regular_invocable<const_function_object const volatile, int>);
+static_assert(std::regular_invocable<const_function_object&, int>);
+static_assert(std::regular_invocable<const_function_object const&, int>);
+static_assert(!std::regular_invocable<const_function_object volatile&, int>);
+static_assert(
+ !std::regular_invocable<const_function_object const volatile&, int>);
+
+struct volatile_function_object {
+ void operator()(int, int) volatile;
+};
+static_assert(std::regular_invocable<volatile_function_object, int, int>);
+static_assert(
+ !std::regular_invocable<volatile_function_object const, int, int>);
+static_assert(
+ std::regular_invocable<volatile_function_object volatile, int, int>);
+static_assert(
+ !std::regular_invocable<volatile_function_object const volatile, int, int>);
+static_assert(std::regular_invocable<volatile_function_object&, int, int>);
+static_assert(
+ !std::regular_invocable<volatile_function_object const&, int, int>);
+static_assert(
+ std::regular_invocable<volatile_function_object volatile&, int, int>);
+static_assert(!std::regular_invocable<volatile_function_object const volatile&,
+ int, int>);
+
+struct cv_function_object {
+ void operator()(int[]) const volatile;
+};
+static_assert(std::regular_invocable<cv_function_object, int*>);
+static_assert(std::regular_invocable<cv_function_object const, int*>);
+static_assert(std::regular_invocable<cv_function_object volatile, int*>);
+static_assert(std::regular_invocable<cv_function_object const volatile, int*>);
+static_assert(std::regular_invocable<cv_function_object&, int*>);
+static_assert(std::regular_invocable<cv_function_object const&, int*>);
+static_assert(std::regular_invocable<cv_function_object volatile&, int*>);
+static_assert(std::regular_invocable<cv_function_object const volatile&, int*>);
+
+struct lvalue_function_object {
+ void operator()() &;
+};
+static_assert(!std::regular_invocable<lvalue_function_object>);
+static_assert(!std::regular_invocable<lvalue_function_object const>);
+static_assert(!std::regular_invocable<lvalue_function_object volatile>);
+static_assert(!std::regular_invocable<lvalue_function_object const volatile>);
+static_assert(std::regular_invocable<lvalue_function_object&>);
+static_assert(!std::regular_invocable<lvalue_function_object const&>);
+static_assert(!std::regular_invocable<lvalue_function_object volatile&>);
+static_assert(!std::regular_invocable<lvalue_function_object const volatile&>);
+
+struct lvalue_const_function_object {
+ void operator()(int) const&;
+};
+static_assert(std::regular_invocable<lvalue_const_function_object, int>);
+static_assert(std::regular_invocable<lvalue_const_function_object const, int>);
+static_assert(
+ !std::regular_invocable<lvalue_const_function_object volatile, int>);
+static_assert(
+ !std::regular_invocable<lvalue_const_function_object const volatile, int>);
+static_assert(std::regular_invocable<lvalue_const_function_object&, int>);
+static_assert(std::regular_invocable<lvalue_const_function_object const&, int>);
+static_assert(
+ !std::regular_invocable<lvalue_const_function_object volatile&, int>);
+static_assert(
+ !std::regular_invocable<lvalue_const_function_object const volatile&, int>);
+
+struct lvalue_volatile_function_object {
+ void operator()(int, int) volatile&;
+};
+static_assert(
+ !std::regular_invocable<lvalue_volatile_function_object, int, int>);
+static_assert(
+ !std::regular_invocable<lvalue_volatile_function_object const, int, int>);
+static_assert(!std::regular_invocable<lvalue_volatile_function_object volatile,
+ int, int>);
+static_assert(!std::regular_invocable<
+ lvalue_volatile_function_object const volatile, int, int>);
+static_assert(
+ std::regular_invocable<lvalue_volatile_function_object&, int, int>);
+static_assert(
+ !std::regular_invocable<lvalue_volatile_function_object const&, int, int>);
+static_assert(std::regular_invocable<lvalue_volatile_function_object volatile&,
+ int, int>);
+static_assert(!std::regular_invocable<
+ lvalue_volatile_function_object const volatile&, int, int>);
+
+struct lvalue_cv_function_object {
+ void operator()(int[]) const volatile&;
+};
+static_assert(!std::regular_invocable<lvalue_cv_function_object, int*>);
+static_assert(!std::regular_invocable<lvalue_cv_function_object const, int*>);
+static_assert(
+ !std::regular_invocable<lvalue_cv_function_object volatile, int*>);
+static_assert(
+ !std::regular_invocable<lvalue_cv_function_object const volatile, int*>);
+static_assert(std::regular_invocable<lvalue_cv_function_object&, int*>);
+static_assert(std::regular_invocable<lvalue_cv_function_object const&, int*>);
+static_assert(
+ std::regular_invocable<lvalue_cv_function_object volatile&, int*>);
+static_assert(
+ std::regular_invocable<lvalue_cv_function_object const volatile&, int*>);
+//
+struct rvalue_function_object {
+ void operator()() &&;
+};
+static_assert(std::regular_invocable<rvalue_function_object>);
+static_assert(!std::regular_invocable<rvalue_function_object const>);
+static_assert(!std::regular_invocable<rvalue_function_object volatile>);
+static_assert(!std::regular_invocable<rvalue_function_object const volatile>);
+static_assert(!std::regular_invocable<rvalue_function_object&>);
+static_assert(!std::regular_invocable<rvalue_function_object const&>);
+static_assert(!std::regular_invocable<rvalue_function_object volatile&>);
+static_assert(!std::regular_invocable<rvalue_function_object const volatile&>);
+
+struct rvalue_const_function_object {
+ void operator()(int) const&&;
+};
+static_assert(std::regular_invocable<rvalue_const_function_object, int>);
+static_assert(std::regular_invocable<rvalue_const_function_object const, int>);
+static_assert(
+ !std::regular_invocable<rvalue_const_function_object volatile, int>);
+static_assert(
+ !std::regular_invocable<rvalue_const_function_object const volatile, int>);
+static_assert(!std::regular_invocable<rvalue_const_function_object&, int>);
+static_assert(
+ !std::regular_invocable<rvalue_const_function_object const&, int>);
+static_assert(
+ !std::regular_invocable<rvalue_const_function_object volatile&, int>);
+static_assert(
+ !std::regular_invocable<rvalue_const_function_object const volatile&, int>);
+
+struct rvalue_volatile_function_object {
+ void operator()(int, int) volatile&&;
+};
+static_assert(
+ std::regular_invocable<rvalue_volatile_function_object, int, int>);
+static_assert(
+ !std::regular_invocable<rvalue_volatile_function_object const, int, int>);
+static_assert(
+ std::regular_invocable<rvalue_volatile_function_object volatile, int, int>);
+static_assert(!std::regular_invocable<
+ rvalue_volatile_function_object const volatile, int, int>);
+static_assert(
+ !std::regular_invocable<rvalue_volatile_function_object&, int, int>);
+static_assert(
+ !std::regular_invocable<rvalue_volatile_function_object const&, int, int>);
+static_assert(!std::regular_invocable<rvalue_volatile_function_object volatile&,
+ int, int>);
+static_assert(!std::regular_invocable<
+ rvalue_volatile_function_object const volatile&, int, int>);
+
+struct rvalue_cv_function_object {
+ void operator()(int[]) const volatile&&;
+};
+static_assert(std::regular_invocable<rvalue_cv_function_object, int*>);
+static_assert(std::regular_invocable<rvalue_cv_function_object const, int*>);
+static_assert(std::regular_invocable<rvalue_cv_function_object volatile, int*>);
+static_assert(
+ std::regular_invocable<rvalue_cv_function_object const volatile, int*>);
+static_assert(!std::regular_invocable<rvalue_cv_function_object&, int*>);
+static_assert(!std::regular_invocable<rvalue_cv_function_object const&, int*>);
+static_assert(
+ !std::regular_invocable<rvalue_cv_function_object volatile&, int*>);
+static_assert(
+ !std::regular_invocable<rvalue_cv_function_object const volatile&, int*>);
+
+struct multiple_overloads {
+ struct A {};
+ struct B { B(int); };
+ struct AB : A, B {};
+ struct O {};
+ void operator()(A) const;
+ void operator()(B) const;
+};
+static_assert(std::regular_invocable<multiple_overloads, multiple_overloads::A>);
+static_assert(std::regular_invocable<multiple_overloads, multiple_overloads::B>);
+static_assert(std::regular_invocable<multiple_overloads, int>);
+static_assert(!std::regular_invocable<multiple_overloads, multiple_overloads::AB>);
+static_assert(!std::regular_invocable<multiple_overloads, multiple_overloads::O>);
+} // namespace function_objects
+
+namespace pointer_to_member_functions {
+// clang-format off
+ template<class Member, class T, class... Args>
+ [[nodiscard]] constexpr bool check_member_is_invocable()
+ {
+ constexpr bool result = std::regular_invocable<Member, T, Args...>;
+ using uncv_t = std::remove_cvref_t<T>;
+ static_assert(std::regular_invocable<Member, uncv_t*, Args...> == result);
+ static_assert(std::regular_invocable<Member, std::unique_ptr<uncv_t>, Args...> == result);
+ static_assert(std::regular_invocable<Member, std::reference_wrapper<uncv_t>, Args...> == result);
+ static_assert(!std::regular_invocable<Member, std::nullptr_t, Args...>);
+ static_assert(!std::regular_invocable<Member, int, Args...>);
+ static_assert(!std::regular_invocable<Member, int*, Args...>);
+ static_assert(!std::regular_invocable<Member, double*, Args...>);
+ struct S2 {};
+ static_assert(!std::regular_invocable<Member, S2*, Args...>);
+ return result;
+ }
+// clang-format on
+
+static_assert(check_member_is_invocable<int S::*, S>());
+static_assert(std::regular_invocable<int S::*, S&>);
+static_assert(std::regular_invocable<int S::*, S const&>);
+static_assert(std::regular_invocable<int S::*, S volatile&>);
+static_assert(std::regular_invocable<int S::*, S const volatile&>);
+static_assert(std::regular_invocable<int S::*, S&&>);
+static_assert(std::regular_invocable<int S::*, S const&&>);
+static_assert(std::regular_invocable<int S::*, S volatile&&>);
+static_assert(std::regular_invocable<int S::*, S const volatile&&>);
+
+static_assert(check_member_is_invocable<int (S::*)(int), S, int>());
+static_assert(!check_member_is_invocable<int (S::*)(int), S>());
+using unqualified = void (S::*)();
+static_assert(std::regular_invocable<unqualified, S&>);
+static_assert(!std::regular_invocable<unqualified, S const&>);
+static_assert(!std::regular_invocable<unqualified, S volatile&>);
+static_assert(!std::regular_invocable<unqualified, S const volatile&>);
+static_assert(std::regular_invocable<unqualified, S&&>);
+static_assert(!std::regular_invocable<unqualified, S const&&>);
+static_assert(!std::regular_invocable<unqualified, S volatile&&>);
+static_assert(!std::regular_invocable<unqualified, S const volatile&&>);
+
+static_assert(check_member_is_invocable<int (S::*)(double) const, S, double>());
+using const_qualified = void (S::*)() const;
+static_assert(std::regular_invocable<const_qualified, S&>);
+static_assert(std::regular_invocable<const_qualified, S const&>);
+static_assert(!std::regular_invocable<const_qualified, S volatile&>);
+static_assert(!std::regular_invocable<const_qualified, S const volatile&>);
+static_assert(std::regular_invocable<const_qualified, S&&>);
+static_assert(std::regular_invocable<const_qualified, S const&&>);
+static_assert(!std::regular_invocable<const_qualified, S volatile&&>);
+static_assert(!std::regular_invocable<const_qualified, S const volatile&&>);
+
+static_assert(
+ check_member_is_invocable<int (S::*)(double[]) volatile, S, double*>());
+using volatile_qualified = void (S::*)() volatile;
+static_assert(std::regular_invocable<volatile_qualified, S&>);
+static_assert(!std::regular_invocable<volatile_qualified, S const&>);
+static_assert(std::regular_invocable<volatile_qualified, S volatile&>);
+static_assert(!std::regular_invocable<volatile_qualified, S const volatile&>);
+static_assert(std::regular_invocable<volatile_qualified, S&&>);
+static_assert(!std::regular_invocable<volatile_qualified, S const&&>);
+static_assert(std::regular_invocable<volatile_qualified, S volatile&&>);
+static_assert(!std::regular_invocable<volatile_qualified, S const volatile&&>);
+
+static_assert(check_member_is_invocable<int (S::*)(int, S&) const volatile, S,
+ int, S&>());
+using cv_qualified = void (S::*)() const volatile;
+static_assert(std::regular_invocable<cv_qualified, S&>);
+static_assert(std::regular_invocable<cv_qualified, S const&>);
+static_assert(std::regular_invocable<cv_qualified, S volatile&>);
+static_assert(std::regular_invocable<cv_qualified, S const volatile&>);
+static_assert(std::regular_invocable<cv_qualified, S&&>);
+static_assert(std::regular_invocable<cv_qualified, S const&&>);
+static_assert(std::regular_invocable<cv_qualified, S volatile&&>);
+static_assert(std::regular_invocable<cv_qualified, S const volatile&&>);
+
+static_assert(check_member_is_invocable<int (S::*)() &, S&>());
+using lvalue_qualified = void (S::*)() &;
+static_assert(std::regular_invocable<lvalue_qualified, S&>);
+static_assert(!std::regular_invocable<lvalue_qualified, S const&>);
+static_assert(!std::regular_invocable<lvalue_qualified, S volatile&>);
+static_assert(!std::regular_invocable<lvalue_qualified, S const volatile&>);
+static_assert(!std::regular_invocable<lvalue_qualified, S&&>);
+static_assert(!std::regular_invocable<lvalue_qualified, S const&&>);
+static_assert(!std::regular_invocable<lvalue_qualified, S volatile&&>);
+static_assert(!std::regular_invocable<lvalue_qualified, S const volatile&&>);
+
+static_assert(check_member_is_invocable<int (S::*)() const&, S>());
+using lvalue_const_qualified = void (S::*)() const&;
+static_assert(std::regular_invocable<lvalue_const_qualified, S&>);
+static_assert(std::regular_invocable<lvalue_const_qualified, S const&>);
+static_assert(!std::regular_invocable<lvalue_const_qualified, S volatile&>);
+static_assert(
+ !std::regular_invocable<lvalue_const_qualified, S const volatile&>);
+static_assert(std::regular_invocable<lvalue_const_qualified, S&&>);
+static_assert(std::regular_invocable<lvalue_const_qualified, S const&&>);
+static_assert(!std::regular_invocable<lvalue_const_qualified, S volatile&&>);
+static_assert(
+ !std::regular_invocable<lvalue_const_qualified, S const volatile&&>);
+
+static_assert(check_member_is_invocable<int (S::*)() volatile&, S&>());
+using lvalue_volatile_qualified = void (S::*)() volatile&;
+static_assert(std::regular_invocable<lvalue_volatile_qualified, S&>);
+static_assert(!std::regular_invocable<lvalue_volatile_qualified, S const&>);
+static_assert(std::regular_invocable<lvalue_volatile_qualified, S volatile&>);
+static_assert(
+ !std::regular_invocable<lvalue_volatile_qualified, S const volatile&>);
+static_assert(!std::regular_invocable<lvalue_volatile_qualified, S&&>);
+static_assert(!std::regular_invocable<lvalue_volatile_qualified, S const&&>);
+static_assert(!std::regular_invocable<lvalue_volatile_qualified, S volatile&&>);
+static_assert(
+ !std::regular_invocable<lvalue_volatile_qualified, S const volatile&&>);
+
+static_assert(check_member_is_invocable<int (S::*)() const volatile&, S&>());
+using lvalue_cv_qualified = void (S::*)() const volatile&;
+static_assert(std::regular_invocable<lvalue_cv_qualified, S&>);
+static_assert(std::regular_invocable<lvalue_cv_qualified, S const&>);
+static_assert(std::regular_invocable<lvalue_cv_qualified, S volatile&>);
+static_assert(std::regular_invocable<lvalue_cv_qualified, S const volatile&>);
+static_assert(!std::regular_invocable<lvalue_cv_qualified, S&&>);
+static_assert(!std::regular_invocable<lvalue_cv_qualified, S const&&>);
+static_assert(!std::regular_invocable<lvalue_cv_qualified, S volatile&&>);
+static_assert(!std::regular_invocable<lvalue_cv_qualified, S const volatile&&>);
+
+using rvalue_unqualified = void (S::*)() &&;
+static_assert(!std::regular_invocable<rvalue_unqualified, S&>);
+static_assert(!std::regular_invocable<rvalue_unqualified, S const&>);
+static_assert(!std::regular_invocable<rvalue_unqualified, S volatile&>);
+static_assert(!std::regular_invocable<rvalue_unqualified, S const volatile&>);
+static_assert(std::regular_invocable<rvalue_unqualified, S&&>);
+static_assert(!std::regular_invocable<rvalue_unqualified, S const&&>);
+static_assert(!std::regular_invocable<rvalue_unqualified, S volatile&&>);
+static_assert(!std::regular_invocable<rvalue_unqualified, S const volatile&&>);
+
+using rvalue_const_unqualified = void (S::*)() const&&;
+static_assert(!std::regular_invocable<rvalue_const_unqualified, S&>);
+static_assert(!std::regular_invocable<rvalue_const_unqualified, S const&>);
+static_assert(!std::regular_invocable<rvalue_const_unqualified, S volatile&>);
+static_assert(
+ !std::regular_invocable<rvalue_const_unqualified, S const volatile&>);
+static_assert(std::regular_invocable<rvalue_const_unqualified, S&&>);
+static_assert(std::regular_invocable<rvalue_const_unqualified, S const&&>);
+static_assert(!std::regular_invocable<rvalue_const_unqualified, S volatile&&>);
+static_assert(
+ !std::regular_invocable<rvalue_const_unqualified, S const volatile&&>);
+
+using rvalue_volatile_unqualified = void (S::*)() volatile&&;
+static_assert(!std::regular_invocable<rvalue_volatile_unqualified, S&>);
+static_assert(!std::regular_invocable<rvalue_volatile_unqualified, S const&>);
+static_assert(
+ !std::regular_invocable<rvalue_volatile_unqualified, S volatile&>);
+static_assert(
+ !std::regular_invocable<rvalue_volatile_unqualified, S const volatile&>);
+static_assert(std::regular_invocable<rvalue_volatile_unqualified, S&&>);
+static_assert(!std::regular_invocable<rvalue_volatile_unqualified, S const&&>);
+static_assert(
+ std::regular_invocable<rvalue_volatile_unqualified, S volatile&&>);
+static_assert(
+ !std::regular_invocable<rvalue_volatile_unqualified, S const volatile&&>);
+
+using rvalue_cv_unqualified = void (S::*)() const volatile&&;
+static_assert(!std::regular_invocable<rvalue_cv_unqualified, S&>);
+static_assert(!std::regular_invocable<rvalue_cv_unqualified, S const&>);
+static_assert(!std::regular_invocable<rvalue_cv_unqualified, S volatile&>);
+static_assert(
+ !std::regular_invocable<rvalue_cv_unqualified, S const volatile&>);
+static_assert(std::regular_invocable<rvalue_cv_unqualified, S&&>);
+static_assert(std::regular_invocable<rvalue_cv_unqualified, S const&&>);
+static_assert(std::regular_invocable<rvalue_cv_unqualified, S volatile&&>);
+static_assert(
+ std::regular_invocable<rvalue_cv_unqualified, S const volatile&&>);
+} // namespace pointer_to_member_functions
+
+[[nodiscard]] constexpr bool check_lambda(auto, auto...) { return false; }
+
+// clang-format off
+template<class F, class... Args>
+requires std::invocable<F, Args...>
+[[nodiscard]] constexpr bool check_lambda(F, Args&&...)
+{
+ return false;
+}
+
+template<class F, class... Args>
+requires std::regular_invocable<F, Args...> && true
+[[nodiscard]] constexpr bool check_lambda(F, Args&&...)
+{
+ return true;
+}
+// clang-format on
+
+[[nodiscard]] constexpr bool check_lambdas() {
+ static_assert(check_lambda([] {}));
+ static_assert(check_lambda([](int) {}, 0));
+ static_assert(check_lambda([](int) {}, 0L));
+ static_assert(!check_lambda([](int) {}, nullptr));
+
+ int i = 0;
+ return check_lambda([](int&) {}, i);
+}
+
+static_assert(check_lambdas());
+
+int main(int, char**) { return 0; }
diff --git a/libcxx/test/std/concepts/concepts.callable/concept.relation/relation.compile.pass.cpp b/libcxx/test/std/concepts/concepts.callable/concept.relation/relation.compile.pass.cpp
new file mode 100644
index 000000000000..d647c11cb9f1
--- /dev/null
+++ b/libcxx/test/std/concepts/concepts.callable/concept.relation/relation.compile.pass.cpp
@@ -0,0 +1,57 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 F, class... Args>
+// concept relation;
+
+#include <concepts>
+
+static_assert(std::relation<bool(int, int), int, int>);
+static_assert(std::relation<bool(int, int), double, double>);
+static_assert(std::relation<bool(int, double), double, double>);
+
+static_assert(!std::relation<bool(), int, double>);
+static_assert(!std::relation<bool(int), int, double>);
+static_assert(!std::relation<bool(double), int, double>);
+static_assert(!std::relation<bool(double, double*), double, double*>);
+static_assert(!std::relation<bool(int&, int&), double&, double&>);
+
+struct S1 {};
+static_assert(std::relation<bool (S1::*)(S1*), S1*, S1*>);
+static_assert(std::relation<bool (S1::*)(S1&), S1&, S1&>);
+
+struct S2 {};
+
+struct P1 {
+ bool operator()(S1, S1) const;
+};
+static_assert(std::relation<P1, S1, S1>);
+
+struct P2 {
+ bool operator()(S1, S1) const;
+ bool operator()(S1, S2) const;
+};
+static_assert(!std::relation<P2, S1, S2>);
+
+struct P3 {
+ bool operator()(S1, S1) const;
+ bool operator()(S1, S2) const;
+ bool operator()(S2, S1) const;
+};
+static_assert(!std::relation<P3, S1, S2>);
+
+struct P4 {
+ bool operator()(S1, S1) const;
+ bool operator()(S1, S2) const;
+ bool operator()(S2, S1) const;
+ bool operator()(S2, S2) const;
+};
+static_assert(std::relation<P4, S1, S2>);
diff --git a/libcxx/test/std/concepts/concepts.callable/concept.relation/relation.pass.cpp b/libcxx/test/std/concepts/concepts.callable/concept.relation/relation.pass.cpp
new file mode 100644
index 000000000000..c7617fca9df0
--- /dev/null
+++ b/libcxx/test/std/concepts/concepts.callable/concept.relation/relation.pass.cpp
@@ -0,0 +1,59 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 F, class... Args>
+// concept relation;
+
+#include <concepts>
+
+static_assert(std::relation<bool(int, int), int, int>);
+static_assert(std::relation<bool(int, int), double, double>);
+static_assert(std::relation<bool(int, double), double, double>);
+
+static_assert(!std::relation<bool(), int, double>);
+static_assert(!std::relation<bool(int), int, double>);
+static_assert(!std::relation<bool(double), int, double>);
+static_assert(!std::relation<bool(double, double*), double, double*>);
+static_assert(!std::relation<bool(int&, int&), double&, double&>);
+
+struct S1 {};
+static_assert(std::relation<bool (S1::*)(S1*), S1*, S1*>);
+static_assert(std::relation<bool (S1::*)(S1&), S1&, S1&>);
+
+struct S2 {};
+
+struct P1 {
+ bool operator()(S1, S1) const;
+};
+static_assert(std::relation<P1, S1, S1>);
+
+struct P2 {
+ bool operator()(S1, S1) const;
+ bool operator()(S1, S2) const;
+};
+static_assert(!std::relation<P2, S1, S2>);
+
+struct P3 {
+ bool operator()(S1, S1) const;
+ bool operator()(S1, S2) const;
+ bool operator()(S2, S1) const;
+};
+static_assert(!std::relation<P3, S1, S2>);
+
+struct P4 {
+ bool operator()(S1, S1) const;
+ bool operator()(S1, S2) const;
+ bool operator()(S2, S1) const;
+ bool operator()(S2, S2) const;
+};
+static_assert(std::relation<P4, S1, S2>);
+
+int main(int, char**) { return 0; }
diff --git a/libcxx/test/std/concepts/concepts.callable/concept.relation/relation.subsumption.compile.pass.cpp b/libcxx/test/std/concepts/concepts.callable/concept.relation/relation.subsumption.compile.pass.cpp
new file mode 100644
index 000000000000..f7a45f2b0751
--- /dev/null
+++ b/libcxx/test/std/concepts/concepts.callable/concept.relation/relation.subsumption.compile.pass.cpp
@@ -0,0 +1,64 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 F, class... Args>
+// concept relation;
+
+#include <concepts>
+
+struct S1 {};
+struct S2 {};
+
+struct R {
+ bool operator()(S1, S1) const;
+ bool operator()(S1, S2) const;
+ bool operator()(S2, S1) const;
+ bool operator()(S2, S2) const;
+};
+
+// clang-format off
+template<class F, class T, class U>
+requires std::predicate<F, T, T> && std::predicate<F, T, U> &&
+ std::predicate<F, U, T> && std::predicate<F, U, U>
+[[nodiscard]] constexpr bool check_relation_subsumes_predicate() {
+ return false;
+}
+
+template<class F, class T, class U>
+requires std::relation<F, T, U> && true
+[[nodiscard]] constexpr bool check_relation_subsumes_predicate() {
+ return true;
+}
+// clang-format on
+
+static_assert(
+ check_relation_subsumes_predicate<int (*)(int, double), int, int>());
+static_assert(
+ check_relation_subsumes_predicate<int (*)(int, double), int, double>());
+static_assert(check_relation_subsumes_predicate<R, S1, S1>());
+static_assert(check_relation_subsumes_predicate<R, S1, S2>());
+
+// clang-format off
+template<class F, class T, class U>
+requires std::relation<F, T, T> && std::relation<F, U, U>
+[[nodiscard]] constexpr bool check_relation_subsumes_itself() {
+ return false;
+}
+
+template<class F, class T, class U>
+requires std::relation<F, T, U>
+[[nodiscard]] constexpr bool check_relation_subsumes_itself() {
+ return true;
+}
+// clang-format on
+
+static_assert(check_relation_subsumes_itself<int (*)(int, double), int, int>());
+static_assert(check_relation_subsumes_itself<R, S1, S1>());
diff --git a/libcxx/test/std/concepts/concepts.callable/concept.relation/relation.subsumption.pass.cpp b/libcxx/test/std/concepts/concepts.callable/concept.relation/relation.subsumption.pass.cpp
new file mode 100644
index 000000000000..8568bd5f6ecf
--- /dev/null
+++ b/libcxx/test/std/concepts/concepts.callable/concept.relation/relation.subsumption.pass.cpp
@@ -0,0 +1,41 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+// UNSUPPORTED: libcpp-no-concepts
+
+// template<class F, class... Args>
+// concept relation;
+
+#include <concepts>
+
+// clang-format off
+template<class F, class T, class U>
+requires std::predicate<F, T, T> && std::predicate<F, T, U> &&
+ std::predicate<F, U, T> && std::predicate<F, U, U>
+[[nodiscard]] constexpr bool check_subsumption() { return false; }
+
+template<class F, class T, class U>
+requires std::relation<F, T, U> && true
+[[nodiscard]] constexpr bool check_subsumption() { return true; }
+// clang-format on
+
+static_assert(check_subsumption<int (*)(int, double), int, double>());
+
+struct S1 {};
+struct S2 {};
+
+struct R {
+ bool operator()(S1, S1) const;
+ bool operator()(S1, S2) const;
+ bool operator()(S2, S1) const;
+ bool operator()(S2, S2) const;
+};
+static_assert(check_subsumption<R, S1, S2>());
+
+int main(int, char**) { return 0; }
diff --git a/libcxx/test/std/concepts/concepts.callable/concept.strictweakorder/strict_weak_order.compile.pass.cpp b/libcxx/test/std/concepts/concepts.callable/concept.strictweakorder/strict_weak_order.compile.pass.cpp
new file mode 100644
index 000000000000..08351dc2e770
--- /dev/null
+++ b/libcxx/test/std/concepts/concepts.callable/concept.strictweakorder/strict_weak_order.compile.pass.cpp
@@ -0,0 +1,58 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 F, class... Args>
+// concept strict_weak_order;
+
+#include <concepts>
+
+static_assert(std::strict_weak_order<bool(int, int), int, int>);
+static_assert(std::strict_weak_order<bool(int, int), double, double>);
+static_assert(std::strict_weak_order<bool(int, double), double, double>);
+
+static_assert(!std::strict_weak_order<bool (*)(), int, double>);
+static_assert(!std::strict_weak_order<bool (*)(int), int, double>);
+static_assert(!std::strict_weak_order<bool (*)(double), int, double>);
+
+static_assert(!std::strict_weak_order<bool(double, double*), double, double*>);
+static_assert(!std::strict_weak_order<bool(int&, int&), double&, double&>);
+
+struct S1 {};
+static_assert(std::strict_weak_order<bool (S1::*)(S1*), S1*, S1*>);
+static_assert(std::strict_weak_order<bool (S1::*)(S1&), S1&, S1&>);
+
+struct S2 {};
+
+struct P1 {
+ bool operator()(S1, S1) const;
+};
+static_assert(std::strict_weak_order<P1, S1, S1>);
+
+struct P2 {
+ bool operator()(S1, S1) const;
+ bool operator()(S1, S2) const;
+};
+static_assert(!std::strict_weak_order<P2, S1, S2>);
+
+struct P3 {
+ bool operator()(S1, S1) const;
+ bool operator()(S1, S2) const;
+ bool operator()(S2, S1) const;
+};
+static_assert(!std::strict_weak_order<P3, S1, S2>);
+
+struct P4 {
+ bool operator()(S1, S1) const;
+ bool operator()(S1, S2) const;
+ bool operator()(S2, S1) const;
+ bool operator()(S2, S2) const;
+};
+static_assert(std::strict_weak_order<P4, S1, S2>);
diff --git a/libcxx/test/std/concepts/concepts.callable/concept.strictweakorder/strict_weak_order.pass.cpp b/libcxx/test/std/concepts/concepts.callable/concept.strictweakorder/strict_weak_order.pass.cpp
new file mode 100644
index 000000000000..437dcd2c870a
--- /dev/null
+++ b/libcxx/test/std/concepts/concepts.callable/concept.strictweakorder/strict_weak_order.pass.cpp
@@ -0,0 +1,60 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 F, class... Args>
+// concept strict_weak_order;
+
+#include <concepts>
+
+static_assert(std::strict_weak_order<bool(int, int), int, int>);
+static_assert(std::strict_weak_order<bool(int, int), double, double>);
+static_assert(std::strict_weak_order<bool(int, double), double, double>);
+
+static_assert(!std::strict_weak_order<bool (*)(), int, double>);
+static_assert(!std::strict_weak_order<bool (*)(int), int, double>);
+static_assert(!std::strict_weak_order<bool (*)(double), int, double>);
+
+static_assert(!std::strict_weak_order<bool(double, double*), double, double*>);
+static_assert(!std::strict_weak_order<bool(int&, int&), double&, double&>);
+
+struct S1 {};
+static_assert(std::strict_weak_order<bool (S1::*)(S1*), S1*, S1*>);
+static_assert(std::strict_weak_order<bool (S1::*)(S1&), S1&, S1&>);
+
+struct S2 {};
+
+struct P1 {
+ bool operator()(S1, S1) const;
+};
+static_assert(std::strict_weak_order<P1, S1, S1>);
+
+struct P2 {
+ bool operator()(S1, S1) const;
+ bool operator()(S1, S2) const;
+};
+static_assert(!std::strict_weak_order<P2, S1, S2>);
+
+struct P3 {
+ bool operator()(S1, S1) const;
+ bool operator()(S1, S2) const;
+ bool operator()(S2, S1) const;
+};
+static_assert(!std::strict_weak_order<P3, S1, S2>);
+
+struct P4 {
+ bool operator()(S1, S1) const;
+ bool operator()(S1, S2) const;
+ bool operator()(S2, S1) const;
+ bool operator()(S2, S2) const;
+};
+static_assert(std::strict_weak_order<P4, S1, S2>);
+
+int main(int, char**) { return 0; }
diff --git a/libcxx/test/std/concepts/concepts.callable/concept.strictweakorder/strict_weak_order.subsumption.compile.pass.cpp b/libcxx/test/std/concepts/concepts.callable/concept.strictweakorder/strict_weak_order.subsumption.compile.pass.cpp
new file mode 100644
index 000000000000..34574f649a3f
--- /dev/null
+++ b/libcxx/test/std/concepts/concepts.callable/concept.strictweakorder/strict_weak_order.subsumption.compile.pass.cpp
@@ -0,0 +1,85 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 F, class... Args>
+// concept strict_weak_order;
+
+#include <concepts>
+
+struct S1 {};
+struct S2 {};
+
+struct R {
+ bool operator()(S1, S1) const;
+ bool operator()(S1, S2) const;
+ bool operator()(S2, S1) const;
+ bool operator()(S2, S2) const;
+};
+
+// clang-format off
+template<class F, class T, class U>
+requires std::relation<F, T, U>
+[[nodiscard]] constexpr bool check_strict_weak_order_subsumes_relation() {
+ return false;
+}
+
+template<class F, class T, class U>
+requires std::strict_weak_order<F, T, U> && true
+[[nodiscard]] constexpr bool check_strict_weak_order_subsumes_relation() {
+ return true;
+}
+// clang-format on
+
+static_assert(
+ check_strict_weak_order_subsumes_relation<int (*)(int, int), int, int>());
+static_assert(check_strict_weak_order_subsumes_relation<int (*)(int, double),
+ int, double>());
+static_assert(check_strict_weak_order_subsumes_relation<R, S1, S1>());
+static_assert(check_strict_weak_order_subsumes_relation<R, S1, S2>());
+
+// clang-format off
+template<class F, class T, class U>
+requires std::relation<F, T, U> && true
+[[nodiscard]] constexpr bool check_relation_subsumes_strict_weak_order() {
+ return true;
+}
+
+template<class F, class T, class U>
+requires std::strict_weak_order<F, T, U>
+[[nodiscard]] constexpr bool check_relation_subsumes_strict_weak_order() {
+ return false;
+}
+// clang-format on
+
+static_assert(
+ check_relation_subsumes_strict_weak_order<int (*)(int, int), int, int>());
+static_assert(check_relation_subsumes_strict_weak_order<int (*)(int, double),
+ int, double>());
+static_assert(check_relation_subsumes_strict_weak_order<R, S1, S1>());
+static_assert(check_relation_subsumes_strict_weak_order<R, S1, S2>());
+
+// clang-format off
+template<class F, class T, class U>
+requires std::strict_weak_order<F, T, T> && std::strict_weak_order<F, U, U>
+[[nodiscard]] constexpr bool check_strict_weak_order_subsumes_itself() {
+ return false;
+}
+
+template<class F, class T, class U>
+requires std::strict_weak_order<F, T, U>
+[[nodiscard]] constexpr bool check_strict_weak_order_subsumes_itself() {
+ return true;
+}
+// clang-format on
+
+static_assert(
+ check_strict_weak_order_subsumes_itself<int (*)(int, int), int, int>());
+static_assert(check_strict_weak_order_subsumes_itself<R, S1, S1>());
diff --git a/libcxx/test/std/concepts/concepts.callable/concept.strictweakorder/strict_weak_order.subsumption.pass.cpp b/libcxx/test/std/concepts/concepts.callable/concept.strictweakorder/strict_weak_order.subsumption.pass.cpp
new file mode 100644
index 000000000000..52a19f4f2d8d
--- /dev/null
+++ b/libcxx/test/std/concepts/concepts.callable/concept.strictweakorder/strict_weak_order.subsumption.pass.cpp
@@ -0,0 +1,40 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 F, class... Args>
+// concept strict_weak_order;
+
+#include <concepts>
+
+// clang-format off
+template<class F, class T, class U>
+requires std::relation<F, T, U>
+[[nodiscard]] constexpr bool check_subsumption() { return false; }
+
+template<class F, class T, class U>
+requires std::strict_weak_order<F, T, U> && true
+[[nodiscard]] constexpr bool check_subsumption() { return true; }
+// clang-format on
+
+static_assert(check_subsumption<int (*)(int, double), int, double>());
+
+struct S1 {};
+struct S2 {};
+
+struct R {
+ bool operator()(S1, S1) const;
+ bool operator()(S1, S2) const;
+ bool operator()(S2, S1) const;
+ bool operator()(S2, S2) const;
+};
+static_assert(check_subsumption<R, S1, S2>());
+
+int main(int, char**) { return 0; }
diff --git a/libcxx/test/std/concepts/comparison/concepts.equalitycomparable/equality_comparable.compile.pass.cpp b/libcxx/test/std/concepts/concepts.compare/concept.equalitycomparable/equality_comparable.compile.pass.cpp
index 93f79a80e542..0211ee3d531e 100644
--- a/libcxx/test/std/concepts/comparison/concepts.equalitycomparable/equality_comparable.compile.pass.cpp
+++ b/libcxx/test/std/concepts/concepts.compare/concept.equalitycomparable/equality_comparable.compile.pass.cpp
@@ -112,14 +112,23 @@ 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_different_return_types>);
+static_assert(std::equality_comparable<different_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<no_lt>);
+static_assert(std::equality_comparable<no_gt>);
+static_assert(std::equality_comparable<no_le>);
+static_assert(std::equality_comparable<no_ge>);
+
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_lt>);
+static_assert(std::equality_comparable<wrong_return_type_gt>);
+static_assert(std::equality_comparable<wrong_return_type_le>);
+static_assert(std::equality_comparable<wrong_return_type_ge>);
static_assert(!std::equality_comparable<wrong_return_type>);
static_assert(
!std::equality_comparable<cxx20_member_eq_operator_with_deleted_ne>);
@@ -134,9 +143,13 @@ static_assert(
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<eq_returns_explicit_bool>);
+static_assert(!std::equality_comparable<ne_returns_explicit_bool>);
+static_assert(std::equality_comparable<lt_returns_explicit_bool>);
+static_assert(std::equality_comparable<gt_returns_explicit_bool>);
+static_assert(std::equality_comparable<le_returns_explicit_bool>);
+static_assert(std::equality_comparable<ge_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
diff --git a/libcxx/test/std/concepts/comparison/concepts.equalitycomparable/equality_comparable_with.compile.pass.cpp b/libcxx/test/std/concepts/concepts.compare/concept.equalitycomparable/equality_comparable_with.compile.pass.cpp
index 4bca901dc5f1..a65e47f936da 100644
--- a/libcxx/test/std/concepts/comparison/concepts.equalitycomparable/equality_comparable_with.compile.pass.cpp
+++ b/libcxx/test/std/concepts/concepts.compare/concept.equalitycomparable/equality_comparable_with.compile.pass.cpp
@@ -1097,12 +1097,12 @@ 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_different_return_types,
- eq_neq_different_return_types>());
+static_assert(check_equality_comparable_with<different_return_types,
+ different_return_types>());
static_assert(check_equality_comparable_with<explicit_operators,
equality_comparable_with_ec1>());
static_assert(check_equality_comparable_with<explicit_operators,
- eq_neq_different_return_types>());
+ different_return_types>());
static_assert(check_equality_comparable_with<one_way_eq, one_way_eq>());
static_assert(
diff --git a/libcxx/test/std/concepts/concepts.compare/concepts.totallyordered/totally_ordered.pass.cpp b/libcxx/test/std/concepts/concepts.compare/concepts.totallyordered/totally_ordered.pass.cpp
new file mode 100644
index 000000000000..fce1efc0cd5d
--- /dev/null
+++ b/libcxx/test/std/concepts/concepts.compare/concepts.totallyordered/totally_ordered.pass.cpp
@@ -0,0 +1,175 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 totally_ordered;
+
+#include <concepts>
+
+#include <array>
+#include <deque>
+#include <forward_list>
+#include <list>
+#include <map>
+#include <memory>
+#include <optional>
+#include <set>
+#include <unordered_map>
+#include <unordered_set>
+#include <vector>
+
+#include "../types.h"
+#include "test_macros.h"
+
+// `models_totally_ordered` checks that `std::totally_ordered` subsumes
+// `std::equality_comparable`. This overload should *never* be called.
+template <std::equality_comparable T>
+constexpr bool models_totally_ordered() noexcept {
+ return false;
+}
+
+template <std::totally_ordered T>
+constexpr bool models_totally_ordered() noexcept {
+ return true;
+}
+
+namespace fundamentals {
+static_assert(models_totally_ordered<int>());
+static_assert(models_totally_ordered<double>());
+static_assert(models_totally_ordered<void*>());
+static_assert(models_totally_ordered<char*>());
+static_assert(models_totally_ordered<char const*>());
+static_assert(models_totally_ordered<char volatile*>());
+static_assert(models_totally_ordered<char const volatile*>());
+static_assert(models_totally_ordered<wchar_t&>());
+static_assert(models_totally_ordered<char8_t const&>());
+static_assert(models_totally_ordered<char16_t volatile&>());
+static_assert(models_totally_ordered<char32_t const volatile&>());
+static_assert(models_totally_ordered<unsigned char&&>());
+static_assert(models_totally_ordered<unsigned short const&&>());
+static_assert(models_totally_ordered<unsigned int volatile&&>());
+static_assert(models_totally_ordered<unsigned long const volatile&&>());
+static_assert(models_totally_ordered<int[5]>());
+static_assert(models_totally_ordered<int (*)(int)>());
+static_assert(models_totally_ordered<int (&)(int)>());
+static_assert(models_totally_ordered<int (*)(int) noexcept>());
+static_assert(models_totally_ordered<int (&)(int) noexcept>());
+
+#ifndef TEST_COMPILER_GCC
+static_assert(!std::totally_ordered<std::nullptr_t>);
+#endif
+
+struct S {};
+static_assert(!std::totally_ordered<S>);
+static_assert(!std::totally_ordered<int S::*>);
+static_assert(!std::totally_ordered<int (S::*)()>);
+static_assert(!std::totally_ordered<int (S::*)() noexcept>);
+static_assert(!std::totally_ordered<int (S::*)() &>);
+static_assert(!std::totally_ordered<int (S::*)() & noexcept>);
+static_assert(!std::totally_ordered<int (S::*)() &&>);
+static_assert(!std::totally_ordered < int (S::*)() && noexcept >);
+static_assert(!std::totally_ordered<int (S::*)() const>);
+static_assert(!std::totally_ordered<int (S::*)() const noexcept>);
+static_assert(!std::totally_ordered<int (S::*)() const&>);
+static_assert(!std::totally_ordered<int (S::*)() const & noexcept>);
+static_assert(!std::totally_ordered<int (S::*)() const&&>);
+static_assert(!std::totally_ordered < int (S::*)() const&& noexcept >);
+static_assert(!std::totally_ordered<int (S::*)() volatile>);
+static_assert(!std::totally_ordered<int (S::*)() volatile noexcept>);
+static_assert(!std::totally_ordered<int (S::*)() volatile&>);
+static_assert(!std::totally_ordered<int (S::*)() volatile & noexcept>);
+static_assert(!std::totally_ordered<int (S::*)() volatile&&>);
+static_assert(!std::totally_ordered < int (S::*)() volatile&& noexcept >);
+static_assert(!std::totally_ordered<int (S::*)() const volatile>);
+static_assert(!std::totally_ordered<int (S::*)() const volatile noexcept>);
+static_assert(!std::totally_ordered<int (S::*)() const volatile&>);
+static_assert(!std::totally_ordered<int (S::*)() const volatile & noexcept>);
+static_assert(!std::totally_ordered<int (S::*)() const volatile&&>);
+static_assert(!std::totally_ordered < int (S::*)() const volatile&& noexcept >);
+
+static_assert(!std::totally_ordered<void>);
+} // namespace fundamentals
+
+namespace standard_types {
+static_assert(models_totally_ordered<std::array<int, 10> >());
+static_assert(models_totally_ordered<std::deque<int> >());
+static_assert(models_totally_ordered<std::forward_list<int> >());
+static_assert(models_totally_ordered<std::list<int> >());
+static_assert(models_totally_ordered<std::optional<int> >());
+static_assert(models_totally_ordered<std::set<int> >());
+static_assert(models_totally_ordered<std::vector<bool> >());
+static_assert(models_totally_ordered<std::vector<int> >());
+
+static_assert(!std::totally_ordered<std::unordered_map<int, void*> >);
+static_assert(!std::totally_ordered<std::unordered_set<int> >);
+
+struct A {};
+// FIXME(cjdb): uncomment when operator<=> is implemented for each of these types.
+// static_assert(!std::totally_ordered<std::array<A, 10> >);
+// static_assert(!std::totally_ordered<std::deque<A> >);
+// static_assert(!std::totally_ordered<std::forward_list<A> >);
+// static_assert(!std::totally_ordered<std::list<A> >);
+static_assert(!std::totally_ordered<std::optional<A> >);
+// static_assert(!std::totally_ordered<std::set<A> >);
+// static_assert(!std::totally_ordered<std::vector<A> >);
+} // namespace standard_types
+
+namespace types_fit_for_purpose {
+static_assert(models_totally_ordered<member_three_way_comparable>());
+static_assert(models_totally_ordered<friend_three_way_comparable>());
+static_assert(models_totally_ordered<explicit_operators>());
+static_assert(models_totally_ordered<different_return_types>());
+static_assert(!std::totally_ordered<cxx20_member_eq>);
+static_assert(!std::totally_ordered<cxx20_friend_eq>);
+static_assert(!std::totally_ordered<one_member_one_friend>);
+static_assert(!std::totally_ordered<equality_comparable_with_ec1>);
+
+static_assert(!std::totally_ordered<no_eq>);
+static_assert(!std::totally_ordered<no_neq>);
+static_assert(!std::totally_ordered<no_lt>);
+static_assert(!std::totally_ordered<no_gt>);
+static_assert(!std::totally_ordered<no_le>);
+static_assert(!std::totally_ordered<no_ge>);
+
+static_assert(!std::totally_ordered<wrong_return_type_eq>);
+static_assert(!std::totally_ordered<wrong_return_type_ne>);
+static_assert(!std::totally_ordered<wrong_return_type_lt>);
+static_assert(!std::totally_ordered<wrong_return_type_gt>);
+static_assert(!std::totally_ordered<wrong_return_type_le>);
+static_assert(!std::totally_ordered<wrong_return_type_ge>);
+static_assert(!std::totally_ordered<wrong_return_type>);
+
+static_assert(!std::totally_ordered<cxx20_member_eq_operator_with_deleted_ne>);
+static_assert(!std::totally_ordered<cxx20_friend_eq_operator_with_deleted_ne>);
+static_assert(
+ !std::totally_ordered<member_three_way_comparable_with_deleted_eq>);
+static_assert(
+ !std::totally_ordered<member_three_way_comparable_with_deleted_ne>);
+static_assert(
+ !std::totally_ordered<friend_three_way_comparable_with_deleted_eq>);
+static_assert(
+ !std::totally_ordered<friend_three_way_comparable_with_deleted_ne>);
+
+static_assert(!std::totally_ordered<eq_returns_explicit_bool>);
+static_assert(!std::totally_ordered<ne_returns_explicit_bool>);
+static_assert(!std::totally_ordered<lt_returns_explicit_bool>);
+static_assert(!std::totally_ordered<gt_returns_explicit_bool>);
+static_assert(!std::totally_ordered<le_returns_explicit_bool>);
+static_assert(!std::totally_ordered<ge_returns_explicit_bool>);
+static_assert(std::totally_ordered<returns_true_type>);
+static_assert(std::totally_ordered<returns_int_ptr>);
+
+static_assert(std::totally_ordered<partial_ordering_totally_ordered_with>);
+static_assert(std::totally_ordered<weak_ordering_totally_ordered_with>);
+static_assert(std::totally_ordered<strong_ordering_totally_ordered_with>);
+} // namespace types_fit_for_purpose
+
+int main(int, char**) { return 0; }
diff --git a/libcxx/test/std/concepts/concepts.compare/concepts.totallyordered/totally_ordered_with.pass.cpp b/libcxx/test/std/concepts/concepts.compare/concepts.totallyordered/totally_ordered_with.pass.cpp
new file mode 100644
index 000000000000..345abac552fe
--- /dev/null
+++ b/libcxx/test/std/concepts/concepts.compare/concepts.totallyordered/totally_ordered_with.pass.cpp
@@ -0,0 +1,1142 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 totally_ordered_with;
+
+#include <concepts>
+
+#include <array>
+#include <deque>
+#include <forward_list>
+#include <list>
+#include <map>
+#include <memory>
+#include <optional>
+#include <set>
+#include <unordered_map>
+#include <unordered_set>
+#include <vector>
+
+#include "../types.h"
+#include "test_macros.h"
+
+template <class T, class U>
+constexpr bool check_totally_ordered_with() noexcept {
+ constexpr bool result = std::totally_ordered_with<T, U>;
+ static_assert(std::totally_ordered_with<U, T> == result);
+ static_assert(std::totally_ordered_with<T, U const> == result);
+ static_assert(std::totally_ordered_with<T const, U const> == result);
+ static_assert(std::totally_ordered_with<T, U const&> == result);
+ static_assert(std::totally_ordered_with<T const, U const&> == result);
+ static_assert(std::totally_ordered_with<T&, U const> == result);
+ static_assert(std::totally_ordered_with<T const&, U const> == result);
+ static_assert(std::totally_ordered_with<T&, U const&> == result);
+ static_assert(std::totally_ordered_with<T const&, U const&> == result);
+ static_assert(std::totally_ordered_with<T, U const&&> == result);
+ static_assert(std::totally_ordered_with<T const, U const&&> == result);
+ static_assert(std::totally_ordered_with<T&, U const&&> == result);
+ static_assert(std::totally_ordered_with<T const&, U const&&> == result);
+ static_assert(std::totally_ordered_with<T&&, U const> == result);
+ static_assert(std::totally_ordered_with<T const&&, U const> == result);
+ static_assert(std::totally_ordered_with<T&&, U const&> == result);
+ static_assert(std::totally_ordered_with<T const&&, U const&> == result);
+ static_assert(std::totally_ordered_with<T&&, U const&&> == result);
+ static_assert(std::totally_ordered_with<T const&&, U const&&> == result);
+ return result;
+}
+
+namespace fundamentals {
+static_assert(check_totally_ordered_with<int, int>());
+static_assert(check_totally_ordered_with<int, bool>());
+static_assert(check_totally_ordered_with<int, char>());
+static_assert(check_totally_ordered_with<int, wchar_t>());
+static_assert(check_totally_ordered_with<int, double>());
+static_assert(!check_totally_ordered_with<int, int*>());
+static_assert(!check_totally_ordered_with<int, int[5]>());
+static_assert(!check_totally_ordered_with<int, int (*)()>());
+static_assert(!check_totally_ordered_with<int, int (&)()>());
+
+struct S {};
+static_assert(!check_totally_ordered_with<int, int S::*>());
+static_assert(!check_totally_ordered_with<int, int (S::*)()>());
+static_assert(!check_totally_ordered_with<int, int (S::*)() noexcept>());
+static_assert(!check_totally_ordered_with<int, int (S::*)() const>());
+static_assert(!check_totally_ordered_with<int, int (S::*)() const noexcept>());
+static_assert(!check_totally_ordered_with<int, int (S::*)() volatile>());
+static_assert(
+ !check_totally_ordered_with<int, int (S::*)() volatile noexcept>());
+static_assert(!check_totally_ordered_with<int, int (S::*)() const volatile>());
+static_assert(
+ !check_totally_ordered_with<int, int (S::*)() const volatile noexcept>());
+static_assert(!check_totally_ordered_with<int, int (S::*)() &>());
+static_assert(!check_totally_ordered_with<int, int (S::*)() & noexcept>());
+static_assert(!check_totally_ordered_with<int, int (S::*)() const&>());
+static_assert(
+ !check_totally_ordered_with<int, int (S::*)() const & noexcept>());
+static_assert(!check_totally_ordered_with<int, int (S::*)() volatile&>());
+static_assert(
+ !check_totally_ordered_with<int, int (S::*)() volatile & noexcept>());
+static_assert(!check_totally_ordered_with<int, int (S::*)() const volatile&>());
+static_assert(
+ !check_totally_ordered_with<int, int (S::*)() const volatile & noexcept>());
+static_assert(!check_totally_ordered_with<int, int (S::*)() &&>());
+static_assert(!check_totally_ordered_with < int, int (S::*)() && noexcept > ());
+static_assert(!check_totally_ordered_with<int, int (S::*)() const&&>());
+static_assert(!check_totally_ordered_with < int,
+ int (S::*)() const&& noexcept > ());
+static_assert(!check_totally_ordered_with<int, int (S::*)() volatile&&>());
+static_assert(!check_totally_ordered_with < int,
+ int (S::*)() volatile&& noexcept > ());
+static_assert(
+ !check_totally_ordered_with<int, int (S::*)() const volatile&&>());
+static_assert(!check_totally_ordered_with < int,
+ int (S::*)() const volatile&& noexcept > ());
+
+static_assert(check_totally_ordered_with<int*, int*>());
+static_assert(check_totally_ordered_with<int*, int[5]>());
+static_assert(!check_totally_ordered_with<int*, int (*)()>());
+static_assert(!check_totally_ordered_with<int*, int (&)()>());
+static_assert(!check_totally_ordered_with<int*, int (S::*)()>());
+static_assert(!check_totally_ordered_with<int*, int (S::*)() noexcept>());
+static_assert(!check_totally_ordered_with<int*, int (S::*)() const>());
+static_assert(!check_totally_ordered_with<int*, int (S::*)() const noexcept>());
+static_assert(!check_totally_ordered_with<int*, int (S::*)() volatile>());
+static_assert(
+ !check_totally_ordered_with<int*, int (S::*)() volatile noexcept>());
+static_assert(!check_totally_ordered_with<int*, int (S::*)() const volatile>());
+static_assert(
+ !check_totally_ordered_with<int*, int (S::*)() const volatile noexcept>());
+static_assert(!check_totally_ordered_with<int*, int (S::*)() &>());
+static_assert(!check_totally_ordered_with<int*, int (S::*)() & noexcept>());
+static_assert(!check_totally_ordered_with<int*, int (S::*)() const&>());
+static_assert(
+ !check_totally_ordered_with<int*, int (S::*)() const & noexcept>());
+static_assert(!check_totally_ordered_with<int*, int (S::*)() volatile&>());
+static_assert(
+ !check_totally_ordered_with<int*, int (S::*)() volatile & noexcept>());
+static_assert(
+ !check_totally_ordered_with<int*, int (S::*)() const volatile&>());
+static_assert(!check_totally_ordered_with<int*, int (S::*)() const volatile &
+ noexcept>());
+static_assert(!check_totally_ordered_with<int*, int (S::*)() &&>());
+static_assert(!check_totally_ordered_with < int*,
+ int (S::*)() && noexcept > ());
+static_assert(!check_totally_ordered_with<int*, int (S::*)() const&&>());
+static_assert(!check_totally_ordered_with < int*,
+ int (S::*)() const&& noexcept > ());
+static_assert(!check_totally_ordered_with<int*, int (S::*)() volatile&&>());
+static_assert(!check_totally_ordered_with < int*,
+ int (S::*)() volatile&& noexcept > ());
+static_assert(
+ !check_totally_ordered_with<int*, int (S::*)() const volatile&&>());
+static_assert(!check_totally_ordered_with < int*,
+ int (S::*)() const volatile&& noexcept > ());
+
+static_assert(check_totally_ordered_with<int[5], int[5]>());
+static_assert(!check_totally_ordered_with<int[5], int (*)()>());
+static_assert(!check_totally_ordered_with<int[5], int (&)()>());
+static_assert(!check_totally_ordered_with<int[5], int (S::*)()>());
+static_assert(!check_totally_ordered_with<int[5], int (S::*)() noexcept>());
+static_assert(!check_totally_ordered_with<int[5], int (S::*)() const>());
+static_assert(
+ !check_totally_ordered_with<int[5], int (S::*)() const noexcept>());
+static_assert(!check_totally_ordered_with<int[5], int (S::*)() volatile>());
+static_assert(
+ !check_totally_ordered_with<int[5], int (S::*)() volatile noexcept>());
+static_assert(
+ !check_totally_ordered_with<int[5], int (S::*)() const volatile>());
+static_assert(!check_totally_ordered_with<
+ int[5], int (S::*)() const volatile noexcept>());
+static_assert(!check_totally_ordered_with<int[5], int (S::*)() &>());
+static_assert(!check_totally_ordered_with<int[5], int (S::*)() & noexcept>());
+static_assert(!check_totally_ordered_with<int[5], int (S::*)() const&>());
+static_assert(
+ !check_totally_ordered_with<int[5], int (S::*)() const & noexcept>());
+static_assert(!check_totally_ordered_with<int[5], int (S::*)() volatile&>());
+static_assert(
+ !check_totally_ordered_with<int[5], int (S::*)() volatile & noexcept>());
+static_assert(
+ !check_totally_ordered_with<int[5], int (S::*)() const volatile&>());
+static_assert(!check_totally_ordered_with<int[5], int (S::*)() const volatile &
+ noexcept>());
+static_assert(!check_totally_ordered_with<int[5], int (S::*)() &&>());
+static_assert(!check_totally_ordered_with < int[5],
+ int (S::*)() && noexcept > ());
+static_assert(!check_totally_ordered_with<int[5], int (S::*)() const&&>());
+static_assert(!check_totally_ordered_with < int[5],
+ int (S::*)() const&& noexcept > ());
+static_assert(!check_totally_ordered_with<int[5], int (S::*)() volatile&&>());
+static_assert(!check_totally_ordered_with < int[5],
+ int (S::*)() volatile&& noexcept > ());
+static_assert(
+ !check_totally_ordered_with<int[5], int (S::*)() const volatile&&>());
+static_assert(!check_totally_ordered_with < int[5],
+ int (S::*)() const volatile&& noexcept > ());
+
+static_assert(check_totally_ordered_with<int (*)(), int (*)()>());
+static_assert(check_totally_ordered_with<int (*)(), int (&)()>());
+static_assert(!check_totally_ordered_with<int (*)(), int (S::*)()>());
+static_assert(!check_totally_ordered_with<int (*)(), int (S::*)() noexcept>());
+static_assert(!check_totally_ordered_with<int (*)(), int (S::*)() const>());
+static_assert(
+ !check_totally_ordered_with<int (*)(), int (S::*)() const noexcept>());
+static_assert(!check_totally_ordered_with<int (*)(), int (S::*)() volatile>());
+static_assert(
+ !check_totally_ordered_with<int (*)(), int (S::*)() volatile noexcept>());
+static_assert(
+ !check_totally_ordered_with<int (*)(), int (S::*)() const volatile>());
+static_assert(!check_totally_ordered_with<
+ int (*)(), int (S::*)() const volatile noexcept>());
+static_assert(!check_totally_ordered_with<int (*)(), int (S::*)() &>());
+static_assert(
+ !check_totally_ordered_with<int (*)(), int (S::*)() & noexcept>());
+static_assert(!check_totally_ordered_with<int (*)(), int (S::*)() const&>());
+static_assert(
+ !check_totally_ordered_with<int (*)(), int (S::*)() const & noexcept>());
+static_assert(!check_totally_ordered_with<int (*)(), int (S::*)() volatile&>());
+static_assert(
+ !check_totally_ordered_with<int (*)(), int (S::*)() volatile & noexcept>());
+static_assert(
+ !check_totally_ordered_with<int (*)(), int (S::*)() const volatile&>());
+static_assert(!check_totally_ordered_with<
+ int (*)(), int (S::*)() const volatile & noexcept>());
+static_assert(!check_totally_ordered_with<int (*)(), int (S::*)() &&>());
+static_assert(!check_totally_ordered_with < int (*)(),
+ int (S::*)() && noexcept > ());
+static_assert(!check_totally_ordered_with<int (*)(), int (S::*)() const&&>());
+static_assert(!check_totally_ordered_with < int (*)(),
+ int (S::*)() const&& noexcept > ());
+static_assert(
+ !check_totally_ordered_with<int (*)(), int (S::*)() volatile&&>());
+static_assert(!check_totally_ordered_with < int (*)(),
+ int (S::*)() volatile&& noexcept > ());
+static_assert(
+ !check_totally_ordered_with<int (*)(), int (S::*)() const volatile&&>());
+static_assert(!check_totally_ordered_with < int (*)(),
+ int (S::*)() const volatile&& noexcept > ());
+
+static_assert(check_totally_ordered_with<int (&)(), int (&)()>());
+static_assert(!check_totally_ordered_with<int (&)(), int (S::*)()>());
+static_assert(!check_totally_ordered_with<int (&)(), int (S::*)() noexcept>());
+static_assert(!check_totally_ordered_with<int (&)(), int (S::*)() const>());
+static_assert(
+ !check_totally_ordered_with<int (&)(), int (S::*)() const noexcept>());
+static_assert(!check_totally_ordered_with<int (&)(), int (S::*)() volatile>());
+static_assert(
+ !check_totally_ordered_with<int (&)(), int (S::*)() volatile noexcept>());
+static_assert(
+ !check_totally_ordered_with<int (&)(), int (S::*)() const volatile>());
+static_assert(!check_totally_ordered_with<
+ int (&)(), int (S::*)() const volatile noexcept>());
+static_assert(!check_totally_ordered_with<int (&)(), int (S::*)() &>());
+static_assert(
+ !check_totally_ordered_with<int (&)(), int (S::*)() & noexcept>());
+static_assert(!check_totally_ordered_with<int (&)(), int (S::*)() const&>());
+static_assert(
+ !check_totally_ordered_with<int (&)(), int (S::*)() const & noexcept>());
+static_assert(!check_totally_ordered_with<int (&)(), int (S::*)() volatile&>());
+static_assert(
+ !check_totally_ordered_with<int (&)(), int (S::*)() volatile & noexcept>());
+static_assert(
+ !check_totally_ordered_with<int (&)(), int (S::*)() const volatile&>());
+static_assert(!check_totally_ordered_with<
+ int (&)(), int (S::*)() const volatile & noexcept>());
+static_assert(!check_totally_ordered_with<int (&)(), int (S::*)() &&>());
+static_assert(!check_totally_ordered_with < int (&)(),
+ int (S::*)() && noexcept > ());
+static_assert(!check_totally_ordered_with<int (&)(), int (S::*)() const&&>());
+static_assert(!check_totally_ordered_with < int (&)(),
+ int (S::*)() const&& noexcept > ());
+static_assert(
+ !check_totally_ordered_with<int (&)(), int (S::*)() volatile&&>());
+static_assert(!check_totally_ordered_with < int (&)(),
+ int (S::*)() volatile&& noexcept > ());
+static_assert(
+ !check_totally_ordered_with<int (&)(), int (S::*)() const volatile&&>());
+static_assert(!check_totally_ordered_with < int (&)(),
+ int (S::*)() const volatile&& noexcept > ());
+
+static_assert(!check_totally_ordered_with<int (S::*)(), int (S::*)()>());
+static_assert(
+ !check_totally_ordered_with<int (S::*)(), int (S::*)() noexcept>());
+static_assert(!check_totally_ordered_with<int (S::*)(), int (S::*)() const>());
+static_assert(
+ !check_totally_ordered_with<int (S::*)(), int (S::*)() const noexcept>());
+static_assert(
+ !check_totally_ordered_with<int (S::*)(), int (S::*)() volatile>());
+static_assert(!check_totally_ordered_with<int (S::*)(),
+ int (S::*)() volatile noexcept>());
+static_assert(
+ !check_totally_ordered_with<int (S::*)(), int (S::*)() const volatile>());
+static_assert(!check_totally_ordered_with<
+ int (S::*)(), int (S::*)() const volatile noexcept>());
+static_assert(!check_totally_ordered_with<int (S::*)(), int (S::*)() &>());
+static_assert(
+ !check_totally_ordered_with<int (S::*)(), int (S::*)() & noexcept>());
+static_assert(!check_totally_ordered_with<int (S::*)(), int (S::*)() const&>());
+static_assert(
+ !check_totally_ordered_with<int (S::*)(), int (S::*)() const & noexcept>());
+static_assert(
+ !check_totally_ordered_with<int (S::*)(), int (S::*)() volatile&>());
+static_assert(!check_totally_ordered_with<int (S::*)(),
+ int (S::*)() volatile & noexcept>());
+static_assert(
+ !check_totally_ordered_with<int (S::*)(), int (S::*)() const volatile&>());
+static_assert(!check_totally_ordered_with<
+ int (S::*)(), int (S::*)() const volatile & noexcept>());
+static_assert(!check_totally_ordered_with<int (S::*)(), int (S::*)() &&>());
+static_assert(!check_totally_ordered_with < int (S::*)(),
+ int (S::*)() && noexcept > ());
+static_assert(
+ !check_totally_ordered_with<int (S::*)(), int (S::*)() const&&>());
+static_assert(!check_totally_ordered_with < int (S::*)(),
+ int (S::*)() const&& noexcept > ());
+static_assert(
+ !check_totally_ordered_with<int (S::*)(), int (S::*)() volatile&&>());
+static_assert(!check_totally_ordered_with < int (S::*)(),
+ int (S::*)() volatile&& noexcept > ());
+static_assert(
+ !check_totally_ordered_with<int (S::*)(), int (S::*)() const volatile&&>());
+static_assert(!check_totally_ordered_with < int (S::*)(),
+ int (S::*)() const volatile&& noexcept > ());
+
+static_assert(!check_totally_ordered_with<int (S::*)() noexcept,
+ int (S::*)() noexcept>());
+static_assert(
+ !check_totally_ordered_with<int (S::*)() noexcept, int (S::*)() const>());
+static_assert(!check_totally_ordered_with<int (S::*)() noexcept,
+ int (S::*)() const noexcept>());
+static_assert(!check_totally_ordered_with<int (S::*)() noexcept,
+ int (S::*)() volatile>());
+static_assert(!check_totally_ordered_with<int (S::*)() noexcept,
+ int (S::*)() volatile noexcept>());
+static_assert(!check_totally_ordered_with<int (S::*)() noexcept,
+ int (S::*)() const volatile>());
+static_assert(!check_totally_ordered_with<
+ int (S::*)() noexcept, int (S::*)() const volatile noexcept>());
+static_assert(
+ !check_totally_ordered_with<int (S::*)() noexcept, int (S::*)() &>());
+static_assert(!check_totally_ordered_with<int (S::*)() noexcept,
+ int (S::*)() & noexcept>());
+static_assert(
+ !check_totally_ordered_with<int (S::*)() noexcept, int (S::*)() const&>());
+static_assert(!check_totally_ordered_with<int (S::*)() noexcept,
+ int (S::*)() const & noexcept>());
+static_assert(!check_totally_ordered_with<int (S::*)() noexcept,
+ int (S::*)() volatile&>());
+static_assert(!check_totally_ordered_with<int (S::*)() noexcept,
+ int (S::*)() volatile & noexcept>());
+static_assert(!check_totally_ordered_with<int (S::*)() noexcept,
+ int (S::*)() const volatile&>());
+static_assert(!check_totally_ordered_with<
+ int (S::*)() noexcept, int (S::*)() const volatile & noexcept>());
+static_assert(
+ !check_totally_ordered_with<int (S::*)() noexcept, int (S::*)() &&>());
+static_assert(!check_totally_ordered_with < int (S::*)() noexcept,
+ int (S::*)() && noexcept > ());
+static_assert(
+ !check_totally_ordered_with<int (S::*)() noexcept, int (S::*)() const&&>());
+static_assert(!check_totally_ordered_with < int (S::*)() noexcept,
+ int (S::*)() const&& noexcept > ());
+static_assert(!check_totally_ordered_with<int (S::*)() noexcept,
+ int (S::*)() volatile&&>());
+static_assert(!check_totally_ordered_with < int (S::*)() noexcept,
+ int (S::*)() volatile&& noexcept > ());
+static_assert(!check_totally_ordered_with<int (S::*)() noexcept,
+ int (S::*)() const volatile&&>());
+static_assert(!check_totally_ordered_with < int (S::*)() noexcept,
+ int (S::*)() const volatile&& noexcept > ());
+
+static_assert(
+ !check_totally_ordered_with<int (S::*)() const, int (S::*)() const>());
+static_assert(!check_totally_ordered_with<int (S::*)() const,
+ int (S::*)() const noexcept>());
+static_assert(
+ !check_totally_ordered_with<int (S::*)() const, int (S::*)() volatile>());
+static_assert(!check_totally_ordered_with<int (S::*)() const,
+ int (S::*)() volatile noexcept>());
+static_assert(!check_totally_ordered_with<int (S::*)() const,
+ int (S::*)() const volatile>());
+static_assert(!check_totally_ordered_with<
+ int (S::*)() const, int (S::*)() const volatile noexcept>());
+static_assert(
+ !check_totally_ordered_with<int (S::*)() const, int (S::*)() &>());
+static_assert(
+ !check_totally_ordered_with<int (S::*)() const, int (S::*)() & noexcept>());
+static_assert(
+ !check_totally_ordered_with<int (S::*)() const, int (S::*)() const&>());
+static_assert(!check_totally_ordered_with<int (S::*)() const,
+ int (S::*)() const & noexcept>());
+static_assert(
+ !check_totally_ordered_with<int (S::*)() const, int (S::*)() volatile&>());
+static_assert(!check_totally_ordered_with<int (S::*)() const,
+ int (S::*)() volatile & noexcept>());
+static_assert(!check_totally_ordered_with<int (S::*)() const,
+ int (S::*)() const volatile&>());
+static_assert(!check_totally_ordered_with<
+ int (S::*)() const, int (S::*)() const volatile & noexcept>());
+static_assert(
+ !check_totally_ordered_with<int (S::*)() const, int (S::*)() &&>());
+static_assert(!check_totally_ordered_with < int (S::*)() const,
+ int (S::*)() && noexcept > ());
+static_assert(
+ !check_totally_ordered_with<int (S::*)() const, int (S::*)() const&&>());
+static_assert(!check_totally_ordered_with < int (S::*)() const,
+ int (S::*)() const&& noexcept > ());
+static_assert(
+ !check_totally_ordered_with<int (S::*)() const, int (S::*)() volatile&&>());
+static_assert(!check_totally_ordered_with < int (S::*)() const,
+ int (S::*)() volatile&& noexcept > ());
+static_assert(!check_totally_ordered_with<int (S::*)() const,
+ int (S::*)() const volatile&&>());
+static_assert(!check_totally_ordered_with < int (S::*)() const,
+ int (S::*)() const volatile&& noexcept > ());
+
+static_assert(!check_totally_ordered_with<int (S::*)() const noexcept,
+ int (S::*)() const noexcept>());
+static_assert(!check_totally_ordered_with<int (S::*)() const noexcept,
+ int (S::*)() volatile>());
+static_assert(!check_totally_ordered_with<int (S::*)() const noexcept,
+ int (S::*)() volatile noexcept>());
+static_assert(!check_totally_ordered_with<int (S::*)() const noexcept,
+ int (S::*)() const volatile>());
+static_assert(
+ !check_totally_ordered_with<int (S::*)() const noexcept,
+ int (S::*)() const volatile noexcept>());
+static_assert(
+ !check_totally_ordered_with<int (S::*)() const noexcept, int (S::*)() &>());
+static_assert(!check_totally_ordered_with<int (S::*)() const noexcept,
+ int (S::*)() & noexcept>());
+static_assert(!check_totally_ordered_with<int (S::*)() const noexcept,
+ int (S::*)() const&>());
+static_assert(!check_totally_ordered_with<int (S::*)() const noexcept,
+ int (S::*)() const & noexcept>());
+static_assert(!check_totally_ordered_with<int (S::*)() const noexcept,
+ int (S::*)() volatile&>());
+static_assert(!check_totally_ordered_with<int (S::*)() const noexcept,
+ int (S::*)() volatile & noexcept>());
+static_assert(!check_totally_ordered_with<int (S::*)() const noexcept,
+ int (S::*)() const volatile&>());
+static_assert(
+ !check_totally_ordered_with<int (S::*)() const noexcept,
+ int (S::*)() const volatile & noexcept>());
+static_assert(!check_totally_ordered_with<int (S::*)() const noexcept,
+ int (S::*)() &&>());
+static_assert(!check_totally_ordered_with < int (S::*)() const noexcept,
+ int (S::*)() && noexcept > ());
+static_assert(!check_totally_ordered_with<int (S::*)() const noexcept,
+ int (S::*)() const&&>());
+static_assert(!check_totally_ordered_with < int (S::*)() const noexcept,
+ int (S::*)() const&& noexcept > ());
+static_assert(!check_totally_ordered_with<int (S::*)() const noexcept,
+ int (S::*)() volatile&&>());
+static_assert(!check_totally_ordered_with < int (S::*)() const noexcept,
+ int (S::*)() volatile&& noexcept > ());
+static_assert(!check_totally_ordered_with<int (S::*)() const noexcept,
+ int (S::*)() const volatile&&>());
+static_assert(!check_totally_ordered_with < int (S::*)() const noexcept,
+ int (S::*)() const volatile&& noexcept > ());
+
+static_assert(!check_totally_ordered_with<int (S::*)() volatile,
+ int (S::*)() volatile>());
+static_assert(!check_totally_ordered_with<int (S::*)() volatile,
+ int (S::*)() volatile noexcept>());
+static_assert(!check_totally_ordered_with<int (S::*)() volatile,
+ int (S::*)() const volatile>());
+static_assert(!check_totally_ordered_with<
+ int (S::*)() volatile, int (S::*)() const volatile noexcept>());
+static_assert(
+ !check_totally_ordered_with<int (S::*)() volatile, int (S::*)() &>());
+static_assert(!check_totally_ordered_with<int (S::*)() volatile,
+ int (S::*)() & noexcept>());
+static_assert(
+ !check_totally_ordered_with<int (S::*)() volatile, int (S::*)() const&>());
+static_assert(!check_totally_ordered_with<int (S::*)() volatile,
+ int (S::*)() const & noexcept>());
+static_assert(!check_totally_ordered_with<int (S::*)() volatile,
+ int (S::*)() volatile&>());
+static_assert(!check_totally_ordered_with<int (S::*)() volatile,
+ int (S::*)() volatile & noexcept>());
+static_assert(!check_totally_ordered_with<int (S::*)() volatile,
+ int (S::*)() const volatile&>());
+static_assert(!check_totally_ordered_with<
+ int (S::*)() volatile, int (S::*)() const volatile & noexcept>());
+static_assert(
+ !check_totally_ordered_with<int (S::*)() volatile, int (S::*)() &&>());
+static_assert(!check_totally_ordered_with < int (S::*)() volatile,
+ int (S::*)() && noexcept > ());
+static_assert(
+ !check_totally_ordered_with<int (S::*)() volatile, int (S::*)() const&&>());
+static_assert(!check_totally_ordered_with < int (S::*)() volatile,
+ int (S::*)() const&& noexcept > ());
+static_assert(!check_totally_ordered_with<int (S::*)() volatile,
+ int (S::*)() volatile&&>());
+static_assert(!check_totally_ordered_with < int (S::*)() volatile,
+ int (S::*)() volatile&& noexcept > ());
+static_assert(!check_totally_ordered_with<int (S::*)() volatile,
+ int (S::*)() const volatile&&>());
+static_assert(!check_totally_ordered_with < int (S::*)() volatile,
+ int (S::*)() const volatile&& noexcept > ());
+
+static_assert(!check_totally_ordered_with<int (S::*)() volatile noexcept,
+ int (S::*)() volatile noexcept>());
+static_assert(!check_totally_ordered_with<int (S::*)() volatile noexcept,
+ int (S::*)() const volatile>());
+static_assert(
+ !check_totally_ordered_with<int (S::*)() volatile noexcept,
+ int (S::*)() const volatile noexcept>());
+static_assert(!check_totally_ordered_with<int (S::*)() volatile noexcept,
+ int (S::*)() &>());
+static_assert(!check_totally_ordered_with<int (S::*)() volatile noexcept,
+ int (S::*)() & noexcept>());
+static_assert(!check_totally_ordered_with<int (S::*)() volatile noexcept,
+ int (S::*)() const&>());
+static_assert(!check_totally_ordered_with<int (S::*)() volatile noexcept,
+ int (S::*)() const & noexcept>());
+static_assert(!check_totally_ordered_with<int (S::*)() volatile noexcept,
+ int (S::*)() volatile&>());
+static_assert(!check_totally_ordered_with<int (S::*)() volatile noexcept,
+ int (S::*)() volatile & noexcept>());
+static_assert(!check_totally_ordered_with<int (S::*)() volatile noexcept,
+ int (S::*)() const volatile&>());
+static_assert(
+ !check_totally_ordered_with<int (S::*)() volatile noexcept,
+ int (S::*)() const volatile & noexcept>());
+static_assert(!check_totally_ordered_with<int (S::*)() volatile noexcept,
+ int (S::*)() &&>());
+static_assert(!check_totally_ordered_with < int (S::*)() volatile noexcept,
+ int (S::*)() && noexcept > ());
+static_assert(!check_totally_ordered_with<int (S::*)() volatile noexcept,
+ int (S::*)() const&&>());
+static_assert(!check_totally_ordered_with < int (S::*)() volatile noexcept,
+ int (S::*)() const&& noexcept > ());
+static_assert(!check_totally_ordered_with<int (S::*)() volatile noexcept,
+ int (S::*)() volatile&&>());
+static_assert(!check_totally_ordered_with < int (S::*)() volatile noexcept,
+ int (S::*)() volatile&& noexcept > ());
+static_assert(!check_totally_ordered_with<int (S::*)() volatile noexcept,
+ int (S::*)() const volatile&&>());
+static_assert(!check_totally_ordered_with < int (S::*)() volatile noexcept,
+ int (S::*)() const volatile&& noexcept > ());
+
+static_assert(!check_totally_ordered_with<int (S::*)() const volatile,
+ int (S::*)() const volatile>());
+static_assert(
+ !check_totally_ordered_with<int (S::*)() const volatile,
+ int (S::*)() const volatile noexcept>());
+static_assert(
+ !check_totally_ordered_with<int (S::*)() const volatile, int (S::*)() &>());
+static_assert(!check_totally_ordered_with<int (S::*)() const volatile,
+ int (S::*)() & noexcept>());
+static_assert(!check_totally_ordered_with<int (S::*)() const volatile,
+ int (S::*)() const&>());
+static_assert(!check_totally_ordered_with<int (S::*)() const volatile,
+ int (S::*)() const & noexcept>());
+static_assert(!check_totally_ordered_with<int (S::*)() const volatile,
+ int (S::*)() volatile&>());
+static_assert(!check_totally_ordered_with<int (S::*)() const volatile,
+ int (S::*)() volatile & noexcept>());
+static_assert(!check_totally_ordered_with<int (S::*)() const volatile,
+ int (S::*)() const volatile&>());
+static_assert(
+ !check_totally_ordered_with<int (S::*)() const volatile,
+ int (S::*)() const volatile & noexcept>());
+static_assert(!check_totally_ordered_with<int (S::*)() const volatile,
+ int (S::*)() &&>());
+static_assert(!check_totally_ordered_with < int (S::*)() const volatile,
+ int (S::*)() && noexcept > ());
+static_assert(!check_totally_ordered_with<int (S::*)() const volatile,
+ int (S::*)() const&&>());
+static_assert(!check_totally_ordered_with < int (S::*)() const volatile,
+ int (S::*)() const&& noexcept > ());
+static_assert(!check_totally_ordered_with<int (S::*)() const volatile,
+ int (S::*)() volatile&&>());
+static_assert(!check_totally_ordered_with < int (S::*)() const volatile,
+ int (S::*)() volatile&& noexcept > ());
+static_assert(!check_totally_ordered_with<int (S::*)() const volatile,
+ int (S::*)() const volatile&&>());
+static_assert(!check_totally_ordered_with < int (S::*)() const volatile,
+ int (S::*)() const volatile&& noexcept > ());
+
+static_assert(
+ !check_totally_ordered_with<int (S::*)() const volatile noexcept,
+ int (S::*)() const volatile noexcept>());
+static_assert(!check_totally_ordered_with<int (S::*)() const volatile noexcept,
+ int (S::*)() &>());
+static_assert(!check_totally_ordered_with<int (S::*)() const volatile noexcept,
+ int (S::*)() & noexcept>());
+static_assert(!check_totally_ordered_with<int (S::*)() const volatile noexcept,
+ int (S::*)() const&>());
+static_assert(!check_totally_ordered_with<int (S::*)() const volatile noexcept,
+ int (S::*)() const & noexcept>());
+static_assert(!check_totally_ordered_with<int (S::*)() const volatile noexcept,
+ int (S::*)() volatile&>());
+static_assert(!check_totally_ordered_with<int (S::*)() const volatile noexcept,
+ int (S::*)() volatile & noexcept>());
+static_assert(!check_totally_ordered_with<int (S::*)() const volatile noexcept,
+ int (S::*)() const volatile&>());
+static_assert(
+ !check_totally_ordered_with<int (S::*)() const volatile noexcept,
+ int (S::*)() const volatile & noexcept>());
+static_assert(!check_totally_ordered_with<int (S::*)() const volatile noexcept,
+ int (S::*)() &&>());
+static_assert(!check_totally_ordered_with < int (S::*)()
+ const volatile noexcept,
+ int (S::*)() && noexcept > ());
+static_assert(!check_totally_ordered_with<int (S::*)() const volatile noexcept,
+ int (S::*)() const&&>());
+static_assert(!check_totally_ordered_with < int (S::*)()
+ const volatile noexcept,
+ int (S::*)() const&& noexcept > ());
+static_assert(!check_totally_ordered_with<int (S::*)() const volatile noexcept,
+ int (S::*)() volatile&&>());
+static_assert(!check_totally_ordered_with < int (S::*)()
+ const volatile noexcept,
+ int (S::*)() volatile&& noexcept > ());
+static_assert(!check_totally_ordered_with<int (S::*)() const volatile noexcept,
+ int (S::*)() const volatile&&>());
+static_assert(!check_totally_ordered_with < int (S::*)()
+ const volatile noexcept,
+ int (S::*)() const volatile&& noexcept > ());
+
+static_assert(!check_totally_ordered_with<int (S::*)() &, int (S::*)() &>());
+static_assert(
+ !check_totally_ordered_with<int (S::*)() &, int (S::*)() & noexcept>());
+static_assert(
+ !check_totally_ordered_with<int (S::*)() &, int (S::*)() const&>());
+static_assert(!check_totally_ordered_with<int (S::*)() &,
+ int (S::*)() const & noexcept>());
+static_assert(
+ !check_totally_ordered_with<int (S::*)() &, int (S::*)() volatile&>());
+static_assert(!check_totally_ordered_with<int (S::*)() &,
+ int (S::*)() volatile & noexcept>());
+static_assert(!check_totally_ordered_with<int (S::*)() &,
+ int (S::*)() const volatile&>());
+static_assert(!check_totally_ordered_with<
+ int (S::*)() &, int (S::*)() const volatile & noexcept>());
+static_assert(!check_totally_ordered_with<int (S::*)() &, int (S::*)() &&>());
+static_assert(!check_totally_ordered_with < int (S::*)() &,
+ int (S::*)() && noexcept > ());
+static_assert(
+ !check_totally_ordered_with<int (S::*)() &, int (S::*)() const&&>());
+static_assert(!check_totally_ordered_with < int (S::*)() &,
+ int (S::*)() const&& noexcept > ());
+static_assert(
+ !check_totally_ordered_with<int (S::*)() &, int (S::*)() volatile&&>());
+static_assert(!check_totally_ordered_with < int (S::*)() &,
+ int (S::*)() volatile&& noexcept > ());
+static_assert(!check_totally_ordered_with<int (S::*)() &,
+ int (S::*)() const volatile&&>());
+static_assert(!check_totally_ordered_with < int (S::*)() &,
+ int (S::*)() const volatile&& noexcept > ());
+
+static_assert(!check_totally_ordered_with<int (S::*)() & noexcept,
+ int (S::*)() & noexcept>());
+static_assert(!check_totally_ordered_with<int (S::*)() & noexcept,
+ int (S::*)() const&>());
+static_assert(!check_totally_ordered_with<int (S::*)() & noexcept,
+ int (S::*)() const & noexcept>());
+static_assert(!check_totally_ordered_with<int (S::*)() & noexcept,
+ int (S::*)() volatile&>());
+static_assert(!check_totally_ordered_with<int (S::*)() & noexcept,
+ int (S::*)() volatile & noexcept>());
+static_assert(!check_totally_ordered_with<int (S::*)() & noexcept,
+ int (S::*)() const volatile&>());
+static_assert(
+ !check_totally_ordered_with<int (S::*)() & noexcept,
+ int (S::*)() const volatile & noexcept>());
+static_assert(
+ !check_totally_ordered_with<int (S::*)() & noexcept, int (S::*)() &&>());
+static_assert(!check_totally_ordered_with < int (S::*)() & noexcept,
+ int (S::*)() && noexcept > ());
+static_assert(!check_totally_ordered_with<int (S::*)() & noexcept,
+ int (S::*)() const&&>());
+static_assert(!check_totally_ordered_with < int (S::*)() & noexcept,
+ int (S::*)() const&& noexcept > ());
+static_assert(!check_totally_ordered_with<int (S::*)() & noexcept,
+ int (S::*)() volatile&&>());
+static_assert(!check_totally_ordered_with < int (S::*)() & noexcept,
+ int (S::*)() volatile&& noexcept > ());
+static_assert(!check_totally_ordered_with<int (S::*)() & noexcept,
+ int (S::*)() const volatile&&>());
+static_assert(!check_totally_ordered_with < int (S::*)() & noexcept,
+ int (S::*)() const volatile&& noexcept > ());
+
+static_assert(
+ !check_totally_ordered_with<int (S::*)() const&, int (S::*)() const&>());
+static_assert(!check_totally_ordered_with<int (S::*)() const&,
+ int (S::*)() const & noexcept>());
+static_assert(
+ !check_totally_ordered_with<int (S::*)() const&, int (S::*)() volatile&>());
+static_assert(!check_totally_ordered_with<int (S::*)() const&,
+ int (S::*)() volatile & noexcept>());
+static_assert(!check_totally_ordered_with<int (S::*)() const&,
+ int (S::*)() const volatile&>());
+static_assert(!check_totally_ordered_with<
+ int (S::*)() const&, int (S::*)() const volatile & noexcept>());
+static_assert(
+ !check_totally_ordered_with<int (S::*)() const&, int (S::*)() &&>());
+static_assert(!check_totally_ordered_with < int (S::*)() const&,
+ int (S::*)() && noexcept > ());
+static_assert(
+ !check_totally_ordered_with<int (S::*)() const&, int (S::*)() const&&>());
+static_assert(!check_totally_ordered_with < int (S::*)() const&,
+ int (S::*)() const&& noexcept > ());
+static_assert(!check_totally_ordered_with<int (S::*)() const&,
+ int (S::*)() volatile&&>());
+static_assert(!check_totally_ordered_with < int (S::*)() const&,
+ int (S::*)() volatile&& noexcept > ());
+static_assert(!check_totally_ordered_with<int (S::*)() const&,
+ int (S::*)() const volatile&&>());
+static_assert(!check_totally_ordered_with < int (S::*)() const&,
+ int (S::*)() const volatile&& noexcept > ());
+
+static_assert(!check_totally_ordered_with<int (S::*)() const & noexcept,
+ int (S::*)() const & noexcept>());
+static_assert(!check_totally_ordered_with<int (S::*)() const & noexcept,
+ int (S::*)() volatile&>());
+static_assert(!check_totally_ordered_with<int (S::*)() const & noexcept,
+ int (S::*)() volatile & noexcept>());
+static_assert(!check_totally_ordered_with<int (S::*)() const & noexcept,
+ int (S::*)() const volatile&>());
+static_assert(
+ !check_totally_ordered_with<int (S::*)() const & noexcept,
+ int (S::*)() const volatile & noexcept>());
+static_assert(!check_totally_ordered_with<int (S::*)() const & noexcept,
+ int (S::*)() &&>());
+static_assert(!check_totally_ordered_with < int (S::*)() const& noexcept,
+ int (S::*)() && noexcept > ());
+static_assert(!check_totally_ordered_with<int (S::*)() const & noexcept,
+ int (S::*)() const&&>());
+static_assert(!check_totally_ordered_with < int (S::*)() const& noexcept,
+ int (S::*)() const&& noexcept > ());
+static_assert(!check_totally_ordered_with<int (S::*)() const & noexcept,
+ int (S::*)() volatile&&>());
+static_assert(!check_totally_ordered_with < int (S::*)() const& noexcept,
+ int (S::*)() volatile&& noexcept > ());
+static_assert(!check_totally_ordered_with<int (S::*)() const & noexcept,
+ int (S::*)() const volatile&&>());
+static_assert(!check_totally_ordered_with < int (S::*)() const& noexcept,
+ int (S::*)() const volatile&& noexcept > ());
+
+static_assert(!check_totally_ordered_with<int (S::*)() volatile&,
+ int (S::*)() volatile&>());
+static_assert(!check_totally_ordered_with<int (S::*)() volatile&,
+ int (S::*)() volatile & noexcept>());
+static_assert(!check_totally_ordered_with<int (S::*)() volatile&,
+ int (S::*)() const volatile&>());
+static_assert(
+ !check_totally_ordered_with<int (S::*)() volatile&,
+ int (S::*)() const volatile & noexcept>());
+static_assert(
+ !check_totally_ordered_with<int (S::*)() volatile&, int (S::*)() &&>());
+static_assert(!check_totally_ordered_with < int (S::*)() volatile&,
+ int (S::*)() && noexcept > ());
+static_assert(!check_totally_ordered_with<int (S::*)() volatile&,
+ int (S::*)() const&&>());
+static_assert(!check_totally_ordered_with < int (S::*)() volatile&,
+ int (S::*)() const&& noexcept > ());
+static_assert(!check_totally_ordered_with<int (S::*)() volatile&,
+ int (S::*)() volatile&&>());
+static_assert(!check_totally_ordered_with < int (S::*)() volatile&,
+ int (S::*)() volatile&& noexcept > ());
+static_assert(!check_totally_ordered_with<int (S::*)() volatile&,
+ int (S::*)() const volatile&&>());
+static_assert(!check_totally_ordered_with < int (S::*)() volatile&,
+ int (S::*)() const volatile&& noexcept > ());
+
+static_assert(!check_totally_ordered_with<int (S::*)() volatile & noexcept,
+ int (S::*)() volatile & noexcept>());
+static_assert(!check_totally_ordered_with<int (S::*)() volatile & noexcept,
+ int (S::*)() const volatile&>());
+static_assert(
+ !check_totally_ordered_with<int (S::*)() volatile & noexcept,
+ int (S::*)() const volatile & noexcept>());
+static_assert(!check_totally_ordered_with<int (S::*)() volatile & noexcept,
+ int (S::*)() &&>());
+static_assert(!check_totally_ordered_with < int (S::*)() volatile& noexcept,
+ int (S::*)() && noexcept > ());
+static_assert(!check_totally_ordered_with<int (S::*)() volatile & noexcept,
+ int (S::*)() const&&>());
+static_assert(!check_totally_ordered_with < int (S::*)() volatile& noexcept,
+ int (S::*)() const&& noexcept > ());
+static_assert(!check_totally_ordered_with<int (S::*)() volatile & noexcept,
+ int (S::*)() volatile&&>());
+static_assert(!check_totally_ordered_with < int (S::*)() volatile& noexcept,
+ int (S::*)() volatile&& noexcept > ());
+static_assert(!check_totally_ordered_with<int (S::*)() volatile & noexcept,
+ int (S::*)() const volatile&&>());
+static_assert(!check_totally_ordered_with < int (S::*)() volatile& noexcept,
+ int (S::*)() const volatile&& noexcept > ());
+
+static_assert(!check_totally_ordered_with<int (S::*)() const volatile&,
+ int (S::*)() const volatile&>());
+static_assert(
+ !check_totally_ordered_with<int (S::*)() const volatile&,
+ int (S::*)() const volatile & noexcept>());
+static_assert(!check_totally_ordered_with<int (S::*)() const volatile&,
+ int (S::*)() &&>());
+static_assert(!check_totally_ordered_with < int (S::*)() const volatile&,
+ int (S::*)() && noexcept > ());
+static_assert(!check_totally_ordered_with<int (S::*)() const volatile&,
+ int (S::*)() const&&>());
+static_assert(!check_totally_ordered_with < int (S::*)() const volatile&,
+ int (S::*)() const&& noexcept > ());
+static_assert(!check_totally_ordered_with<int (S::*)() const volatile&,
+ int (S::*)() volatile&&>());
+static_assert(!check_totally_ordered_with < int (S::*)() const volatile&,
+ int (S::*)() volatile&& noexcept > ());
+static_assert(!check_totally_ordered_with<int (S::*)() const volatile&,
+ int (S::*)() const volatile&&>());
+static_assert(!check_totally_ordered_with < int (S::*)() const volatile&,
+ int (S::*)() const volatile&& noexcept > ());
+
+static_assert(
+ !check_totally_ordered_with<int (S::*)() const volatile & noexcept,
+ int (S::*)() const volatile & noexcept>());
+static_assert(!check_totally_ordered_with<
+ int (S::*)() const volatile & noexcept, int (S::*)() &&>());
+static_assert(!check_totally_ordered_with < int (S::*)()
+ const volatile& noexcept,
+ int (S::*)() && noexcept > ());
+static_assert(!check_totally_ordered_with<
+ int (S::*)() const volatile & noexcept, int (S::*)() const&&>());
+static_assert(!check_totally_ordered_with < int (S::*)()
+ const volatile& noexcept,
+ int (S::*)() const&& noexcept > ());
+static_assert(
+ !check_totally_ordered_with<int (S::*)() const volatile & noexcept,
+ int (S::*)() volatile&&>());
+static_assert(!check_totally_ordered_with < int (S::*)()
+ const volatile& noexcept,
+ int (S::*)() volatile&& noexcept > ());
+static_assert(
+ !check_totally_ordered_with<int (S::*)() const volatile & noexcept,
+ int (S::*)() const volatile&&>());
+static_assert(!check_totally_ordered_with < int (S::*)()
+ const volatile& noexcept,
+ int (S::*)() const volatile&& noexcept > ());
+
+static_assert(!check_totally_ordered_with<int (S::*)() &&, int (S::*)() &&>());
+static_assert(!check_totally_ordered_with < int (S::*)() &&,
+ int (S::*)() && noexcept > ());
+static_assert(
+ !check_totally_ordered_with<int (S::*)() &&, int (S::*)() const&&>());
+static_assert(!check_totally_ordered_with < int (S::*)() &&,
+ int (S::*)() const&& noexcept > ());
+static_assert(
+ !check_totally_ordered_with<int (S::*)() &&, int (S::*)() volatile&&>());
+static_assert(!check_totally_ordered_with < int (S::*)() &&,
+ int (S::*)() volatile&& noexcept > ());
+static_assert(!check_totally_ordered_with<int (S::*)() &&,
+ int (S::*)() const volatile&&>());
+static_assert(!check_totally_ordered_with < int (S::*)() &&,
+ int (S::*)() const volatile&& noexcept > ());
+
+static_assert(!check_totally_ordered_with < int (S::*)() && noexcept,
+ int (S::*)() && noexcept > ());
+static_assert(!check_totally_ordered_with < int (S::*)() && noexcept,
+ int (S::*)() const&& > ());
+static_assert(!check_totally_ordered_with < int (S::*)() && noexcept,
+ int (S::*)() const&& noexcept > ());
+static_assert(!check_totally_ordered_with < int (S::*)() && noexcept,
+ int (S::*)() volatile&& > ());
+static_assert(!check_totally_ordered_with < int (S::*)() && noexcept,
+ int (S::*)() volatile&& noexcept > ());
+static_assert(!check_totally_ordered_with < int (S::*)() && noexcept,
+ int (S::*)() const volatile&& > ());
+static_assert(!check_totally_ordered_with < int (S::*)() && noexcept,
+ int (S::*)() const volatile&& noexcept > ());
+
+static_assert(
+ !check_totally_ordered_with<int (S::*)() const&&, int (S::*)() const&&>());
+static_assert(!check_totally_ordered_with < int (S::*)() const&&,
+ int (S::*)() const&& noexcept > ());
+static_assert(!check_totally_ordered_with<int (S::*)() const&&,
+ int (S::*)() volatile&&>());
+static_assert(!check_totally_ordered_with < int (S::*)() const&&,
+ int (S::*)() volatile&& noexcept > ());
+static_assert(!check_totally_ordered_with<int (S::*)() const&&,
+ int (S::*)() const volatile&&>());
+static_assert(!check_totally_ordered_with < int (S::*)() const&&,
+ int (S::*)() const volatile&& noexcept > ());
+
+static_assert(!check_totally_ordered_with < int (S::*)() const&& noexcept,
+ int (S::*)() const&& noexcept > ());
+static_assert(!check_totally_ordered_with < int (S::*)() const&& noexcept,
+ int (S::*)() volatile&& > ());
+static_assert(!check_totally_ordered_with < int (S::*)() const&& noexcept,
+ int (S::*)() volatile&& noexcept > ());
+static_assert(!check_totally_ordered_with < int (S::*)() const&& noexcept,
+ int (S::*)() const volatile&& > ());
+static_assert(!check_totally_ordered_with < int (S::*)() const&& noexcept,
+ int (S::*)() const volatile&& noexcept > ());
+
+static_assert(!check_totally_ordered_with<int (S::*)() volatile&&,
+ int (S::*)() volatile&&>());
+static_assert(!check_totally_ordered_with < int (S::*)() volatile&&,
+ int (S::*)() volatile&& noexcept > ());
+static_assert(!check_totally_ordered_with<int (S::*)() volatile&&,
+ int (S::*)() const volatile&&>());
+static_assert(!check_totally_ordered_with < int (S::*)() volatile&&,
+ int (S::*)() const volatile&& noexcept > ());
+
+static_assert(!check_totally_ordered_with < int (S::*)() volatile&& noexcept,
+ int (S::*)() volatile&& noexcept > ());
+static_assert(!check_totally_ordered_with < int (S::*)() volatile&& noexcept,
+ int (S::*)() const volatile&& > ());
+static_assert(!check_totally_ordered_with < int (S::*)() volatile&& noexcept,
+ int (S::*)() const volatile&& noexcept > ());
+
+static_assert(!check_totally_ordered_with<int (S::*)() const volatile&&,
+ int (S::*)() const volatile&&>());
+static_assert(!check_totally_ordered_with < int (S::*)() const volatile&&,
+ int (S::*)() const volatile&& noexcept > ());
+static_assert(!check_totally_ordered_with < int (S::*)()
+ const volatile&& noexcept,
+ int (S::*)() const volatile&& noexcept > ());
+
+#if !defined(TEST_COMPILER_GCC)
+static_assert(!check_totally_ordered_with<std::nullptr_t, int>());
+
+static_assert(!check_totally_ordered_with<std::nullptr_t, int*>());
+static_assert(!check_totally_ordered_with<std::nullptr_t, int[]>());
+static_assert(!check_totally_ordered_with<std::nullptr_t, int[5]>());
+static_assert(!check_totally_ordered_with<std::nullptr_t, int (*)()>());
+static_assert(!check_totally_ordered_with<std::nullptr_t, int (&)()>());
+#endif
+
+static_assert(!check_totally_ordered_with<std::nullptr_t, int (S::*)()>());
+static_assert(
+ !check_totally_ordered_with<std::nullptr_t, int (S::*)() noexcept>());
+static_assert(
+ !check_totally_ordered_with<std::nullptr_t, int (S::*)() const>());
+static_assert(
+ !check_totally_ordered_with<std::nullptr_t, int (S::*)() const noexcept>());
+static_assert(
+ !check_totally_ordered_with<std::nullptr_t, int (S::*)() volatile>());
+static_assert(!check_totally_ordered_with<std::nullptr_t,
+ int (S::*)() volatile noexcept>());
+static_assert(
+ !check_totally_ordered_with<std::nullptr_t, int (S::*)() const volatile>());
+static_assert(!check_totally_ordered_with<
+ std::nullptr_t, int (S::*)() const volatile noexcept>());
+static_assert(!check_totally_ordered_with<std::nullptr_t, int (S::*)() &>());
+static_assert(
+ !check_totally_ordered_with<std::nullptr_t, int (S::*)() & noexcept>());
+static_assert(
+ !check_totally_ordered_with<std::nullptr_t, int (S::*)() const&>());
+static_assert(!check_totally_ordered_with<std::nullptr_t,
+ int (S::*)() const & noexcept>());
+static_assert(
+ !check_totally_ordered_with<std::nullptr_t, int (S::*)() volatile&>());
+static_assert(!check_totally_ordered_with<std::nullptr_t,
+ int (S::*)() volatile & noexcept>());
+static_assert(!check_totally_ordered_with<std::nullptr_t,
+ int (S::*)() const volatile&>());
+static_assert(!check_totally_ordered_with<
+ std::nullptr_t, int (S::*)() const volatile & noexcept>());
+static_assert(!check_totally_ordered_with<std::nullptr_t, int (S::*)() &&>());
+static_assert(!check_totally_ordered_with < std::nullptr_t,
+ int (S::*)() && noexcept > ());
+static_assert(
+ !check_totally_ordered_with<std::nullptr_t, int (S::*)() const&&>());
+static_assert(!check_totally_ordered_with < std::nullptr_t,
+ int (S::*)() const&& noexcept > ());
+static_assert(
+ !check_totally_ordered_with<std::nullptr_t, int (S::*)() volatile&&>());
+static_assert(!check_totally_ordered_with < std::nullptr_t,
+ int (S::*)() volatile&& noexcept > ());
+static_assert(!check_totally_ordered_with<std::nullptr_t,
+ int (S::*)() const volatile&&>());
+static_assert(!check_totally_ordered_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_totally_ordered_with<std::array<int, 10>, std::array<int, 10> >());
+static_assert(!check_totally_ordered_with<std::array<int, 10>,
+ std::array<double, 10> >());
+static_assert(check_totally_ordered_with<std::deque<int>, std::deque<int> >());
+static_assert(
+ !check_totally_ordered_with<std::deque<int>, std::vector<int> >());
+static_assert(check_totally_ordered_with<std::forward_list<int>,
+ std::forward_list<int> >());
+static_assert(
+ !check_totally_ordered_with<std::forward_list<int>, std::vector<int> >());
+static_assert(check_totally_ordered_with<std::list<int>, std::list<int> >());
+static_assert(!check_totally_ordered_with<std::list<int>, std::vector<int> >());
+
+static_assert(
+ check_totally_ordered_with<std::map<int, void*>, std::map<int, void*> >());
+static_assert(
+ !check_totally_ordered_with<std::map<int, void*>, std::vector<int> >());
+static_assert(check_totally_ordered_with<std::optional<std::vector<int> >,
+ std::optional<std::vector<int> > >());
+static_assert(check_totally_ordered_with<std::optional<std::vector<int> >,
+ std::vector<int> >());
+static_assert(
+ check_totally_ordered_with<std::vector<int>, std::vector<int> >());
+static_assert(!check_totally_ordered_with<std::vector<int>, int>());
+
+struct A {};
+// FIXME(cjdb): uncomment when operator<=> is implemented for each of these types.
+// static_assert(!check_totally_ordered_with<std::optional<std::vector<A> >,
+// std::optional<std::vector<A> > >());
+// static_assert(!check_totally_ordered_with<std::optional<std::vector<A> >,
+// std::vector<A> >());
+struct B {};
+static_assert(!check_totally_ordered_with<std::vector<A>, std::vector<B> >());
+static_assert(
+ !check_totally_ordered_with<std::optional<A>, std::optional<B> >());
+} // namespace standard_types
+
+namespace types_fit_for_purpose {
+static_assert(!check_totally_ordered_with<cxx20_member_eq, cxx20_member_eq>());
+static_assert(!check_totally_ordered_with<cxx20_friend_eq, cxx20_friend_eq>());
+static_assert(!check_totally_ordered_with<cxx20_member_eq, cxx20_friend_eq>());
+
+static_assert(check_totally_ordered_with<member_three_way_comparable,
+ member_three_way_comparable>());
+static_assert(check_totally_ordered_with<friend_three_way_comparable,
+ friend_three_way_comparable>());
+static_assert(!check_totally_ordered_with<member_three_way_comparable,
+ friend_three_way_comparable>());
+
+static_assert(
+ check_totally_ordered_with<explicit_operators, explicit_operators>());
+static_assert(!check_totally_ordered_with<equality_comparable_with_ec1,
+ equality_comparable_with_ec1>());
+static_assert(check_totally_ordered_with<different_return_types,
+ different_return_types>());
+static_assert(!check_totally_ordered_with<explicit_operators,
+ equality_comparable_with_ec1>());
+static_assert(
+ check_totally_ordered_with<explicit_operators, different_return_types>());
+
+static_assert(!check_totally_ordered_with<one_way_eq, one_way_eq>());
+static_assert(
+ std::common_reference_with<one_way_eq const&, explicit_operators const&> &&
+ !check_totally_ordered_with<one_way_eq, explicit_operators>());
+
+static_assert(!check_totally_ordered_with<one_way_ne, one_way_ne>());
+static_assert(
+ std::common_reference_with<one_way_ne const&, explicit_operators const&> &&
+ !check_totally_ordered_with<one_way_ne, explicit_operators>());
+
+static_assert(
+ check_totally_ordered_with<totally_ordered_with_others,
+ partial_ordering_totally_ordered_with>());
+static_assert(check_totally_ordered_with<totally_ordered_with_others,
+ weak_ordering_totally_ordered_with>());
+static_assert(
+ check_totally_ordered_with<totally_ordered_with_others,
+ strong_ordering_totally_ordered_with>());
+
+static_assert(!check_totally_ordered_with<totally_ordered_with_others,
+ eq_returns_explicit_bool>());
+static_assert(!check_totally_ordered_with<totally_ordered_with_others,
+ ne_returns_explicit_bool>());
+static_assert(std::equality_comparable_with<totally_ordered_with_others,
+ lt_returns_explicit_bool> &&
+ !check_totally_ordered_with<totally_ordered_with_others,
+ lt_returns_explicit_bool>());
+static_assert(std::equality_comparable_with<totally_ordered_with_others,
+ gt_returns_explicit_bool> &&
+ !check_totally_ordered_with<totally_ordered_with_others,
+ gt_returns_explicit_bool>());
+static_assert(std::equality_comparable_with<totally_ordered_with_others,
+ le_returns_explicit_bool> &&
+ !check_totally_ordered_with<totally_ordered_with_others,
+ le_returns_explicit_bool>());
+static_assert(std::equality_comparable_with<totally_ordered_with_others,
+ ge_returns_explicit_bool> &&
+ !check_totally_ordered_with<totally_ordered_with_others,
+ ge_returns_explicit_bool>());
+static_assert(check_totally_ordered_with<totally_ordered_with_others,
+ returns_true_type>());
+static_assert(
+ check_totally_ordered_with<totally_ordered_with_others, returns_int_ptr>());
+
+static_assert(
+ std::totally_ordered<no_lt_not_totally_ordered_with>&&
+ std::equality_comparable_with<totally_ordered_with_others,
+ no_lt_not_totally_ordered_with> &&
+ !check_totally_ordered_with<totally_ordered_with_others,
+ no_lt_not_totally_ordered_with>());
+static_assert(
+ std::totally_ordered<no_gt_not_totally_ordered_with>&&
+ std::equality_comparable_with<totally_ordered_with_others,
+ no_gt_not_totally_ordered_with> &&
+ !check_totally_ordered_with<totally_ordered_with_others,
+ no_gt_not_totally_ordered_with>());
+static_assert(
+ std::totally_ordered<no_le_not_totally_ordered_with>&&
+ std::equality_comparable_with<totally_ordered_with_others,
+ no_le_not_totally_ordered_with> &&
+ !check_totally_ordered_with<totally_ordered_with_others,
+ no_le_not_totally_ordered_with>());
+static_assert(
+ std::totally_ordered<no_ge_not_totally_ordered_with>&&
+ std::equality_comparable_with<totally_ordered_with_others,
+ no_ge_not_totally_ordered_with> &&
+ !check_totally_ordered_with<totally_ordered_with_others,
+ no_ge_not_totally_ordered_with>());
+} // namespace types_fit_for_purpose
+
+int main(int, char**) { return 0; }
diff --git a/libcxx/test/std/concepts/concepts.compare/types.h b/libcxx/test/std/concepts/concepts.compare/types.h
new file mode 100644
index 000000000000..de816a371e45
--- /dev/null
+++ b/libcxx/test/std/concepts/concepts.compare/types.h
@@ -0,0 +1,573 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_TYPES_H
+#define TEST_STD_CONCEPTS_COMPARISON_TYPES_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, explicit_operators) noexcept;
+ friend bool operator>(explicit_operators, explicit_operators) noexcept;
+ friend bool operator<=(explicit_operators, explicit_operators) noexcept;
+ 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 different_return_types {
+ bool operator==(different_return_types) const noexcept;
+ char operator!=(different_return_types) const noexcept;
+ short operator<(different_return_types) const noexcept;
+ int operator>(different_return_types) const noexcept;
+ long operator<=(different_return_types) const noexcept;
+ long long operator>=(different_return_types) const noexcept;
+
+ friend signed char operator==(explicit_operators, different_return_types);
+ friend unsigned char operator==(different_return_types, explicit_operators);
+ friend float operator!=(explicit_operators, different_return_types);
+ friend double operator!=(different_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 different_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) = delete;
+ friend bool operator!=(no_eq, no_eq) noexcept;
+ friend bool operator<(no_eq, no_eq) noexcept;
+ friend bool operator>(no_eq, no_eq) noexcept;
+ friend bool operator>=(no_eq, no_eq) noexcept;
+ 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;
+ friend bool operator<(no_eq, no_eq) noexcept;
+ friend bool operator>(no_eq, no_eq) noexcept;
+ friend bool operator>=(no_eq, no_eq) noexcept;
+ friend bool operator<=(no_eq, no_eq) noexcept;
+};
+
+struct no_lt {
+ friend bool operator==(no_lt, no_lt) noexcept;
+ friend bool operator!=(no_lt, no_lt) noexcept;
+ friend bool operator<(no_lt, no_lt) = delete;
+ friend bool operator>(no_lt, no_lt) noexcept;
+ friend bool operator>=(no_lt, no_lt) noexcept;
+ friend bool operator<=(no_lt, no_lt) noexcept;
+};
+
+struct no_gt {
+ friend bool operator==(no_gt, no_gt) noexcept;
+ friend bool operator!=(no_gt, no_gt) noexcept;
+ friend bool operator<(no_gt, no_gt) noexcept;
+ friend bool operator>(no_gt, no_gt) = delete;
+ friend bool operator>=(no_gt, no_gt) noexcept;
+ friend bool operator<=(no_gt, no_gt) noexcept;
+};
+
+struct no_le {
+ friend bool operator==(no_le, no_le) noexcept;
+ friend bool operator!=(no_le, no_le) noexcept;
+ friend bool operator<(no_le, no_le) noexcept;
+ friend bool operator>(no_le, no_le) noexcept;
+ friend bool operator>=(no_le, no_le) = delete;
+ friend bool operator<=(no_le, no_le) noexcept;
+};
+
+struct no_ge {
+ friend bool operator==(no_ge, no_ge) noexcept;
+ friend bool operator!=(no_ge, no_ge) noexcept;
+ friend bool operator<(no_ge, no_ge) noexcept;
+ friend bool operator>(no_ge, no_ge) noexcept;
+ friend bool operator>=(no_ge, no_ge) noexcept;
+ friend bool operator<=(no_ge, no_ge) = delete;
+};
+
+struct wrong_return_type_eq {
+ void operator==(wrong_return_type_eq) const noexcept;
+ bool operator!=(wrong_return_type_eq) const noexcept;
+ bool operator<(wrong_return_type_eq) const noexcept;
+ bool operator>(wrong_return_type_eq) const noexcept;
+ bool 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;
+ bool operator<(wrong_return_type_ne) const noexcept;
+ bool operator>(wrong_return_type_ne) const noexcept;
+ bool operator>=(wrong_return_type_ne) const noexcept;
+ bool operator<=(wrong_return_type_ne) const noexcept;
+};
+
+struct wrong_return_type_lt {
+ bool operator==(wrong_return_type_lt) const noexcept;
+ bool operator!=(wrong_return_type_lt) const noexcept;
+ void operator<(wrong_return_type_lt) const noexcept;
+ bool operator>(wrong_return_type_lt) const noexcept;
+ bool operator>=(wrong_return_type_lt) const noexcept;
+ bool operator<=(wrong_return_type_lt) const noexcept;
+};
+
+struct wrong_return_type_gt {
+ bool operator==(wrong_return_type_gt) const noexcept;
+ bool operator!=(wrong_return_type_gt) const noexcept;
+ bool operator<(wrong_return_type_gt) const noexcept;
+ void operator>(wrong_return_type_gt) const noexcept;
+ bool operator>=(wrong_return_type_gt) const noexcept;
+ bool operator<=(wrong_return_type_gt) const noexcept;
+};
+
+struct wrong_return_type_le {
+ bool operator==(wrong_return_type_le) const noexcept;
+ bool operator!=(wrong_return_type_le) const noexcept;
+ bool operator<(wrong_return_type_le) const noexcept;
+ bool operator>(wrong_return_type_le) const noexcept;
+ void operator>=(wrong_return_type_le) const noexcept;
+ bool operator<=(wrong_return_type_le) const noexcept;
+};
+
+struct wrong_return_type_ge {
+ bool operator==(wrong_return_type_ge) const noexcept;
+ bool operator!=(wrong_return_type_ge) const noexcept;
+ bool operator<(wrong_return_type_ge) const noexcept;
+ bool operator>(wrong_return_type_ge) const noexcept;
+ bool operator>=(wrong_return_type_ge) const noexcept;
+ void operator<=(wrong_return_type_ge) const noexcept;
+};
+
+struct wrong_return_type {
+ void operator==(wrong_return_type) const noexcept;
+ void operator!=(wrong_return_type) const noexcept;
+ void operator<(wrong_return_type) const noexcept;
+ void operator>(wrong_return_type) const noexcept;
+ void operator>=(wrong_return_type) const noexcept;
+ void operator<=(wrong_return_type_ge) 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;
+ bool
+ 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;
+ bool
+ 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 bool
+ 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 bool
+ 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 totally_ordered_with_others {
+ auto operator<=>(totally_ordered_with_others const&) const = default;
+};
+
+struct no_lt_not_totally_ordered_with {
+ [[nodiscard]] bool
+ operator==(no_lt_not_totally_ordered_with const&) const = default;
+ [[nodiscard]] auto
+ operator<=>(no_lt_not_totally_ordered_with const&) const = default;
+ operator totally_ordered_with_others() const noexcept;
+
+ [[nodiscard]] bool operator==(totally_ordered_with_others const&) const;
+ [[nodiscard]] auto operator<=>(totally_ordered_with_others const&) const;
+ [[nodiscard]] auto operator<(totally_ordered_with_others const&) const;
+};
+
+struct no_gt_not_totally_ordered_with {
+ [[nodiscard]] bool
+ operator==(no_gt_not_totally_ordered_with const&) const = default;
+ [[nodiscard]] auto
+ operator<=>(no_gt_not_totally_ordered_with const&) const = default;
+ operator totally_ordered_with_others() const noexcept;
+
+ [[nodiscard]] bool operator==(totally_ordered_with_others const&) const;
+ [[nodiscard]] auto operator<=>(totally_ordered_with_others const&) const;
+ [[nodiscard]] auto operator>(totally_ordered_with_others const&) const;
+};
+
+struct no_le_not_totally_ordered_with {
+ [[nodiscard]] bool
+ operator==(no_le_not_totally_ordered_with const&) const = default;
+ [[nodiscard]] auto
+ operator<=>(no_le_not_totally_ordered_with const&) const = default;
+ operator totally_ordered_with_others() const noexcept;
+
+ [[nodiscard]] bool operator==(totally_ordered_with_others const&) const;
+ [[nodiscard]] auto operator<=>(totally_ordered_with_others const&) const;
+ [[nodiscard]] auto operator<=(totally_ordered_with_others const&) const;
+};
+
+struct no_ge_not_totally_ordered_with {
+ [[nodiscard]] bool
+ operator==(no_ge_not_totally_ordered_with const&) const = default;
+ [[nodiscard]] auto
+ operator<=>(no_ge_not_totally_ordered_with const&) const = default;
+ operator totally_ordered_with_others() const noexcept;
+
+ [[nodiscard]] bool operator==(totally_ordered_with_others const&) const;
+ [[nodiscard]] auto operator<=>(totally_ordered_with_others const&) const;
+ [[nodiscard]] auto operator>=(totally_ordered_with_others const&) const;
+};
+
+struct partial_ordering_totally_ordered_with {
+ [[nodiscard]] auto operator<=>(
+ partial_ordering_totally_ordered_with const&) const noexcept = default;
+ [[nodiscard]] std::partial_ordering
+ operator<=>(totally_ordered_with_others const&) const noexcept;
+
+ operator totally_ordered_with_others() const;
+};
+
+struct weak_ordering_totally_ordered_with {
+ [[nodiscard]] auto operator<=>(
+ weak_ordering_totally_ordered_with const&) const noexcept = default;
+ [[nodiscard]] std::weak_ordering
+ operator<=>(totally_ordered_with_others const&) const noexcept;
+
+ operator totally_ordered_with_others() const;
+};
+
+struct strong_ordering_totally_ordered_with {
+ [[nodiscard]] auto operator<=>(
+ strong_ordering_totally_ordered_with const&) const noexcept = default;
+ [[nodiscard]] std::strong_ordering
+ operator<=>(totally_ordered_with_others const&) const noexcept;
+
+ operator totally_ordered_with_others() const;
+};
+
+struct eq_returns_explicit_bool {
+ friend explicit_bool operator==(eq_returns_explicit_bool,
+ eq_returns_explicit_bool);
+ friend bool operator!=(eq_returns_explicit_bool, eq_returns_explicit_bool);
+ friend bool operator<(eq_returns_explicit_bool, eq_returns_explicit_bool);
+ friend bool operator>(eq_returns_explicit_bool, eq_returns_explicit_bool);
+ friend bool operator<=(eq_returns_explicit_bool, eq_returns_explicit_bool);
+ friend bool operator>=(eq_returns_explicit_bool, eq_returns_explicit_bool);
+
+ operator totally_ordered_with_others() const;
+
+ friend explicit_bool operator==(eq_returns_explicit_bool,
+ totally_ordered_with_others);
+ friend explicit_bool operator==(totally_ordered_with_others,
+ eq_returns_explicit_bool);
+ friend bool operator!=(eq_returns_explicit_bool, totally_ordered_with_others);
+ friend bool operator!=(totally_ordered_with_others, eq_returns_explicit_bool);
+ friend bool operator<(eq_returns_explicit_bool, totally_ordered_with_others);
+ friend bool operator<(totally_ordered_with_others, eq_returns_explicit_bool);
+ friend bool operator>(eq_returns_explicit_bool, totally_ordered_with_others);
+ friend bool operator>(totally_ordered_with_others, eq_returns_explicit_bool);
+ friend bool operator<=(eq_returns_explicit_bool, totally_ordered_with_others);
+ friend bool operator<=(totally_ordered_with_others, eq_returns_explicit_bool);
+ friend bool operator>=(eq_returns_explicit_bool, totally_ordered_with_others);
+ friend bool operator>=(totally_ordered_with_others, eq_returns_explicit_bool);
+};
+
+struct ne_returns_explicit_bool {
+ friend bool operator==(ne_returns_explicit_bool, ne_returns_explicit_bool);
+ friend explicit_bool operator!=(ne_returns_explicit_bool,
+ ne_returns_explicit_bool);
+ friend bool operator<(ne_returns_explicit_bool, ne_returns_explicit_bool);
+ friend bool operator>(ne_returns_explicit_bool, ne_returns_explicit_bool);
+ friend bool operator<=(ne_returns_explicit_bool, ne_returns_explicit_bool);
+ friend bool operator>=(ne_returns_explicit_bool, ne_returns_explicit_bool);
+
+ operator totally_ordered_with_others() const;
+
+ friend bool operator==(ne_returns_explicit_bool, totally_ordered_with_others);
+ friend explicit_bool operator!=(ne_returns_explicit_bool,
+ totally_ordered_with_others);
+ friend explicit_bool operator!=(totally_ordered_with_others,
+ ne_returns_explicit_bool);
+ friend bool operator<(ne_returns_explicit_bool, totally_ordered_with_others);
+ friend bool operator<(totally_ordered_with_others, ne_returns_explicit_bool);
+ friend bool operator>(ne_returns_explicit_bool, totally_ordered_with_others);
+ friend bool operator>(totally_ordered_with_others, ne_returns_explicit_bool);
+ friend bool operator<=(ne_returns_explicit_bool, totally_ordered_with_others);
+ friend bool operator<=(totally_ordered_with_others, ne_returns_explicit_bool);
+ friend bool operator>=(ne_returns_explicit_bool, totally_ordered_with_others);
+ friend bool operator>=(totally_ordered_with_others, ne_returns_explicit_bool);
+};
+
+struct lt_returns_explicit_bool {
+ friend bool operator==(lt_returns_explicit_bool, lt_returns_explicit_bool);
+ friend bool operator!=(lt_returns_explicit_bool, lt_returns_explicit_bool);
+ friend explicit_bool operator<(lt_returns_explicit_bool,
+ lt_returns_explicit_bool);
+ friend bool operator>(lt_returns_explicit_bool, lt_returns_explicit_bool);
+ friend bool operator<=(lt_returns_explicit_bool, lt_returns_explicit_bool);
+ friend bool operator>=(lt_returns_explicit_bool, lt_returns_explicit_bool);
+
+ operator totally_ordered_with_others() const;
+
+ friend bool operator==(lt_returns_explicit_bool, totally_ordered_with_others);
+ friend bool operator!=(lt_returns_explicit_bool, totally_ordered_with_others);
+ friend bool operator!=(totally_ordered_with_others, lt_returns_explicit_bool);
+ friend explicit_bool operator<(lt_returns_explicit_bool,
+ totally_ordered_with_others);
+ friend bool operator<(totally_ordered_with_others, lt_returns_explicit_bool);
+ friend bool operator>(lt_returns_explicit_bool, totally_ordered_with_others);
+ friend bool operator>(totally_ordered_with_others, lt_returns_explicit_bool);
+ friend bool operator<=(lt_returns_explicit_bool, totally_ordered_with_others);
+ friend bool operator<=(totally_ordered_with_others, lt_returns_explicit_bool);
+ friend bool operator>=(lt_returns_explicit_bool, totally_ordered_with_others);
+ friend bool operator>=(totally_ordered_with_others, lt_returns_explicit_bool);
+};
+
+struct gt_returns_explicit_bool {
+ friend bool operator==(gt_returns_explicit_bool, gt_returns_explicit_bool);
+ friend bool operator!=(gt_returns_explicit_bool, gt_returns_explicit_bool);
+ friend bool operator<(gt_returns_explicit_bool, gt_returns_explicit_bool);
+ friend explicit_bool operator>(gt_returns_explicit_bool,
+ gt_returns_explicit_bool);
+ friend bool operator<=(gt_returns_explicit_bool, gt_returns_explicit_bool);
+ friend bool operator>=(gt_returns_explicit_bool, gt_returns_explicit_bool);
+
+ operator totally_ordered_with_others() const;
+
+ friend bool operator==(gt_returns_explicit_bool, totally_ordered_with_others);
+ friend bool operator!=(gt_returns_explicit_bool, totally_ordered_with_others);
+ friend bool operator!=(totally_ordered_with_others, gt_returns_explicit_bool);
+ friend bool operator<(gt_returns_explicit_bool, totally_ordered_with_others);
+ friend bool operator<(totally_ordered_with_others, gt_returns_explicit_bool);
+ friend explicit_bool operator>(gt_returns_explicit_bool,
+ totally_ordered_with_others);
+ friend bool operator>(totally_ordered_with_others, gt_returns_explicit_bool);
+ friend bool operator<=(gt_returns_explicit_bool, totally_ordered_with_others);
+ friend bool operator<=(totally_ordered_with_others, gt_returns_explicit_bool);
+ friend bool operator>=(gt_returns_explicit_bool, totally_ordered_with_others);
+ friend bool operator>=(totally_ordered_with_others, gt_returns_explicit_bool);
+};
+
+struct le_returns_explicit_bool {
+ friend bool operator==(le_returns_explicit_bool, le_returns_explicit_bool);
+ friend bool operator!=(le_returns_explicit_bool, le_returns_explicit_bool);
+ friend bool operator<(le_returns_explicit_bool, le_returns_explicit_bool);
+ friend bool operator>(le_returns_explicit_bool, le_returns_explicit_bool);
+ friend explicit_bool operator<=(le_returns_explicit_bool,
+ le_returns_explicit_bool);
+ friend bool operator>=(le_returns_explicit_bool, le_returns_explicit_bool);
+
+ operator totally_ordered_with_others() const;
+
+ friend bool operator==(le_returns_explicit_bool, totally_ordered_with_others);
+ friend bool operator!=(le_returns_explicit_bool, totally_ordered_with_others);
+ friend bool operator!=(totally_ordered_with_others, le_returns_explicit_bool);
+ friend bool operator<(le_returns_explicit_bool, totally_ordered_with_others);
+ friend bool operator<(totally_ordered_with_others, le_returns_explicit_bool);
+ friend bool operator>(le_returns_explicit_bool, totally_ordered_with_others);
+ friend bool operator>(totally_ordered_with_others, le_returns_explicit_bool);
+ friend bool operator<=(le_returns_explicit_bool, totally_ordered_with_others);
+ friend explicit_bool operator<=(totally_ordered_with_others,
+ le_returns_explicit_bool);
+ friend bool operator>=(le_returns_explicit_bool, totally_ordered_with_others);
+ friend bool operator>=(totally_ordered_with_others, le_returns_explicit_bool);
+};
+
+struct ge_returns_explicit_bool {
+ friend bool operator==(ge_returns_explicit_bool, ge_returns_explicit_bool);
+ friend bool operator!=(ge_returns_explicit_bool, ge_returns_explicit_bool);
+ friend bool operator<(ge_returns_explicit_bool, ge_returns_explicit_bool);
+ friend bool operator>(ge_returns_explicit_bool, ge_returns_explicit_bool);
+ friend bool operator<=(ge_returns_explicit_bool, ge_returns_explicit_bool);
+ friend explicit_bool operator>=(ge_returns_explicit_bool,
+ ge_returns_explicit_bool);
+
+ operator totally_ordered_with_others() const;
+
+ friend bool operator==(ge_returns_explicit_bool, totally_ordered_with_others);
+ friend bool operator!=(ge_returns_explicit_bool, totally_ordered_with_others);
+ friend bool operator!=(totally_ordered_with_others, ge_returns_explicit_bool);
+ friend bool operator<(ge_returns_explicit_bool, totally_ordered_with_others);
+ friend bool operator<(totally_ordered_with_others, ge_returns_explicit_bool);
+ friend bool operator>(ge_returns_explicit_bool, totally_ordered_with_others);
+ friend bool operator>(totally_ordered_with_others, ge_returns_explicit_bool);
+ friend bool operator<=(ge_returns_explicit_bool, totally_ordered_with_others);
+ friend bool operator<=(totally_ordered_with_others, ge_returns_explicit_bool);
+ friend bool operator>=(ge_returns_explicit_bool, totally_ordered_with_others);
+ friend explicit_bool operator>=(totally_ordered_with_others,
+ ge_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);
+ friend std::true_type operator<(returns_true_type, 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);
+ friend std::true_type operator>=(returns_true_type, returns_true_type);
+
+ operator totally_ordered_with_others() const;
+
+ friend std::true_type operator==(returns_true_type,
+ totally_ordered_with_others);
+ friend std::true_type operator==(totally_ordered_with_others,
+ returns_true_type);
+ friend std::true_type operator!=(returns_true_type,
+ totally_ordered_with_others);
+ friend std::true_type operator!=(totally_ordered_with_others,
+ returns_true_type);
+ friend std::true_type operator<(returns_true_type,
+ totally_ordered_with_others);
+ friend std::true_type operator<(totally_ordered_with_others,
+ returns_true_type);
+ friend std::true_type operator>(returns_true_type,
+ totally_ordered_with_others);
+ friend std::true_type operator>(totally_ordered_with_others,
+ returns_true_type);
+ friend std::true_type operator<=(returns_true_type,
+ totally_ordered_with_others);
+ friend std::true_type operator<=(totally_ordered_with_others,
+ returns_true_type);
+ friend std::true_type operator>=(returns_true_type,
+ totally_ordered_with_others);
+ friend std::true_type operator>=(totally_ordered_with_others,
+ returns_true_type);
+};
+
+struct returns_int_ptr {
+ friend int* operator==(returns_int_ptr, returns_int_ptr);
+ friend int* operator!=(returns_int_ptr, returns_int_ptr);
+ friend int* operator<(returns_int_ptr, returns_int_ptr);
+ friend int* operator>(returns_int_ptr, returns_int_ptr);
+ friend int* operator<=(returns_int_ptr, returns_int_ptr);
+ friend int* operator>=(returns_int_ptr, returns_int_ptr);
+
+ operator totally_ordered_with_others() const;
+
+ friend int* operator==(returns_int_ptr, totally_ordered_with_others);
+ friend int* operator==(totally_ordered_with_others, returns_int_ptr);
+ friend int* operator!=(returns_int_ptr, totally_ordered_with_others);
+ friend int* operator!=(totally_ordered_with_others, returns_int_ptr);
+ friend int* operator<(returns_int_ptr, totally_ordered_with_others);
+ friend int* operator<(totally_ordered_with_others, returns_int_ptr);
+ friend int* operator>(returns_int_ptr, totally_ordered_with_others);
+ friend int* operator>(totally_ordered_with_others, returns_int_ptr);
+ friend int* operator<=(returns_int_ptr, totally_ordered_with_others);
+ friend int* operator<=(totally_ordered_with_others, returns_int_ptr);
+ friend int* operator>=(returns_int_ptr, totally_ordered_with_others);
+ friend int* operator>=(totally_ordered_with_others, returns_int_ptr);
+};
+
+#endif // TEST_STD_CONCEPTS_COMPARISON_TYPES_H
diff --git a/libcxx/test/std/concepts/lang/assignable.compile.pass.cpp b/libcxx/test/std/concepts/concepts.lang/concept.assignable/assignable_from.compile.pass.cpp
index 1278f84c10b5..1278f84c10b5 100644
--- a/libcxx/test/std/concepts/lang/assignable.compile.pass.cpp
+++ b/libcxx/test/std/concepts/concepts.lang/concept.assignable/assignable_from.compile.pass.cpp
diff --git a/libcxx/test/std/concepts/lang/common.compile.pass.cpp b/libcxx/test/std/concepts/concepts.lang/concept.common/common_with.compile.pass.cpp
index d66d00d37080..d66d00d37080 100644
--- a/libcxx/test/std/concepts/lang/common.compile.pass.cpp
+++ b/libcxx/test/std/concepts/concepts.lang/concept.common/common_with.compile.pass.cpp
diff --git a/libcxx/test/std/concepts/lang/commonreference.compile.pass.cpp b/libcxx/test/std/concepts/concepts.lang/concept.commonref/common_reference.compile.pass.cpp
index 114058e5cf6f..114058e5cf6f 100644
--- a/libcxx/test/std/concepts/lang/commonreference.compile.pass.cpp
+++ b/libcxx/test/std/concepts/concepts.lang/concept.commonref/common_reference.compile.pass.cpp
diff --git a/libcxx/test/std/concepts/concept.constructible/constructible_from.compile.pass.cpp b/libcxx/test/std/concepts/concepts.lang/concept.constructible/constructible_from.compile.pass.cpp
index 2e59b42c3da1..4db2f9299192 100644
--- a/libcxx/test/std/concepts/concept.constructible/constructible_from.compile.pass.cpp
+++ b/libcxx/test/std/concepts/concepts.lang/concept.constructible/constructible_from.compile.pass.cpp
@@ -149,3 +149,5 @@ void test() {
test<std::array<int, 1>, int>();
test<std::array<int, 1>, int, int>();
}
+
+int main(int, char**) { return 0; }
diff --git a/libcxx/test/std/concepts/lang/convertible.compile.pass.cpp b/libcxx/test/std/concepts/concepts.lang/concept.convertible/convertible_to.pass.cpp
index c1818deee9f9..c1818deee9f9 100644
--- a/libcxx/test/std/concepts/lang/convertible.compile.pass.cpp
+++ b/libcxx/test/std/concepts/concepts.lang/concept.convertible/convertible_to.pass.cpp
diff --git a/libcxx/test/std/concepts/lang/copyconstructible.compile.pass.cpp b/libcxx/test/std/concepts/concepts.lang/concept.copyconstructible/copy_constructible.compile.pass.cpp
index 95fcb7e62017..95fcb7e62017 100644
--- a/libcxx/test/std/concepts/lang/copyconstructible.compile.pass.cpp
+++ b/libcxx/test/std/concepts/concepts.lang/concept.copyconstructible/copy_constructible.compile.pass.cpp
diff --git a/libcxx/test/std/concepts/concept.default.init/default_initializable.compile.pass.cpp b/libcxx/test/std/concepts/concepts.lang/concept.default.init/default_initializable.compile.pass.cpp
index 3519c57f3b97..3519c57f3b97 100644
--- a/libcxx/test/std/concepts/concept.default.init/default_initializable.compile.pass.cpp
+++ b/libcxx/test/std/concepts/concepts.lang/concept.default.init/default_initializable.compile.pass.cpp
diff --git a/libcxx/test/std/concepts/concept.default.init/default_initializable.verify.cpp b/libcxx/test/std/concepts/concepts.lang/concept.default.init/default_initializable.verify.cpp
index 789846e21b24..789846e21b24 100644
--- a/libcxx/test/std/concepts/concept.default.init/default_initializable.verify.cpp
+++ b/libcxx/test/std/concepts/concepts.lang/concept.default.init/default_initializable.verify.cpp
diff --git a/libcxx/test/std/concepts/lang/derived.compile.pass.cpp b/libcxx/test/std/concepts/concepts.lang/concept.derived/derived_from.pass.cpp
index f8b57e46b69e..f8b57e46b69e 100644
--- a/libcxx/test/std/concepts/lang/derived.compile.pass.cpp
+++ b/libcxx/test/std/concepts/concepts.lang/concept.derived/derived_from.pass.cpp
diff --git a/libcxx/test/std/concepts/concept.destructible/destructible.compile.pass.cpp b/libcxx/test/std/concepts/concepts.lang/concept.destructible/destructible.compile.pass.cpp
index 06c1d893fd89..06c1d893fd89 100644
--- a/libcxx/test/std/concepts/concept.destructible/destructible.compile.pass.cpp
+++ b/libcxx/test/std/concepts/concepts.lang/concept.destructible/destructible.compile.pass.cpp
diff --git a/libcxx/test/std/concepts/lang/moveconstructible.compile.pass.cpp b/libcxx/test/std/concepts/concepts.lang/concept.moveconstructible/move_constructible.compile.pass.cpp
index 7a1b81588b85..7a1b81588b85 100644
--- a/libcxx/test/std/concepts/lang/moveconstructible.compile.pass.cpp
+++ b/libcxx/test/std/concepts/concepts.lang/concept.moveconstructible/move_constructible.compile.pass.cpp
diff --git a/libcxx/test/std/concepts/lang/same_as.pass.cpp b/libcxx/test/std/concepts/concepts.lang/concept.same/same_as.pass.cpp
index 7d39946335f8..7d39946335f8 100644
--- a/libcxx/test/std/concepts/lang/same_as.pass.cpp
+++ b/libcxx/test/std/concepts/concepts.lang/concept.same/same_as.pass.cpp
diff --git a/libcxx/test/std/concepts/lang/swappable.pass.cpp b/libcxx/test/std/concepts/concepts.lang/concept.swappable/swappable.pass.cpp
index 657577676849..657577676849 100644
--- a/libcxx/test/std/concepts/lang/swappable.pass.cpp
+++ b/libcxx/test/std/concepts/concepts.lang/concept.swappable/swappable.pass.cpp
diff --git a/libcxx/test/std/concepts/lang/swappable_with.compile.pass.cpp b/libcxx/test/std/concepts/concepts.lang/concept.swappable/swappable_with.compile.pass.cpp
index 46e526dcd0c8..e0772b51d818 100644
--- a/libcxx/test/std/concepts/lang/swappable_with.compile.pass.cpp
+++ b/libcxx/test/std/concepts/concepts.lang/concept.swappable/swappable_with.compile.pass.cpp
@@ -15,6 +15,7 @@
#include <concepts>
#include <array>
+#include <cassert>
#include <deque>
#include <forward_list>
#include <list>
@@ -555,7 +556,7 @@ struct swappable_with_rvalue_ref_to_volatile_s3 {
friend void swap(swappable_with_rvalue_ref_to_volatile_s3 volatile&&,
s3 volatile&&);
- operator s3 volatile &() volatile;
+ operator s3 volatile &&() volatile;
};
static_assert(
std::swappable_with<swappable_with_rvalue_ref_to_volatile_s3 volatile&&,
@@ -578,7 +579,7 @@ struct swappable_with_rvalue_ref_to_cv_s3 {
friend void swap(swappable_with_rvalue_ref_to_cv_s3 const volatile&&,
s3 const volatile&&);
- operator s3 const volatile &() const volatile;
+ operator s3 const volatile &&() const volatile;
};
static_assert(
std::swappable_with<swappable_with_rvalue_ref_to_cv_s3 const volatile&&,
@@ -644,4 +645,42 @@ static_assert(
static_assert(!check_swappable_with<HasANonMovable, HasANonMovable>());
} // namespace types_with_purpose
-int main(int, char**) { return 0; }
+namespace LWG3175 {
+// Example taken directly from [concept.swappable]
+template <class T, std::swappable_with<T> U>
+constexpr void value_swap(T&& t, U&& u) {
+ std::ranges::swap(std::forward<T>(t), std::forward<U>(u));
+}
+
+template <std::swappable T>
+constexpr void lv_swap(T& t1, T& t2) {
+ std::ranges::swap(t1, t2);
+}
+
+namespace N {
+struct A {
+ int m;
+};
+struct Proxy {
+ A* a;
+ constexpr Proxy(A& a_) : a{&a_} {}
+ friend constexpr void swap(Proxy x, Proxy y) {
+ std::ranges::swap(*x.a, *y.a);
+ }
+};
+constexpr Proxy proxy(A& a) { return Proxy{a}; }
+} // namespace N
+
+[[nodiscard]] constexpr bool CheckRegression() {
+ int i = 1, j = 2;
+ lv_swap(i, j);
+ assert(i == 2 && j == 1);
+
+ N::A a1 = {5}, a2 = {-5};
+ value_swap(a1, proxy(a2));
+ assert(a1.m == -5 && a2.m == 5);
+ return true;
+}
+
+static_assert(CheckRegression());
+} // namespace LWG3175
diff --git a/libcxx/test/std/concepts/concepts.lang/concepts.arithmetic/arithmetic.h b/libcxx/test/std/concepts/concepts.lang/concepts.arithmetic/arithmetic.h
new file mode 100644
index 000000000000..bb7016508cca
--- /dev/null
+++ b/libcxx/test/std/concepts/concepts.lang/concepts.arithmetic/arithmetic.h
@@ -0,0 +1,37 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 LIBCXX_TEST_CONCEPTS_LANG_CONCEPTS_ARITHMETIC_H_
+#define LIBCXX_TEST_CONCEPTS_LANG_CONCEPTS_ARITHMETIC_H_
+
+#include <concepts>
+
+// This overload should never be called. It exists solely to force subsumption.
+template <std::integral I>
+[[nodiscard]] constexpr bool CheckSubsumption(I) {
+ return false;
+}
+
+// clang-format off
+template <std::integral I>
+requires std::signed_integral<I> && (!std::unsigned_integral<I>)
+[[nodiscard]] constexpr bool CheckSubsumption(I) {
+ return std::is_signed_v<I>;
+}
+
+template <std::integral I>
+requires std::unsigned_integral<I> && (!std::signed_integral<I>)
+[[nodiscard]] constexpr bool CheckSubsumption(I) {
+ return std::is_unsigned_v<I>;
+}
+// clang-format on
+
+enum ClassicEnum { a, b, c };
+enum class ScopedEnum { x, y, z };
+struct EmptyStruct {};
+
+#endif // LIBCXX_TEST_CONCEPTS_LANG_CONCEPTS_ARITHMETIC_H_
diff --git a/libcxx/test/std/concepts/concepts.lang/concepts.arithmetic/floating_point.pass.cpp b/libcxx/test/std/concepts/concepts.lang/concepts.arithmetic/floating_point.pass.cpp
new file mode 100644
index 000000000000..b540ceb4a06b
--- /dev/null
+++ b/libcxx/test/std/concepts/concepts.lang/concepts.arithmetic/floating_point.pass.cpp
@@ -0,0 +1,79 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 floating_point = // see below
+
+#include <concepts>
+#include <type_traits>
+
+#include "arithmetic.h"
+
+template <typename T>
+constexpr bool CheckFloatingPointQualifiers() {
+ constexpr bool result = std::floating_point<T>;
+ static_assert(std::floating_point<const T> == result);
+ static_assert(std::floating_point<volatile T> == result);
+ static_assert(std::floating_point<const volatile T> == result);
+
+ static_assert(!std::floating_point<T&>);
+ static_assert(!std::floating_point<const T&>);
+ static_assert(!std::floating_point<volatile T&>);
+ static_assert(!std::floating_point<const volatile T&>);
+
+ static_assert(!std::floating_point<T&&>);
+ static_assert(!std::floating_point<const T&&>);
+ static_assert(!std::floating_point<volatile T&&>);
+ static_assert(!std::floating_point<const volatile T&&>);
+
+ static_assert(!std::floating_point<T*>);
+ static_assert(!std::floating_point<const T*>);
+ static_assert(!std::floating_point<volatile T*>);
+ static_assert(!std::floating_point<const volatile T*>);
+
+ static_assert(!std::floating_point<T (*)()>);
+ static_assert(!std::floating_point<T (&)()>);
+ static_assert(!std::floating_point<T(&&)()>);
+
+ return result;
+}
+
+// floating-point types
+static_assert(CheckFloatingPointQualifiers<float>());
+static_assert(CheckFloatingPointQualifiers<double>());
+static_assert(CheckFloatingPointQualifiers<long double>());
+
+// types that aren't floating-point
+static_assert(!CheckFloatingPointQualifiers<signed char>());
+static_assert(!CheckFloatingPointQualifiers<unsigned char>());
+static_assert(!CheckFloatingPointQualifiers<short>());
+static_assert(!CheckFloatingPointQualifiers<unsigned short>());
+static_assert(!CheckFloatingPointQualifiers<int>());
+static_assert(!CheckFloatingPointQualifiers<unsigned int>());
+static_assert(!CheckFloatingPointQualifiers<long>());
+static_assert(!CheckFloatingPointQualifiers<unsigned long>());
+static_assert(!CheckFloatingPointQualifiers<long long>());
+static_assert(!CheckFloatingPointQualifiers<unsigned long long>());
+static_assert(!CheckFloatingPointQualifiers<wchar_t>());
+static_assert(!CheckFloatingPointQualifiers<bool>());
+static_assert(!CheckFloatingPointQualifiers<char>());
+static_assert(!CheckFloatingPointQualifiers<char8_t>());
+static_assert(!CheckFloatingPointQualifiers<char16_t>());
+static_assert(!CheckFloatingPointQualifiers<char32_t>());
+static_assert(!std::floating_point<void>);
+
+static_assert(!CheckFloatingPointQualifiers<ClassicEnum>());
+static_assert(!CheckFloatingPointQualifiers<ScopedEnum>());
+static_assert(!CheckFloatingPointQualifiers<EmptyStruct>());
+static_assert(!CheckFloatingPointQualifiers<int EmptyStruct::*>());
+static_assert(!CheckFloatingPointQualifiers<int (EmptyStruct::*)()>());
+
+int main(int, char**) { return 0; }
diff --git a/libcxx/test/std/concepts/concepts.lang/concepts.arithmetic/integral.pass.cpp b/libcxx/test/std/concepts/concepts.lang/concepts.arithmetic/integral.pass.cpp
new file mode 100644
index 000000000000..42b85a1c020b
--- /dev/null
+++ b/libcxx/test/std/concepts/concepts.lang/concepts.arithmetic/integral.pass.cpp
@@ -0,0 +1,92 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 integral = // see below
+
+#include <concepts>
+#include <type_traits>
+
+#include "arithmetic.h"
+
+template <typename T>
+constexpr bool CheckIntegralQualifiers() {
+ constexpr bool result = std::integral<T>;
+ static_assert(std::integral<const T> == result);
+ static_assert(std::integral<volatile T> == result);
+ static_assert(std::integral<const volatile T> == result);
+
+ static_assert(!std::integral<T&>);
+ static_assert(!std::integral<const T&>);
+ static_assert(!std::integral<volatile T&>);
+ static_assert(!std::integral<const volatile T&>);
+
+ static_assert(!std::integral<T&&>);
+ static_assert(!std::integral<const T&&>);
+ static_assert(!std::integral<volatile T&&>);
+ static_assert(!std::integral<const volatile T&&>);
+
+ static_assert(!std::integral<T*>);
+ static_assert(!std::integral<const T*>);
+ static_assert(!std::integral<volatile T*>);
+ static_assert(!std::integral<const volatile T*>);
+
+ static_assert(!std::integral<T (*)()>);
+ static_assert(!std::integral<T (&)()>);
+ static_assert(!std::integral<T(&&)()>);
+
+ return result;
+}
+
+// standard signed and unsigned integers
+static_assert(CheckIntegralQualifiers<signed char>());
+static_assert(CheckIntegralQualifiers<unsigned char>());
+static_assert(CheckIntegralQualifiers<short>());
+static_assert(CheckIntegralQualifiers<unsigned short>());
+static_assert(CheckIntegralQualifiers<int>());
+static_assert(CheckIntegralQualifiers<unsigned int>());
+static_assert(CheckIntegralQualifiers<long>());
+static_assert(CheckIntegralQualifiers<unsigned long>());
+static_assert(CheckIntegralQualifiers<long long>());
+static_assert(CheckIntegralQualifiers<unsigned long long>());
+
+// extended integers
+#ifndef _LIBCPP_HAS_NO_INT128
+static_assert(CheckIntegralQualifiers<__int128_t>());
+static_assert(CheckIntegralQualifiers<__uint128_t>());
+#endif
+
+// bool and char types are also integral
+static_assert(CheckIntegralQualifiers<wchar_t>());
+static_assert(CheckIntegralQualifiers<bool>());
+static_assert(CheckIntegralQualifiers<char>());
+static_assert(CheckIntegralQualifiers<char8_t>());
+static_assert(CheckIntegralQualifiers<char16_t>());
+static_assert(CheckIntegralQualifiers<char32_t>());
+
+// types that aren't integral
+static_assert(!std::integral<void>);
+static_assert(!CheckIntegralQualifiers<float>());
+static_assert(!CheckIntegralQualifiers<double>());
+static_assert(!CheckIntegralQualifiers<long double>());
+
+static_assert(!CheckIntegralQualifiers<ClassicEnum>());
+
+static_assert(!CheckIntegralQualifiers<ScopedEnum>());
+
+static_assert(!CheckIntegralQualifiers<EmptyStruct>());
+static_assert(!CheckIntegralQualifiers<int EmptyStruct::*>());
+static_assert(!CheckIntegralQualifiers<int (EmptyStruct::*)()>());
+
+static_assert(CheckSubsumption(0));
+static_assert(CheckSubsumption(0U));
+
+int main(int, char**) { return 0; }
diff --git a/libcxx/test/std/concepts/concepts.lang/concepts.arithmetic/signed_integral.pass.cpp b/libcxx/test/std/concepts/concepts.lang/concepts.arithmetic/signed_integral.pass.cpp
new file mode 100644
index 000000000000..df97b39709dc
--- /dev/null
+++ b/libcxx/test/std/concepts/concepts.lang/concepts.arithmetic/signed_integral.pass.cpp
@@ -0,0 +1,96 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 signed_integral = // see below
+
+#include <concepts>
+#include <type_traits>
+
+#include "arithmetic.h"
+
+template <typename T>
+constexpr bool CheckSignedIntegralQualifiers() {
+ constexpr bool result = std::signed_integral<T>;
+ static_assert(std::signed_integral<const T> == result);
+ static_assert(std::signed_integral<volatile T> == result);
+ static_assert(std::signed_integral<const volatile T> == result);
+
+ static_assert(!std::signed_integral<T&>);
+ static_assert(!std::signed_integral<const T&>);
+ static_assert(!std::signed_integral<volatile T&>);
+ static_assert(!std::signed_integral<const volatile T&>);
+
+ static_assert(!std::signed_integral<T&&>);
+ static_assert(!std::signed_integral<const T&&>);
+ static_assert(!std::signed_integral<volatile T&&>);
+ static_assert(!std::signed_integral<const volatile T&&>);
+
+ static_assert(!std::signed_integral<T*>);
+ static_assert(!std::signed_integral<const T*>);
+ static_assert(!std::signed_integral<volatile T*>);
+ static_assert(!std::signed_integral<const volatile T*>);
+
+ static_assert(!std::signed_integral<T (*)()>);
+ static_assert(!std::signed_integral<T (&)()>);
+ static_assert(!std::signed_integral<T(&&)()>);
+
+ return result;
+}
+
+// standard signed integers
+static_assert(CheckSignedIntegralQualifiers<signed char>());
+static_assert(CheckSignedIntegralQualifiers<short>());
+static_assert(CheckSignedIntegralQualifiers<int>());
+static_assert(CheckSignedIntegralQualifiers<long>());
+static_assert(CheckSignedIntegralQualifiers<long long>());
+
+// bool and character *may* be signed
+static_assert(CheckSignedIntegralQualifiers<wchar_t>() ==
+ std::is_signed_v<wchar_t>);
+static_assert(CheckSignedIntegralQualifiers<bool>() == std::is_signed_v<bool>);
+static_assert(CheckSignedIntegralQualifiers<char>() == std::is_signed_v<char>);
+static_assert(CheckSignedIntegralQualifiers<char8_t>() ==
+ std::is_signed_v<char8_t>);
+static_assert(CheckSignedIntegralQualifiers<char16_t>() ==
+ std::is_signed_v<char16_t>);
+static_assert(CheckSignedIntegralQualifiers<char32_t>() ==
+ std::is_signed_v<char32_t>);
+
+// integers that aren't signed integrals
+static_assert(!CheckSignedIntegralQualifiers<unsigned char>());
+static_assert(!CheckSignedIntegralQualifiers<unsigned short>());
+static_assert(!CheckSignedIntegralQualifiers<unsigned int>());
+static_assert(!CheckSignedIntegralQualifiers<unsigned long>());
+static_assert(!CheckSignedIntegralQualifiers<unsigned long long>());
+
+// extended integers
+#ifndef _LIBCPP_HAS_NO_INT128
+static_assert(CheckSignedIntegralQualifiers<__int128_t>());
+static_assert(!CheckSignedIntegralQualifiers<__uint128_t>());
+#endif
+
+// types that aren't even integers shouldn't be signed integers!
+static_assert(!std::signed_integral<void>);
+static_assert(!CheckSignedIntegralQualifiers<float>());
+static_assert(!CheckSignedIntegralQualifiers<double>());
+static_assert(!CheckSignedIntegralQualifiers<long double>());
+
+static_assert(!CheckSignedIntegralQualifiers<ClassicEnum>());
+static_assert(!CheckSignedIntegralQualifiers<ScopedEnum>());
+static_assert(!CheckSignedIntegralQualifiers<EmptyStruct>());
+static_assert(!CheckSignedIntegralQualifiers<int EmptyStruct::*>());
+static_assert(!CheckSignedIntegralQualifiers<int (EmptyStruct::*)()>());
+
+static_assert(CheckSubsumption(0));
+static_assert(CheckSubsumption(0U));
+
+int main(int, char**) { return 0; }
diff --git a/libcxx/test/std/concepts/concepts.lang/concepts.arithmetic/unsigned_integral.pass.cpp b/libcxx/test/std/concepts/concepts.lang/concepts.arithmetic/unsigned_integral.pass.cpp
new file mode 100644
index 000000000000..02a62865f2dd
--- /dev/null
+++ b/libcxx/test/std/concepts/concepts.lang/concepts.arithmetic/unsigned_integral.pass.cpp
@@ -0,0 +1,97 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 unsigned_integral = // see below
+
+#include <concepts>
+#include <type_traits>
+
+#include "arithmetic.h"
+
+template <typename T>
+constexpr bool CheckUnsignedIntegralQualifiers() {
+ constexpr bool result = std::unsigned_integral<T>;
+ static_assert(std::unsigned_integral<const T> == result);
+ static_assert(std::unsigned_integral<volatile T> == result);
+ static_assert(std::unsigned_integral<const volatile T> == result);
+
+ static_assert(!std::unsigned_integral<T&>);
+ static_assert(!std::unsigned_integral<const T&>);
+ static_assert(!std::unsigned_integral<volatile T&>);
+ static_assert(!std::unsigned_integral<const volatile T&>);
+
+ static_assert(!std::unsigned_integral<T&&>);
+ static_assert(!std::unsigned_integral<const T&&>);
+ static_assert(!std::unsigned_integral<volatile T&&>);
+ static_assert(!std::unsigned_integral<const volatile T&&>);
+
+ static_assert(!std::unsigned_integral<T*>);
+ static_assert(!std::unsigned_integral<const T*>);
+ static_assert(!std::unsigned_integral<volatile T*>);
+ static_assert(!std::unsigned_integral<const volatile T*>);
+
+ static_assert(!std::unsigned_integral<T (*)()>);
+ static_assert(!std::unsigned_integral<T (&)()>);
+ static_assert(!std::unsigned_integral<T(&&)()>);
+
+ return result;
+}
+
+// standard unsigned types
+static_assert(CheckUnsignedIntegralQualifiers<unsigned char>());
+static_assert(CheckUnsignedIntegralQualifiers<unsigned short>());
+static_assert(CheckUnsignedIntegralQualifiers<unsigned int>());
+static_assert(CheckUnsignedIntegralQualifiers<unsigned long>());
+static_assert(CheckUnsignedIntegralQualifiers<unsigned long long>());
+
+// Whether bool and character types are signed or unsigned is impl-defined
+static_assert(CheckUnsignedIntegralQualifiers<wchar_t>() ==
+ !std::is_signed_v<wchar_t>);
+static_assert(CheckUnsignedIntegralQualifiers<bool>() ==
+ !std::is_signed_v<bool>);
+static_assert(CheckUnsignedIntegralQualifiers<char>() ==
+ !std::is_signed_v<char>);
+static_assert(CheckUnsignedIntegralQualifiers<char8_t>() ==
+ !std::is_signed_v<char8_t>);
+static_assert(CheckUnsignedIntegralQualifiers<char16_t>() ==
+ !std::is_signed_v<char16_t>);
+static_assert(CheckUnsignedIntegralQualifiers<char32_t>() ==
+ !std::is_signed_v<char32_t>);
+
+// extended integers
+#ifndef _LIBCPP_HAS_NO_INT128
+static_assert(CheckUnsignedIntegralQualifiers<__uint128_t>());
+static_assert(!CheckUnsignedIntegralQualifiers<__int128_t>());
+#endif
+
+// integer types that aren't unsigned integrals
+static_assert(!CheckUnsignedIntegralQualifiers<signed char>());
+static_assert(!CheckUnsignedIntegralQualifiers<short>());
+static_assert(!CheckUnsignedIntegralQualifiers<int>());
+static_assert(!CheckUnsignedIntegralQualifiers<long>());
+static_assert(!CheckUnsignedIntegralQualifiers<long long>());
+
+static_assert(!std::unsigned_integral<void>);
+static_assert(!CheckUnsignedIntegralQualifiers<float>());
+static_assert(!CheckUnsignedIntegralQualifiers<double>());
+static_assert(!CheckUnsignedIntegralQualifiers<long double>());
+
+static_assert(!CheckUnsignedIntegralQualifiers<ClassicEnum>());
+static_assert(!CheckUnsignedIntegralQualifiers<ScopedEnum>());
+static_assert(!CheckUnsignedIntegralQualifiers<EmptyStruct>());
+static_assert(!CheckUnsignedIntegralQualifiers<int EmptyStruct::*>());
+static_assert(!CheckUnsignedIntegralQualifiers<int (EmptyStruct::*)()>());
+
+static_assert(CheckSubsumption(0));
+static_assert(CheckSubsumption(0U));
+
+int main(int, char**) { return 0; }
diff --git a/libcxx/test/std/concepts/object/copyable.compile.pass.cpp b/libcxx/test/std/concepts/concepts.object/copyable.compile.pass.cpp
index 9d589f937879..9d589f937879 100644
--- a/libcxx/test/std/concepts/object/copyable.compile.pass.cpp
+++ b/libcxx/test/std/concepts/concepts.object/copyable.compile.pass.cpp
diff --git a/libcxx/test/std/concepts/object/movable.compile.pass.cpp b/libcxx/test/std/concepts/concepts.object/movable.compile.pass.cpp
index 5459dcd1940d..5459dcd1940d 100644
--- a/libcxx/test/std/concepts/object/movable.compile.pass.cpp
+++ b/libcxx/test/std/concepts/concepts.object/movable.compile.pass.cpp
diff --git a/libcxx/test/std/concepts/object/regular.compile.pass.cpp b/libcxx/test/std/concepts/concepts.object/regular.compile.pass.cpp
index a70e265984eb..a70e265984eb 100644
--- a/libcxx/test/std/concepts/object/regular.compile.pass.cpp
+++ b/libcxx/test/std/concepts/concepts.object/regular.compile.pass.cpp
diff --git a/libcxx/test/std/concepts/object/semiregular.compile.pass.cpp b/libcxx/test/std/concepts/concepts.object/semiregular.compile.pass.cpp
index 19c773f04369..19c773f04369 100644
--- a/libcxx/test/std/concepts/object/semiregular.compile.pass.cpp
+++ b/libcxx/test/std/concepts/concepts.object/semiregular.compile.pass.cpp
diff --git a/libcxx/test/std/concepts/lang/arithmetic.pass.cpp b/libcxx/test/std/concepts/lang/arithmetic.pass.cpp
deleted file mode 100644
index 9b7b75b27cc1..000000000000
--- a/libcxx/test/std/concepts/lang/arithmetic.pass.cpp
+++ /dev/null
@@ -1,346 +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
-//
-//===----------------------------------------------------------------------===//
-
-// UNSUPPORTED: c++03, c++11, c++14, c++17
-// UNSUPPORTED: libcpp-no-concepts
-
-// template<class T>
-// concept integral = // see below
-
-// template<class T>
-// concept signed_integral = // see below
-
-// template<class T>
-// concept unsigned_integral = // see below
-
-// template<class T>
-// concept floating_point = // see below
-
-#include <concepts>
-#include <type_traits>
-
-namespace {
-template <typename T>
-constexpr bool CheckIntegralQualifiers() {
- constexpr bool result = std::integral<T>;
- static_assert(std::integral<const T> == result);
- static_assert(std::integral<volatile T> == result);
- static_assert(std::integral<const volatile T> == result);
-
- static_assert(!std::integral<T&>);
- static_assert(!std::integral<const T&>);
- static_assert(!std::integral<volatile T&>);
- static_assert(!std::integral<const volatile T&>);
-
- static_assert(!std::integral<T&&>);
- static_assert(!std::integral<const T&&>);
- static_assert(!std::integral<volatile T&&>);
- static_assert(!std::integral<const volatile T&&>);
-
- static_assert(!std::integral<T*>);
- static_assert(!std::integral<const T*>);
- static_assert(!std::integral<volatile T*>);
- static_assert(!std::integral<const volatile T*>);
-
- static_assert(!std::integral<T (*)()>);
- static_assert(!std::integral<T (&)()>);
- static_assert(!std::integral<T(&&)()>);
-
- return result;
-}
-
-enum ClassicEnum { a, b, c };
-enum class ScopedEnum { x, y, z };
-struct EmptyStruct {};
-
-constexpr void CheckIntegral() {
- // standard signed and unsigned integers
- static_assert(CheckIntegralQualifiers<signed char>());
- static_assert(CheckIntegralQualifiers<unsigned char>());
- static_assert(CheckIntegralQualifiers<short>());
- static_assert(CheckIntegralQualifiers<unsigned short>());
- static_assert(CheckIntegralQualifiers<int>());
- static_assert(CheckIntegralQualifiers<unsigned int>());
- static_assert(CheckIntegralQualifiers<long>());
- static_assert(CheckIntegralQualifiers<unsigned long>());
- static_assert(CheckIntegralQualifiers<long long>());
- static_assert(CheckIntegralQualifiers<unsigned long long>());
-
- // extended integers
-#ifndef _LIBCPP_HAS_NO_INT128
- static_assert(CheckIntegralQualifiers<__int128_t>());
- static_assert(CheckIntegralQualifiers<__uint128_t>());
-#endif
-
- // bool and char types are also integral
- static_assert(CheckIntegralQualifiers<wchar_t>());
- static_assert(CheckIntegralQualifiers<bool>());
- static_assert(CheckIntegralQualifiers<char>());
- static_assert(CheckIntegralQualifiers<char8_t>());
- static_assert(CheckIntegralQualifiers<char16_t>());
- static_assert(CheckIntegralQualifiers<char32_t>());
-
- // types that aren't integral
- static_assert(!std::integral<void>);
- static_assert(!CheckIntegralQualifiers<float>());
- static_assert(!CheckIntegralQualifiers<double>());
- static_assert(!CheckIntegralQualifiers<long double>());
-
- static_assert(!CheckIntegralQualifiers<ClassicEnum>());
-
- static_assert(!CheckIntegralQualifiers<ScopedEnum>());
-
- static_assert(!CheckIntegralQualifiers<EmptyStruct>());
- static_assert(!CheckIntegralQualifiers<int EmptyStruct::*>());
- static_assert(!CheckIntegralQualifiers<int (EmptyStruct::*)()>());
-}
-
-template <typename T>
-constexpr bool CheckSignedIntegralQualifiers() {
- constexpr bool result = std::signed_integral<T>;
- static_assert(std::signed_integral<const T> == result);
- static_assert(std::signed_integral<volatile T> == result);
- static_assert(std::signed_integral<const volatile T> == result);
-
- static_assert(!std::signed_integral<T&>);
- static_assert(!std::signed_integral<const T&>);
- static_assert(!std::signed_integral<volatile T&>);
- static_assert(!std::signed_integral<const volatile T&>);
-
- static_assert(!std::signed_integral<T&&>);
- static_assert(!std::signed_integral<const T&&>);
- static_assert(!std::signed_integral<volatile T&&>);
- static_assert(!std::signed_integral<const volatile T&&>);
-
- static_assert(!std::signed_integral<T*>);
- static_assert(!std::signed_integral<const T*>);
- static_assert(!std::signed_integral<volatile T*>);
- static_assert(!std::signed_integral<const volatile T*>);
-
- static_assert(!std::signed_integral<T (*)()>);
- static_assert(!std::signed_integral<T (&)()>);
- static_assert(!std::signed_integral<T(&&)()>);
-
- return result;
-}
-
-constexpr void CheckSignedIntegral() {
- // standard signed integers
- static_assert(CheckSignedIntegralQualifiers<signed char>());
- static_assert(CheckSignedIntegralQualifiers<short>());
- static_assert(CheckSignedIntegralQualifiers<int>());
- static_assert(CheckSignedIntegralQualifiers<long>());
- static_assert(CheckSignedIntegralQualifiers<long long>());
-
- // bool and character *may* be signed
- static_assert(CheckSignedIntegralQualifiers<wchar_t>() ==
- std::is_signed_v<wchar_t>);
- static_assert(CheckSignedIntegralQualifiers<bool>() ==
- std::is_signed_v<bool>);
- static_assert(CheckSignedIntegralQualifiers<char>() ==
- std::is_signed_v<char>);
- static_assert(CheckSignedIntegralQualifiers<char8_t>() ==
- std::is_signed_v<char8_t>);
- static_assert(CheckSignedIntegralQualifiers<char16_t>() ==
- std::is_signed_v<char16_t>);
- static_assert(CheckSignedIntegralQualifiers<char32_t>() ==
- std::is_signed_v<char32_t>);
-
- // integers that aren't signed integrals
- static_assert(!CheckSignedIntegralQualifiers<unsigned char>());
- static_assert(!CheckSignedIntegralQualifiers<unsigned short>());
- static_assert(!CheckSignedIntegralQualifiers<unsigned int>());
- static_assert(!CheckSignedIntegralQualifiers<unsigned long>());
- static_assert(!CheckSignedIntegralQualifiers<unsigned long long>());
-
- // extended integers
-#ifndef _LIBCPP_HAS_NO_INT128
- static_assert(CheckSignedIntegralQualifiers<__int128_t>());
- static_assert(!CheckSignedIntegralQualifiers<__uint128_t>());
-#endif
-
- // types that aren't even integers shouldn't be signed integers!
- static_assert(!std::signed_integral<void>);
- static_assert(!CheckSignedIntegralQualifiers<float>());
- static_assert(!CheckSignedIntegralQualifiers<double>());
- static_assert(!CheckSignedIntegralQualifiers<long double>());
-
- static_assert(!CheckSignedIntegralQualifiers<ClassicEnum>());
- static_assert(!CheckSignedIntegralQualifiers<ScopedEnum>());
- static_assert(!CheckSignedIntegralQualifiers<EmptyStruct>());
- static_assert(!CheckSignedIntegralQualifiers<int EmptyStruct::*>());
- static_assert(!CheckSignedIntegralQualifiers<int (EmptyStruct::*)()>());
-}
-
-template <typename T>
-constexpr bool CheckUnsignedIntegralQualifiers() {
- constexpr bool result = std::unsigned_integral<T>;
- static_assert(std::unsigned_integral<const T> == result);
- static_assert(std::unsigned_integral<volatile T> == result);
- static_assert(std::unsigned_integral<const volatile T> == result);
-
- static_assert(!std::unsigned_integral<T&>);
- static_assert(!std::unsigned_integral<const T&>);
- static_assert(!std::unsigned_integral<volatile T&>);
- static_assert(!std::unsigned_integral<const volatile T&>);
-
- static_assert(!std::unsigned_integral<T&&>);
- static_assert(!std::unsigned_integral<const T&&>);
- static_assert(!std::unsigned_integral<volatile T&&>);
- static_assert(!std::unsigned_integral<const volatile T&&>);
-
- static_assert(!std::unsigned_integral<T*>);
- static_assert(!std::unsigned_integral<const T*>);
- static_assert(!std::unsigned_integral<volatile T*>);
- static_assert(!std::unsigned_integral<const volatile T*>);
-
- static_assert(!std::unsigned_integral<T (*)()>);
- static_assert(!std::unsigned_integral<T (&)()>);
- static_assert(!std::unsigned_integral<T(&&)()>);
-
- return result;
-}
-
-constexpr void CheckUnsignedIntegral() {
- // standard unsigned types
- static_assert(CheckUnsignedIntegralQualifiers<unsigned char>());
- static_assert(CheckUnsignedIntegralQualifiers<unsigned short>());
- static_assert(CheckUnsignedIntegralQualifiers<unsigned int>());
- static_assert(CheckUnsignedIntegralQualifiers<unsigned long>());
- static_assert(CheckUnsignedIntegralQualifiers<unsigned long long>());
-
- // Whether bool and character types are signed or unsigned is impl-defined
- static_assert(CheckUnsignedIntegralQualifiers<wchar_t>() ==
- !std::is_signed_v<wchar_t>);
- static_assert(CheckUnsignedIntegralQualifiers<bool>() ==
- !std::is_signed_v<bool>);
- static_assert(CheckUnsignedIntegralQualifiers<char>() ==
- !std::is_signed_v<char>);
- static_assert(CheckUnsignedIntegralQualifiers<char8_t>() ==
- !std::is_signed_v<char8_t>);
- static_assert(CheckUnsignedIntegralQualifiers<char16_t>() ==
- !std::is_signed_v<char16_t>);
- static_assert(CheckUnsignedIntegralQualifiers<char32_t>() ==
- !std::is_signed_v<char32_t>);
-
- // extended integers
-#ifndef _LIBCPP_HAS_NO_INT128
- static_assert(CheckUnsignedIntegralQualifiers<__uint128_t>());
- static_assert(!CheckUnsignedIntegralQualifiers<__int128_t>());
-#endif
-
- // integer types that aren't unsigned integrals
- static_assert(!CheckUnsignedIntegralQualifiers<signed char>());
- static_assert(!CheckUnsignedIntegralQualifiers<short>());
- static_assert(!CheckUnsignedIntegralQualifiers<int>());
- static_assert(!CheckUnsignedIntegralQualifiers<long>());
- static_assert(!CheckUnsignedIntegralQualifiers<long long>());
-
- static_assert(!std::unsigned_integral<void>);
- static_assert(!CheckUnsignedIntegralQualifiers<float>());
- static_assert(!CheckUnsignedIntegralQualifiers<double>());
- static_assert(!CheckUnsignedIntegralQualifiers<long double>());
-
- static_assert(!CheckUnsignedIntegralQualifiers<ClassicEnum>());
- static_assert(!CheckUnsignedIntegralQualifiers<ScopedEnum>());
- static_assert(!CheckUnsignedIntegralQualifiers<EmptyStruct>());
- static_assert(!CheckUnsignedIntegralQualifiers<int EmptyStruct::*>());
- static_assert(!CheckUnsignedIntegralQualifiers<int (EmptyStruct::*)()>());
-}
-
-// This overload should never be called. It exists solely to force subsumption.
-template <std::integral I>
-[[nodiscard]] constexpr bool CheckSubsumption(I) {
- return false;
-}
-
-// clang-format off
-template <std::integral I>
-requires std::signed_integral<I> && (!std::unsigned_integral<I>)
-[[nodiscard]] constexpr bool CheckSubsumption(I) {
- return std::is_signed_v<I>;
-}
-
-template <std::integral I>
-requires std::unsigned_integral<I> && (!std::signed_integral<I>)
-[[nodiscard]] constexpr bool CheckSubsumption(I) {
- return std::is_unsigned_v<I>;
-}
-// clang-format on
-
-template <typename T>
-constexpr bool CheckFloatingPointQualifiers() {
- constexpr bool result = std::floating_point<T>;
- static_assert(std::floating_point<const T> == result);
- static_assert(std::floating_point<volatile T> == result);
- static_assert(std::floating_point<const volatile T> == result);
-
- static_assert(!std::floating_point<T&>);
- static_assert(!std::floating_point<const T&>);
- static_assert(!std::floating_point<volatile T&>);
- static_assert(!std::floating_point<const volatile T&>);
-
- static_assert(!std::floating_point<T&&>);
- static_assert(!std::floating_point<const T&&>);
- static_assert(!std::floating_point<volatile T&&>);
- static_assert(!std::floating_point<const volatile T&&>);
-
- static_assert(!std::floating_point<T*>);
- static_assert(!std::floating_point<const T*>);
- static_assert(!std::floating_point<volatile T*>);
- static_assert(!std::floating_point<const volatile T*>);
-
- static_assert(!std::floating_point<T (*)()>);
- static_assert(!std::floating_point<T (&)()>);
- static_assert(!std::floating_point<T(&&)()>);
-
- return result;
-}
-
-constexpr void CheckFloatingPoint() {
- // floating-point types
- static_assert(CheckFloatingPointQualifiers<float>());
- static_assert(CheckFloatingPointQualifiers<double>());
- static_assert(CheckFloatingPointQualifiers<long double>());
-
- // types that aren't floating-point
- static_assert(!CheckFloatingPointQualifiers<signed char>());
- static_assert(!CheckFloatingPointQualifiers<unsigned char>());
- static_assert(!CheckFloatingPointQualifiers<short>());
- static_assert(!CheckFloatingPointQualifiers<unsigned short>());
- static_assert(!CheckFloatingPointQualifiers<int>());
- static_assert(!CheckFloatingPointQualifiers<unsigned int>());
- static_assert(!CheckFloatingPointQualifiers<long>());
- static_assert(!CheckFloatingPointQualifiers<unsigned long>());
- static_assert(!CheckFloatingPointQualifiers<long long>());
- static_assert(!CheckFloatingPointQualifiers<unsigned long long>());
- static_assert(!CheckFloatingPointQualifiers<wchar_t>());
- static_assert(!CheckFloatingPointQualifiers<bool>());
- static_assert(!CheckFloatingPointQualifiers<char>());
- static_assert(!CheckFloatingPointQualifiers<char8_t>());
- static_assert(!CheckFloatingPointQualifiers<char16_t>());
- static_assert(!CheckFloatingPointQualifiers<char32_t>());
- static_assert(!std::floating_point<void>);
-
- static_assert(!CheckFloatingPointQualifiers<ClassicEnum>());
- static_assert(!CheckFloatingPointQualifiers<ScopedEnum>());
- static_assert(!CheckFloatingPointQualifiers<EmptyStruct>());
- static_assert(!CheckFloatingPointQualifiers<int EmptyStruct::*>());
- static_assert(!CheckFloatingPointQualifiers<int (EmptyStruct::*)()>());
-}
-} // namespace
-
-int main(int, char**) {
- CheckIntegral();
- CheckSignedIntegral();
- CheckUnsignedIntegral();
- static_assert(CheckSubsumption(0));
- static_assert(CheckSubsumption(0U));
- CheckFloatingPoint();
- return 0;
-}