diff --git a/libcxx/test/std/concepts/callable/functions.h b/libcxx/test/std/concepts/callable/functions.h deleted file mode 100644 --- 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 - 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 --- a/libcxx/test/std/concepts/callable/invocable.compile.pass.cpp +++ b/libcxx/test/std/concepts/callable/invocable.compile.pass.cpp @@ -18,17 +18,41 @@ #include #include -#include "functions.h" +template +[[nodiscard]] constexpr bool check_invocable() { + constexpr bool result = std::invocable; + static_assert(std::invocable == result); + static_assert(std::invocable == result); + static_assert(std::invocable == result); + static_assert(std::invocable == result); + static_assert(std::invocable == result); -// clang-format off -template -requires std::invocable -constexpr void ModelsInvocable(F, Args&&...) noexcept{} + return result; +} -template -requires(!std::invocable) -constexpr void NotInvocable(F, Args&&...) noexcept {} -// clang-format on +static_assert(check_invocable()); +static_assert(check_invocable()); +static_assert(check_invocable()); +static_assert(check_invocable()); +static_assert(check_invocable()); +static_assert(check_invocable()); + +struct S; +static_assert(check_invocable()); +static_assert(check_invocable()); +static_assert(std::invocable); +static_assert(std::invocable); +static_assert(std::invocable); +static_assert(std::invocable); + +static_assert(!std::invocable); +static_assert(!std::invocable); +static_assert(!std::invocable); +static_assert(!std::invocable); +static_assert(std::invocable >); +static_assert(std::invocable >); +static_assert(!std::invocable); +static_assert(!std::invocable); static_assert(!std::invocable); static_assert(!std::invocable); @@ -36,84 +60,372 @@ static_assert(!std::invocable); static_assert(!std::invocable); -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(); - ModelsInvocable(&A::I, Up); - ModelsInvocable(&A::F, Up); - ModelsInvocable(&A::G, Up, 0); - NotInvocable(&A::H, Up, 0); - } - { - auto Sp = std::make_shared(); - 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(); - ModelsInvocable(&L2rSorted::operator(), Up, 0, 1, 2); - NotInvocable(&L2rSorted::operator(), Up); - NotInvocable(&L2rSorted::operator(), Up, 0); - NotInvocable(&L2rSorted::operator(), Up, 0, 1); - } - { - auto Sp = std::make_shared(); - ModelsInvocable(&L2rSorted::operator(), Sp, 0, 1, 2); - NotInvocable(&L2rSorted::operator(), Sp); - NotInvocable(&L2rSorted::operator(), Sp, 0); - NotInvocable(&L2rSorted::operator(), Sp, 0, 1); - } - } +namespace function_objects { +struct function_object { + void operator()(); +}; +static_assert(std::invocable); +static_assert(!std::invocable); +static_assert(!std::invocable); +static_assert(!std::invocable); +static_assert(std::invocable); +static_assert(!std::invocable); +static_assert(!std::invocable); +static_assert(!std::invocable); + +struct const_function_object { + void operator()(int) const; +}; +static_assert(std::invocable); +static_assert(std::invocable); +static_assert(!std::invocable); +static_assert(!std::invocable); +static_assert(std::invocable); +static_assert(std::invocable); +static_assert(!std::invocable); +static_assert(!std::invocable); + +struct volatile_function_object { + void operator()(int, int) volatile; +}; +static_assert(std::invocable); +static_assert(!std::invocable); +static_assert(std::invocable); +static_assert( + !std::invocable); +static_assert(std::invocable); +static_assert(!std::invocable); +static_assert(std::invocable); +static_assert( + !std::invocable); + +struct cv_function_object { + void operator()(int[]) const volatile; +}; +static_assert(std::invocable); +static_assert(std::invocable); +static_assert(std::invocable); +static_assert(std::invocable); +static_assert(std::invocable); +static_assert(std::invocable); +static_assert(std::invocable); +static_assert(std::invocable); + +struct lvalue_function_object { + void operator()() &; +}; +static_assert(!std::invocable); +static_assert(!std::invocable); +static_assert(!std::invocable); +static_assert(!std::invocable); +static_assert(std::invocable); +static_assert(!std::invocable); +static_assert(!std::invocable); +static_assert(!std::invocable); + +struct lvalue_const_function_object { + void operator()(int) const&; +}; +static_assert(std::invocable); +static_assert(std::invocable); +static_assert(!std::invocable); +static_assert( + !std::invocable); +static_assert(std::invocable); +static_assert(std::invocable); +static_assert(!std::invocable); +static_assert( + !std::invocable); + +struct lvalue_volatile_function_object { + void operator()(int, int) volatile&; +}; +static_assert(!std::invocable); +static_assert(!std::invocable); +static_assert( + !std::invocable); +static_assert( + !std::invocable); +static_assert(std::invocable); +static_assert( + !std::invocable); +static_assert( + std::invocable); +static_assert( + !std::invocable); + +struct lvalue_cv_function_object { + void operator()(int[]) const volatile&; +}; +static_assert(!std::invocable); +static_assert(!std::invocable); +static_assert(!std::invocable); +static_assert(!std::invocable); +static_assert(std::invocable); +static_assert(std::invocable); +static_assert(std::invocable); +static_assert(std::invocable); +// +struct rvalue_function_object { + void operator()() &&; +}; +static_assert(std::invocable); +static_assert(!std::invocable); +static_assert(!std::invocable); +static_assert(!std::invocable); +static_assert(!std::invocable); +static_assert(!std::invocable); +static_assert(!std::invocable); +static_assert(!std::invocable); + +struct rvalue_const_function_object { + void operator()(int) const&&; +}; +static_assert(std::invocable); +static_assert(std::invocable); +static_assert(!std::invocable); +static_assert( + !std::invocable); +static_assert(!std::invocable); +static_assert(!std::invocable); +static_assert(!std::invocable); +static_assert( + !std::invocable); + +struct rvalue_volatile_function_object { + void operator()(int, int) volatile&&; +}; +static_assert(std::invocable); +static_assert(!std::invocable); +static_assert( + std::invocable); +static_assert( + !std::invocable); +static_assert(!std::invocable); +static_assert( + !std::invocable); +static_assert( + !std::invocable); +static_assert( + !std::invocable); + +struct rvalue_cv_function_object { + void operator()(int[]) const volatile&&; +}; +static_assert(std::invocable); +static_assert(std::invocable); +static_assert(std::invocable); +static_assert(std::invocable); +static_assert(!std::invocable); +static_assert(!std::invocable); +static_assert(!std::invocable); +static_assert(!std::invocable); + +struct multiple_overloads { + bool operator()(); + void operator()(int); + int operator()(double); +}; +static_assert(std::invocable); +static_assert(std::invocable); +static_assert(std::invocable); +static_assert(!std::invocable); +static_assert(std::invocable); +static_assert(std::invocable); +static_assert(std::invocable); +static_assert(std::invocable); +static_assert(!std::invocable); +static_assert(std::invocable); +static_assert(std::invocable); +} // namespace function_objects + +namespace pointer_to_member_functions { +// clang-format off + template + [[nodiscard]] constexpr bool check_member_is_invocable() { - auto G = std::mt19937_64( - std::chrono::high_resolution_clock().now().time_since_epoch().count()); - auto D = std::uniform_int_distribution<>(); - ModelsInvocable(D, G); + constexpr bool result = std::invocable; + using uncv_t = std::remove_cvref_t; + static_assert(std::invocable == result); + static_assert(std::invocable, Args...> == result); + static_assert(std::invocable, Args...> == result); + static_assert(!std::invocable); + static_assert(!std::invocable); + static_assert(!std::invocable); + static_assert(!std::invocable); + struct S2 {}; + static_assert(!std::invocable); + return result; } - return 0; +// clang-format on + +static_assert(check_member_is_invocable()); +static_assert(std::invocable); +static_assert(std::invocable); +static_assert(std::invocable); +static_assert(std::invocable); +static_assert(std::invocable); +static_assert(std::invocable); +static_assert(std::invocable); +static_assert(std::invocable); + +static_assert(check_member_is_invocable()); +static_assert(!check_member_is_invocable()); +using unqualified = void (S::*)(); +static_assert(std::invocable); +static_assert(!std::invocable); +static_assert(!std::invocable); +static_assert(!std::invocable); +static_assert(std::invocable); +static_assert(!std::invocable); +static_assert(!std::invocable); +static_assert(!std::invocable); + +static_assert(check_member_is_invocable()); +using const_qualified = void (S::*)() const; +static_assert(std::invocable); +static_assert(std::invocable); +static_assert(!std::invocable); +static_assert(!std::invocable); +static_assert(std::invocable); +static_assert(std::invocable); +static_assert(!std::invocable); +static_assert(!std::invocable); + +static_assert( + check_member_is_invocable()); +using volatile_qualified = void (S::*)() volatile; +static_assert(std::invocable); +static_assert(!std::invocable); +static_assert(std::invocable); +static_assert(!std::invocable); +static_assert(std::invocable); +static_assert(!std::invocable); +static_assert(std::invocable); +static_assert(!std::invocable); + +static_assert(check_member_is_invocable()); +using cv_qualified = void (S::*)() const volatile; +static_assert(std::invocable); +static_assert(std::invocable); +static_assert(std::invocable); +static_assert(std::invocable); +static_assert(std::invocable); +static_assert(std::invocable); +static_assert(std::invocable); +static_assert(std::invocable); + +static_assert(check_member_is_invocable()); +using lvalue_qualified = void (S::*)() &; +static_assert(std::invocable); +static_assert(!std::invocable); +static_assert(!std::invocable); +static_assert(!std::invocable); +static_assert(!std::invocable); +static_assert(!std::invocable); +static_assert(!std::invocable); +static_assert(!std::invocable); + +static_assert(check_member_is_invocable()); +using lvalue_const_qualified = void (S::*)() const&; +static_assert(std::invocable); +static_assert(std::invocable); +static_assert(!std::invocable); +static_assert(!std::invocable); +static_assert(std::invocable); +static_assert(std::invocable); +static_assert(!std::invocable); +static_assert(!std::invocable); + +static_assert(check_member_is_invocable()); +using lvalue_volatile_qualified = void (S::*)() volatile&; +static_assert(std::invocable); +static_assert(!std::invocable); +static_assert(std::invocable); +static_assert(!std::invocable); +static_assert(!std::invocable); +static_assert(!std::invocable); +static_assert(!std::invocable); +static_assert(!std::invocable); + +static_assert(check_member_is_invocable()); +using lvalue_cv_qualified = void (S::*)() const volatile&; +static_assert(std::invocable); +static_assert(std::invocable); +static_assert(std::invocable); +static_assert(std::invocable); +static_assert(!std::invocable); +static_assert(!std::invocable); +static_assert(!std::invocable); +static_assert(!std::invocable); + +using rvalue_unqualified = void (S::*)() &&; +static_assert(!std::invocable); +static_assert(!std::invocable); +static_assert(!std::invocable); +static_assert(!std::invocable); +static_assert(std::invocable); +static_assert(!std::invocable); +static_assert(!std::invocable); +static_assert(!std::invocable); + +using rvalue_const_unqualified = void (S::*)() const&&; +static_assert(!std::invocable); +static_assert(!std::invocable); +static_assert(!std::invocable); +static_assert(!std::invocable); +static_assert(std::invocable); +static_assert(std::invocable); +static_assert(!std::invocable); +static_assert(!std::invocable); + +using rvalue_volatile_unqualified = void (S::*)() volatile&&; +static_assert(!std::invocable); +static_assert(!std::invocable); +static_assert(!std::invocable); +static_assert(!std::invocable); +static_assert(std::invocable); +static_assert(!std::invocable); +static_assert(std::invocable); +static_assert(!std::invocable); + +using rvalue_cv_unqualified = void (S::*)() const volatile&&; +static_assert(!std::invocable); +static_assert(!std::invocable); +static_assert(!std::invocable); +static_assert(!std::invocable); +static_assert(std::invocable); +static_assert(std::invocable); +static_assert(std::invocable); +static_assert(std::invocable); +} // namespace pointer_to_member_functions + +// std::invocable-specific +static_assert( + std::invocable, std::mt19937_64&>); + +[[nodiscard]] constexpr bool check_lambda(auto, auto...) { return false; } + +// clang-format off +template +requires std::invocable +[[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/callable/regularinvocable.compile.pass.cpp b/libcxx/test/std/concepts/callable/regularinvocable.compile.pass.cpp --- a/libcxx/test/std/concepts/callable/regularinvocable.compile.pass.cpp +++ b/libcxx/test/std/concepts/callable/regularinvocable.compile.pass.cpp @@ -12,22 +12,49 @@ // template // concept regular_invocable; +#include #include #include #include #include -#include "functions.h" +template +[[nodiscard]] constexpr bool check_invocable() { + constexpr bool result = std::regular_invocable; + static_assert(std::regular_invocable == result); + static_assert(std::regular_invocable == result); + static_assert(std::regular_invocable == + result); + static_assert(std::regular_invocable == result); + static_assert(std::regular_invocable == + result); -// clang-format off -template -requires std::regular_invocable -constexpr void ModelsRegularInvocable(F, Args&&...) noexcept {} + return result; +} -template -requires (!std::regular_invocable) -constexpr void NotRegularInvocable(F, Args&&...) noexcept {} -// clang-format on +static_assert(check_invocable()); +static_assert(check_invocable()); +static_assert(check_invocable()); +static_assert(check_invocable()); +static_assert(check_invocable()); +static_assert(check_invocable()); + +struct S; +static_assert(check_invocable()); +static_assert(check_invocable()); +static_assert(std::regular_invocable); +static_assert(std::regular_invocable); +static_assert(std::regular_invocable); +static_assert(std::regular_invocable); + +static_assert(!std::regular_invocable); +static_assert(!std::regular_invocable); +static_assert(!std::regular_invocable); +static_assert(!std::regular_invocable); +static_assert(std::regular_invocable >); +static_assert(std::regular_invocable >); +static_assert(!std::regular_invocable); +static_assert(!std::regular_invocable); static_assert(!std::regular_invocable); static_assert(!std::regular_invocable); @@ -35,84 +62,411 @@ static_assert(!std::regular_invocable); static_assert(!std::regular_invocable); -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(); - ModelsRegularInvocable(&A::I, Up); - ModelsRegularInvocable(&A::F, Up); - ModelsRegularInvocable(&A::G, Up, 0); - NotRegularInvocable(&A::H, Up, 0); - } - { - auto Sp = std::make_shared(); - ModelsRegularInvocable(&A::I, Sp); - ModelsRegularInvocable(&A::F, Sp); - ModelsRegularInvocable(&A::G, Sp, 0); - NotRegularInvocable(&A::H, Sp, 0); - } - } +namespace function_objects { +struct function_object { + void operator()(); +}; +static_assert(std::regular_invocable); +static_assert(!std::regular_invocable); +static_assert(!std::regular_invocable); +static_assert(!std::regular_invocable); +static_assert(std::regular_invocable); +static_assert(!std::regular_invocable); +static_assert(!std::regular_invocable); +static_assert(!std::regular_invocable); + +struct const_function_object { + void operator()(int) const; +}; +static_assert(std::regular_invocable); +static_assert(std::regular_invocable); +static_assert(!std::regular_invocable); +static_assert( + !std::regular_invocable); +static_assert(std::regular_invocable); +static_assert(std::regular_invocable); +static_assert(!std::regular_invocable); +static_assert( + !std::regular_invocable); + +struct volatile_function_object { + void operator()(int, int) volatile; +}; +static_assert(std::regular_invocable); +static_assert( + !std::regular_invocable); +static_assert( + std::regular_invocable); +static_assert( + !std::regular_invocable); +static_assert(std::regular_invocable); +static_assert( + !std::regular_invocable); +static_assert( + std::regular_invocable); +static_assert(!std::regular_invocable); + +struct cv_function_object { + void operator()(int[]) const volatile; +}; +static_assert(std::regular_invocable); +static_assert(std::regular_invocable); +static_assert(std::regular_invocable); +static_assert(std::regular_invocable); +static_assert(std::regular_invocable); +static_assert(std::regular_invocable); +static_assert(std::regular_invocable); +static_assert(std::regular_invocable); + +struct lvalue_function_object { + void operator()() &; +}; +static_assert(!std::regular_invocable); +static_assert(!std::regular_invocable); +static_assert(!std::regular_invocable); +static_assert(!std::regular_invocable); +static_assert(std::regular_invocable); +static_assert(!std::regular_invocable); +static_assert(!std::regular_invocable); +static_assert(!std::regular_invocable); + +struct lvalue_const_function_object { + void operator()(int) const&; +}; +static_assert(std::regular_invocable); +static_assert(std::regular_invocable); +static_assert( + !std::regular_invocable); +static_assert( + !std::regular_invocable); +static_assert(std::regular_invocable); +static_assert(std::regular_invocable); +static_assert( + !std::regular_invocable); +static_assert( + !std::regular_invocable); + +struct lvalue_volatile_function_object { + void operator()(int, int) volatile&; +}; +static_assert( + !std::regular_invocable); +static_assert( + !std::regular_invocable); +static_assert(!std::regular_invocable); +static_assert(!std::regular_invocable< + lvalue_volatile_function_object const volatile, int, int>); +static_assert( + std::regular_invocable); +static_assert( + !std::regular_invocable); +static_assert(std::regular_invocable); +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); +static_assert(!std::regular_invocable); +static_assert( + !std::regular_invocable); +static_assert( + !std::regular_invocable); +static_assert(std::regular_invocable); +static_assert(std::regular_invocable); +static_assert( + std::regular_invocable); +static_assert( + std::regular_invocable); +// +struct rvalue_function_object { + void operator()() &&; +}; +static_assert(std::regular_invocable); +static_assert(!std::regular_invocable); +static_assert(!std::regular_invocable); +static_assert(!std::regular_invocable); +static_assert(!std::regular_invocable); +static_assert(!std::regular_invocable); +static_assert(!std::regular_invocable); +static_assert(!std::regular_invocable); + +struct rvalue_const_function_object { + void operator()(int) const&&; +}; +static_assert(std::regular_invocable); +static_assert(std::regular_invocable); +static_assert( + !std::regular_invocable); +static_assert( + !std::regular_invocable); +static_assert(!std::regular_invocable); +static_assert( + !std::regular_invocable); +static_assert( + !std::regular_invocable); +static_assert( + !std::regular_invocable); + +struct rvalue_volatile_function_object { + void operator()(int, int) volatile&&; +}; +static_assert( + std::regular_invocable); +static_assert( + !std::regular_invocable); +static_assert( + std::regular_invocable); +static_assert(!std::regular_invocable< + rvalue_volatile_function_object const volatile, int, int>); +static_assert( + !std::regular_invocable); +static_assert( + !std::regular_invocable); +static_assert(!std::regular_invocable); +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); +static_assert(std::regular_invocable); +static_assert(std::regular_invocable); +static_assert( + std::regular_invocable); +static_assert(!std::regular_invocable); +static_assert(!std::regular_invocable); +static_assert( + !std::regular_invocable); +static_assert( + !std::regular_invocable); + +struct multiple_overloads { + bool operator()(); + void operator()(int); + int operator()(double); +}; +static_assert(std::regular_invocable); +static_assert(std::regular_invocable); +static_assert(std::regular_invocable); +static_assert(!std::regular_invocable); +static_assert(std::regular_invocable); +static_assert(std::regular_invocable); +static_assert(std::regular_invocable); +static_assert(std::regular_invocable); +static_assert(!std::regular_invocable); +static_assert(std::regular_invocable); +static_assert(std::regular_invocable); +} // namespace function_objects + +namespace pointer_to_member_functions { +// clang-format off + template + [[nodiscard]] constexpr bool check_member_is_invocable() { - using namespace Predicate; - { - ModelsRegularInvocable(L2rSorted{}, 0, 1, 2); - NotRegularInvocable(L2rSorted{}); - NotRegularInvocable(L2rSorted{}, 0); - NotRegularInvocable(L2rSorted{}, 0, 1); - } - { - auto Up = std::make_unique(); - ModelsRegularInvocable(&L2rSorted::operator(), Up, 0, 1, 2); - NotRegularInvocable(&L2rSorted::operator(), Up); - NotRegularInvocable(&L2rSorted::operator(), Up, 0); - NotRegularInvocable(&L2rSorted::operator(), Up, 0, 1); - } - { - auto Sp = std::make_shared(); - ModelsRegularInvocable(&L2rSorted::operator(), Sp, 0, 1, 2); - NotRegularInvocable(&L2rSorted::operator(), Sp); - NotRegularInvocable(&L2rSorted::operator(), Sp, 0); - NotRegularInvocable(&L2rSorted::operator(), Sp, 0, 1); - } + constexpr bool result = std::regular_invocable; + using uncv_t = std::remove_cvref_t; + static_assert(std::regular_invocable == result); + static_assert(std::regular_invocable, Args...> == result); + static_assert(std::regular_invocable, Args...> == result); + static_assert(!std::regular_invocable); + static_assert(!std::regular_invocable); + static_assert(!std::regular_invocable); + static_assert(!std::regular_invocable); + struct S2 {}; + static_assert(!std::regular_invocable); + return result; } - // { - // 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; +// clang-format on + +static_assert(check_member_is_invocable()); +static_assert(std::regular_invocable); +static_assert(std::regular_invocable); +static_assert(std::regular_invocable); +static_assert(std::regular_invocable); +static_assert(std::regular_invocable); +static_assert(std::regular_invocable); +static_assert(std::regular_invocable); +static_assert(std::regular_invocable); + +static_assert(check_member_is_invocable()); +static_assert(!check_member_is_invocable()); +using unqualified = void (S::*)(); +static_assert(std::regular_invocable); +static_assert(!std::regular_invocable); +static_assert(!std::regular_invocable); +static_assert(!std::regular_invocable); +static_assert(std::regular_invocable); +static_assert(!std::regular_invocable); +static_assert(!std::regular_invocable); +static_assert(!std::regular_invocable); + +static_assert(check_member_is_invocable()); +using const_qualified = void (S::*)() const; +static_assert(std::regular_invocable); +static_assert(std::regular_invocable); +static_assert(!std::regular_invocable); +static_assert(!std::regular_invocable); +static_assert(std::regular_invocable); +static_assert(std::regular_invocable); +static_assert(!std::regular_invocable); +static_assert(!std::regular_invocable); + +static_assert( + check_member_is_invocable()); +using volatile_qualified = void (S::*)() volatile; +static_assert(std::regular_invocable); +static_assert(!std::regular_invocable); +static_assert(std::regular_invocable); +static_assert(!std::regular_invocable); +static_assert(std::regular_invocable); +static_assert(!std::regular_invocable); +static_assert(std::regular_invocable); +static_assert(!std::regular_invocable); + +static_assert(check_member_is_invocable()); +using cv_qualified = void (S::*)() const volatile; +static_assert(std::regular_invocable); +static_assert(std::regular_invocable); +static_assert(std::regular_invocable); +static_assert(std::regular_invocable); +static_assert(std::regular_invocable); +static_assert(std::regular_invocable); +static_assert(std::regular_invocable); +static_assert(std::regular_invocable); + +static_assert(check_member_is_invocable()); +using lvalue_qualified = void (S::*)() &; +static_assert(std::regular_invocable); +static_assert(!std::regular_invocable); +static_assert(!std::regular_invocable); +static_assert(!std::regular_invocable); +static_assert(!std::regular_invocable); +static_assert(!std::regular_invocable); +static_assert(!std::regular_invocable); +static_assert(!std::regular_invocable); + +static_assert(check_member_is_invocable()); +using lvalue_const_qualified = void (S::*)() const&; +static_assert(std::regular_invocable); +static_assert(std::regular_invocable); +static_assert(!std::regular_invocable); +static_assert( + !std::regular_invocable); +static_assert(std::regular_invocable); +static_assert(std::regular_invocable); +static_assert(!std::regular_invocable); +static_assert( + !std::regular_invocable); + +static_assert(check_member_is_invocable()); +using lvalue_volatile_qualified = void (S::*)() volatile&; +static_assert(std::regular_invocable); +static_assert(!std::regular_invocable); +static_assert(std::regular_invocable); +static_assert( + !std::regular_invocable); +static_assert(!std::regular_invocable); +static_assert(!std::regular_invocable); +static_assert(!std::regular_invocable); +static_assert( + !std::regular_invocable); + +static_assert(check_member_is_invocable()); +using lvalue_cv_qualified = void (S::*)() const volatile&; +static_assert(std::regular_invocable); +static_assert(std::regular_invocable); +static_assert(std::regular_invocable); +static_assert(std::regular_invocable); +static_assert(!std::regular_invocable); +static_assert(!std::regular_invocable); +static_assert(!std::regular_invocable); +static_assert(!std::regular_invocable); + +using rvalue_unqualified = void (S::*)() &&; +static_assert(!std::regular_invocable); +static_assert(!std::regular_invocable); +static_assert(!std::regular_invocable); +static_assert(!std::regular_invocable); +static_assert(std::regular_invocable); +static_assert(!std::regular_invocable); +static_assert(!std::regular_invocable); +static_assert(!std::regular_invocable); + +using rvalue_const_unqualified = void (S::*)() const&&; +static_assert(!std::regular_invocable); +static_assert(!std::regular_invocable); +static_assert(!std::regular_invocable); +static_assert( + !std::regular_invocable); +static_assert(std::regular_invocable); +static_assert(std::regular_invocable); +static_assert(!std::regular_invocable); +static_assert( + !std::regular_invocable); + +using rvalue_volatile_unqualified = void (S::*)() volatile&&; +static_assert(!std::regular_invocable); +static_assert(!std::regular_invocable); +static_assert( + !std::regular_invocable); +static_assert( + !std::regular_invocable); +static_assert(std::regular_invocable); +static_assert(!std::regular_invocable); +static_assert( + std::regular_invocable); +static_assert( + !std::regular_invocable); + +using rvalue_cv_unqualified = void (S::*)() const volatile&&; +static_assert(!std::regular_invocable); +static_assert(!std::regular_invocable); +static_assert(!std::regular_invocable); +static_assert( + !std::regular_invocable); +static_assert(std::regular_invocable); +static_assert(std::regular_invocable); +static_assert(std::regular_invocable); +static_assert( + std::regular_invocable); +} // namespace pointer_to_member_functions + +[[nodiscard]] constexpr bool check_lambda(auto, auto...) { return false; } + +// clang-format off +template +requires std::invocable +[[nodiscard]] constexpr bool check_lambda(F, Args&&...) +{ + return false; } + +template +requires std::regular_invocable && 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; }