//===----------------------------------------------------------------------===// // // 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 // concept regular_invocable; #include #include #include #include #include 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); return result; } 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); static_assert(!std::regular_invocable); static_assert(!std::regular_invocable); static_assert(!std::regular_invocable); 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() { 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; } // 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; }