diff options
Diffstat (limited to 'libcxx/test/std/concepts')
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; -} |