//===----------------------------------------------------------------------===// // // 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 // template // concept regular_invocable; #include #include #include #include #include template 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 { 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); 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 { template 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; } 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 // Check the concept with closure types (and also check for subsumption) template constexpr bool is_regular_invocable(F, Args&&...) { return false; } template requires std::invocable constexpr bool is_regular_invocable(F, Args&&...) { return false; } template requires std::regular_invocable && true constexpr bool is_regular_invocable(F, Args&&...) { return true; } static_assert(is_regular_invocable([] {})); static_assert(is_regular_invocable([](int) {}, 0)); static_assert(is_regular_invocable([](int) {}, 0L)); static_assert(!is_regular_invocable([](int) {}, nullptr)); int i = 0; static_assert(is_regular_invocable([](int&) {}, i));