131191e15SLouis Dionne //===----------------------------------------------------------------------===// 231191e15SLouis Dionne // 331191e15SLouis Dionne // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 431191e15SLouis Dionne // See https://llvm.org/LICENSE.txt for license information. 531191e15SLouis Dionne // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 631191e15SLouis Dionne // 731191e15SLouis Dionne //===----------------------------------------------------------------------===// 831191e15SLouis Dionne 931191e15SLouis Dionne // UNSUPPORTED: c++03, c++11, c++14, c++17 1031191e15SLouis Dionne 1131191e15SLouis Dionne // template<class T, class U> 1231191e15SLouis Dionne // concept regular_invocable; 1331191e15SLouis Dionne 1431191e15SLouis Dionne #include <concepts> 15*e99c4906SNikolas Klauser #include <cstddef> 1634f73804SNikolas Klauser #include <functional> 1731191e15SLouis Dionne #include <memory> 1831191e15SLouis Dionne #include <type_traits> 1931191e15SLouis Dionne 2031191e15SLouis Dionne template <class R, class... Args> 2188b73a98SLouis Dionne constexpr bool check_invocable() { 2231191e15SLouis Dionne constexpr bool result = std::regular_invocable<R(Args...), Args...>; 2331191e15SLouis Dionne static_assert(std::regular_invocable<R(Args...) noexcept, Args...> == result); 2431191e15SLouis Dionne static_assert(std::regular_invocable<R (*)(Args...), Args...> == result); 2531191e15SLouis Dionne static_assert(std::regular_invocable<R (*)(Args...) noexcept, Args...> == 2631191e15SLouis Dionne result); 2731191e15SLouis Dionne static_assert(std::regular_invocable<R (&)(Args...), Args...> == result); 2831191e15SLouis Dionne static_assert(std::regular_invocable<R (&)(Args...) noexcept, Args...> == 2931191e15SLouis Dionne result); 3031191e15SLouis Dionne 3131191e15SLouis Dionne return result; 3231191e15SLouis Dionne } 3331191e15SLouis Dionne 3431191e15SLouis Dionne static_assert(check_invocable<void>()); 3531191e15SLouis Dionne static_assert(check_invocable<void, int>()); 3631191e15SLouis Dionne static_assert(check_invocable<void, int&>()); 3731191e15SLouis Dionne static_assert(check_invocable<void, int*, double>()); 3831191e15SLouis Dionne static_assert(check_invocable<int>()); 3931191e15SLouis Dionne static_assert(check_invocable<int, int[]>()); 4031191e15SLouis Dionne 4131191e15SLouis Dionne struct S; 4231191e15SLouis Dionne static_assert(check_invocable<int, int S::*, std::nullptr_t>()); 4331191e15SLouis Dionne static_assert(check_invocable<int, int (S::*)(), int (S::*)(int), int>()); 4431191e15SLouis Dionne static_assert(std::regular_invocable<void (*)(int const&), int&>); 4531191e15SLouis Dionne static_assert(std::regular_invocable<void (*)(int const&), int&&>); 4631191e15SLouis Dionne static_assert(std::regular_invocable<void (*)(int volatile&), int&>); 4731191e15SLouis Dionne static_assert(std::regular_invocable<void (*)(int const volatile&), int&>); 4831191e15SLouis Dionne 4931191e15SLouis Dionne static_assert(!std::regular_invocable<void(), int>); 5031191e15SLouis Dionne static_assert(!std::regular_invocable<void(int)>); 5131191e15SLouis Dionne static_assert(!std::regular_invocable<void(int*), double*>); 5231191e15SLouis Dionne static_assert(!std::regular_invocable<void (*)(int&), double*>); 5331191e15SLouis Dionne static_assert(std::regular_invocable<int S::*, std::unique_ptr<S> >); 5431191e15SLouis Dionne static_assert(std::regular_invocable<int S::*, std::shared_ptr<S> >); 5531191e15SLouis Dionne static_assert(!std::regular_invocable<void (*)(int&&), int&>); 5631191e15SLouis Dionne static_assert(!std::regular_invocable<void (*)(int&&), int const&>); 5731191e15SLouis Dionne 5831191e15SLouis Dionne static_assert(!std::regular_invocable<void>); 5931191e15SLouis Dionne static_assert(!std::regular_invocable<void*>); 6031191e15SLouis Dionne static_assert(!std::regular_invocable<int>); 6131191e15SLouis Dionne static_assert(!std::regular_invocable<int&>); 6231191e15SLouis Dionne static_assert(!std::regular_invocable<int&&>); 6331191e15SLouis Dionne 6431191e15SLouis Dionne namespace function_objects { 6531191e15SLouis Dionne struct function_object { 6631191e15SLouis Dionne void operator()(); 6731191e15SLouis Dionne }; 6831191e15SLouis Dionne static_assert(std::regular_invocable<function_object>); 6931191e15SLouis Dionne static_assert(!std::regular_invocable<function_object const>); 7031191e15SLouis Dionne static_assert(!std::regular_invocable<function_object volatile>); 7131191e15SLouis Dionne static_assert(!std::regular_invocable<function_object const volatile>); 7231191e15SLouis Dionne static_assert(std::regular_invocable<function_object&>); 7331191e15SLouis Dionne static_assert(!std::regular_invocable<function_object const&>); 7431191e15SLouis Dionne static_assert(!std::regular_invocable<function_object volatile&>); 7531191e15SLouis Dionne static_assert(!std::regular_invocable<function_object const volatile&>); 7631191e15SLouis Dionne 7731191e15SLouis Dionne struct const_function_object { 7831191e15SLouis Dionne void operator()(int) const; 7931191e15SLouis Dionne }; 8031191e15SLouis Dionne static_assert(std::regular_invocable<const_function_object, int>); 8131191e15SLouis Dionne static_assert(std::regular_invocable<const_function_object const, int>); 8231191e15SLouis Dionne static_assert(!std::regular_invocable<const_function_object volatile, int>); 8331191e15SLouis Dionne static_assert( 8431191e15SLouis Dionne !std::regular_invocable<const_function_object const volatile, int>); 8531191e15SLouis Dionne static_assert(std::regular_invocable<const_function_object&, int>); 8631191e15SLouis Dionne static_assert(std::regular_invocable<const_function_object const&, int>); 8731191e15SLouis Dionne static_assert(!std::regular_invocable<const_function_object volatile&, int>); 8831191e15SLouis Dionne static_assert( 8931191e15SLouis Dionne !std::regular_invocable<const_function_object const volatile&, int>); 9031191e15SLouis Dionne 9131191e15SLouis Dionne struct volatile_function_object { 9231191e15SLouis Dionne void operator()(int, int) volatile; 9331191e15SLouis Dionne }; 9431191e15SLouis Dionne static_assert(std::regular_invocable<volatile_function_object, int, int>); 9531191e15SLouis Dionne static_assert( 9631191e15SLouis Dionne !std::regular_invocable<volatile_function_object const, int, int>); 9731191e15SLouis Dionne static_assert( 9831191e15SLouis Dionne std::regular_invocable<volatile_function_object volatile, int, int>); 9931191e15SLouis Dionne static_assert( 10031191e15SLouis Dionne !std::regular_invocable<volatile_function_object const volatile, int, int>); 10131191e15SLouis Dionne static_assert(std::regular_invocable<volatile_function_object&, int, int>); 10231191e15SLouis Dionne static_assert( 10331191e15SLouis Dionne !std::regular_invocable<volatile_function_object const&, int, int>); 10431191e15SLouis Dionne static_assert( 10531191e15SLouis Dionne std::regular_invocable<volatile_function_object volatile&, int, int>); 10631191e15SLouis Dionne static_assert(!std::regular_invocable<volatile_function_object const volatile&, 10731191e15SLouis Dionne int, int>); 10831191e15SLouis Dionne 10931191e15SLouis Dionne struct cv_function_object { 11031191e15SLouis Dionne void operator()(int[]) const volatile; 11131191e15SLouis Dionne }; 11231191e15SLouis Dionne static_assert(std::regular_invocable<cv_function_object, int*>); 11331191e15SLouis Dionne static_assert(std::regular_invocable<cv_function_object const, int*>); 11431191e15SLouis Dionne static_assert(std::regular_invocable<cv_function_object volatile, int*>); 11531191e15SLouis Dionne static_assert(std::regular_invocable<cv_function_object const volatile, int*>); 11631191e15SLouis Dionne static_assert(std::regular_invocable<cv_function_object&, int*>); 11731191e15SLouis Dionne static_assert(std::regular_invocable<cv_function_object const&, int*>); 11831191e15SLouis Dionne static_assert(std::regular_invocable<cv_function_object volatile&, int*>); 11931191e15SLouis Dionne static_assert(std::regular_invocable<cv_function_object const volatile&, int*>); 12031191e15SLouis Dionne 12131191e15SLouis Dionne struct lvalue_function_object { 12231191e15SLouis Dionne void operator()() &; 12331191e15SLouis Dionne }; 12431191e15SLouis Dionne static_assert(!std::regular_invocable<lvalue_function_object>); 12531191e15SLouis Dionne static_assert(!std::regular_invocable<lvalue_function_object const>); 12631191e15SLouis Dionne static_assert(!std::regular_invocable<lvalue_function_object volatile>); 12731191e15SLouis Dionne static_assert(!std::regular_invocable<lvalue_function_object const volatile>); 12831191e15SLouis Dionne static_assert(std::regular_invocable<lvalue_function_object&>); 12931191e15SLouis Dionne static_assert(!std::regular_invocable<lvalue_function_object const&>); 13031191e15SLouis Dionne static_assert(!std::regular_invocable<lvalue_function_object volatile&>); 13131191e15SLouis Dionne static_assert(!std::regular_invocable<lvalue_function_object const volatile&>); 13231191e15SLouis Dionne 13331191e15SLouis Dionne struct lvalue_const_function_object { 13431191e15SLouis Dionne void operator()(int) const&; 13531191e15SLouis Dionne }; 13631191e15SLouis Dionne static_assert(std::regular_invocable<lvalue_const_function_object, int>); 13731191e15SLouis Dionne static_assert(std::regular_invocable<lvalue_const_function_object const, int>); 13831191e15SLouis Dionne static_assert( 13931191e15SLouis Dionne !std::regular_invocable<lvalue_const_function_object volatile, int>); 14031191e15SLouis Dionne static_assert( 14131191e15SLouis Dionne !std::regular_invocable<lvalue_const_function_object const volatile, int>); 14231191e15SLouis Dionne static_assert(std::regular_invocable<lvalue_const_function_object&, int>); 14331191e15SLouis Dionne static_assert(std::regular_invocable<lvalue_const_function_object const&, int>); 14431191e15SLouis Dionne static_assert( 14531191e15SLouis Dionne !std::regular_invocable<lvalue_const_function_object volatile&, int>); 14631191e15SLouis Dionne static_assert( 14731191e15SLouis Dionne !std::regular_invocable<lvalue_const_function_object const volatile&, int>); 14831191e15SLouis Dionne 14931191e15SLouis Dionne struct lvalue_volatile_function_object { 15031191e15SLouis Dionne void operator()(int, int) volatile&; 15131191e15SLouis Dionne }; 15231191e15SLouis Dionne static_assert( 15331191e15SLouis Dionne !std::regular_invocable<lvalue_volatile_function_object, int, int>); 15431191e15SLouis Dionne static_assert( 15531191e15SLouis Dionne !std::regular_invocable<lvalue_volatile_function_object const, int, int>); 15631191e15SLouis Dionne static_assert(!std::regular_invocable<lvalue_volatile_function_object volatile, 15731191e15SLouis Dionne int, int>); 15831191e15SLouis Dionne static_assert(!std::regular_invocable< 15931191e15SLouis Dionne lvalue_volatile_function_object const volatile, int, int>); 16031191e15SLouis Dionne static_assert( 16131191e15SLouis Dionne std::regular_invocable<lvalue_volatile_function_object&, int, int>); 16231191e15SLouis Dionne static_assert( 16331191e15SLouis Dionne !std::regular_invocable<lvalue_volatile_function_object const&, int, int>); 16431191e15SLouis Dionne static_assert(std::regular_invocable<lvalue_volatile_function_object volatile&, 16531191e15SLouis Dionne int, int>); 16631191e15SLouis Dionne static_assert(!std::regular_invocable< 16731191e15SLouis Dionne lvalue_volatile_function_object const volatile&, int, int>); 16831191e15SLouis Dionne 16931191e15SLouis Dionne struct lvalue_cv_function_object { 17031191e15SLouis Dionne void operator()(int[]) const volatile&; 17131191e15SLouis Dionne }; 17231191e15SLouis Dionne static_assert(!std::regular_invocable<lvalue_cv_function_object, int*>); 17331191e15SLouis Dionne static_assert(!std::regular_invocable<lvalue_cv_function_object const, int*>); 17431191e15SLouis Dionne static_assert( 17531191e15SLouis Dionne !std::regular_invocable<lvalue_cv_function_object volatile, int*>); 17631191e15SLouis Dionne static_assert( 17731191e15SLouis Dionne !std::regular_invocable<lvalue_cv_function_object const volatile, int*>); 17831191e15SLouis Dionne static_assert(std::regular_invocable<lvalue_cv_function_object&, int*>); 17931191e15SLouis Dionne static_assert(std::regular_invocable<lvalue_cv_function_object const&, int*>); 18031191e15SLouis Dionne static_assert( 18131191e15SLouis Dionne std::regular_invocable<lvalue_cv_function_object volatile&, int*>); 18231191e15SLouis Dionne static_assert( 18331191e15SLouis Dionne std::regular_invocable<lvalue_cv_function_object const volatile&, int*>); 18431191e15SLouis Dionne // 18531191e15SLouis Dionne struct rvalue_function_object { 18631191e15SLouis Dionne void operator()() &&; 18731191e15SLouis Dionne }; 18831191e15SLouis Dionne static_assert(std::regular_invocable<rvalue_function_object>); 18931191e15SLouis Dionne static_assert(!std::regular_invocable<rvalue_function_object const>); 19031191e15SLouis Dionne static_assert(!std::regular_invocable<rvalue_function_object volatile>); 19131191e15SLouis Dionne static_assert(!std::regular_invocable<rvalue_function_object const volatile>); 19231191e15SLouis Dionne static_assert(!std::regular_invocable<rvalue_function_object&>); 19331191e15SLouis Dionne static_assert(!std::regular_invocable<rvalue_function_object const&>); 19431191e15SLouis Dionne static_assert(!std::regular_invocable<rvalue_function_object volatile&>); 19531191e15SLouis Dionne static_assert(!std::regular_invocable<rvalue_function_object const volatile&>); 19631191e15SLouis Dionne 19731191e15SLouis Dionne struct rvalue_const_function_object { 19831191e15SLouis Dionne void operator()(int) const&&; 19931191e15SLouis Dionne }; 20031191e15SLouis Dionne static_assert(std::regular_invocable<rvalue_const_function_object, int>); 20131191e15SLouis Dionne static_assert(std::regular_invocable<rvalue_const_function_object const, int>); 20231191e15SLouis Dionne static_assert( 20331191e15SLouis Dionne !std::regular_invocable<rvalue_const_function_object volatile, int>); 20431191e15SLouis Dionne static_assert( 20531191e15SLouis Dionne !std::regular_invocable<rvalue_const_function_object const volatile, int>); 20631191e15SLouis Dionne static_assert(!std::regular_invocable<rvalue_const_function_object&, int>); 20731191e15SLouis Dionne static_assert( 20831191e15SLouis Dionne !std::regular_invocable<rvalue_const_function_object const&, int>); 20931191e15SLouis Dionne static_assert( 21031191e15SLouis Dionne !std::regular_invocable<rvalue_const_function_object volatile&, int>); 21131191e15SLouis Dionne static_assert( 21231191e15SLouis Dionne !std::regular_invocable<rvalue_const_function_object const volatile&, int>); 21331191e15SLouis Dionne 21431191e15SLouis Dionne struct rvalue_volatile_function_object { 21531191e15SLouis Dionne void operator()(int, int) volatile&&; 21631191e15SLouis Dionne }; 21731191e15SLouis Dionne static_assert( 21831191e15SLouis Dionne std::regular_invocable<rvalue_volatile_function_object, int, int>); 21931191e15SLouis Dionne static_assert( 22031191e15SLouis Dionne !std::regular_invocable<rvalue_volatile_function_object const, int, int>); 22131191e15SLouis Dionne static_assert( 22231191e15SLouis Dionne std::regular_invocable<rvalue_volatile_function_object volatile, int, int>); 22331191e15SLouis Dionne static_assert(!std::regular_invocable< 22431191e15SLouis Dionne rvalue_volatile_function_object const volatile, int, int>); 22531191e15SLouis Dionne static_assert( 22631191e15SLouis Dionne !std::regular_invocable<rvalue_volatile_function_object&, int, int>); 22731191e15SLouis Dionne static_assert( 22831191e15SLouis Dionne !std::regular_invocable<rvalue_volatile_function_object const&, int, int>); 22931191e15SLouis Dionne static_assert(!std::regular_invocable<rvalue_volatile_function_object volatile&, 23031191e15SLouis Dionne int, int>); 23131191e15SLouis Dionne static_assert(!std::regular_invocable< 23231191e15SLouis Dionne rvalue_volatile_function_object const volatile&, int, int>); 23331191e15SLouis Dionne 23431191e15SLouis Dionne struct rvalue_cv_function_object { 23531191e15SLouis Dionne void operator()(int[]) const volatile&&; 23631191e15SLouis Dionne }; 23731191e15SLouis Dionne static_assert(std::regular_invocable<rvalue_cv_function_object, int*>); 23831191e15SLouis Dionne static_assert(std::regular_invocable<rvalue_cv_function_object const, int*>); 23931191e15SLouis Dionne static_assert(std::regular_invocable<rvalue_cv_function_object volatile, int*>); 24031191e15SLouis Dionne static_assert( 24131191e15SLouis Dionne std::regular_invocable<rvalue_cv_function_object const volatile, int*>); 24231191e15SLouis Dionne static_assert(!std::regular_invocable<rvalue_cv_function_object&, int*>); 24331191e15SLouis Dionne static_assert(!std::regular_invocable<rvalue_cv_function_object const&, int*>); 24431191e15SLouis Dionne static_assert( 24531191e15SLouis Dionne !std::regular_invocable<rvalue_cv_function_object volatile&, int*>); 24631191e15SLouis Dionne static_assert( 24731191e15SLouis Dionne !std::regular_invocable<rvalue_cv_function_object const volatile&, int*>); 24831191e15SLouis Dionne 24931191e15SLouis Dionne struct multiple_overloads { 25031191e15SLouis Dionne struct A {}; 25131191e15SLouis Dionne struct B { B(int); }; 25231191e15SLouis Dionne struct AB : A, B {}; 25331191e15SLouis Dionne struct O {}; 25431191e15SLouis Dionne void operator()(A) const; 25531191e15SLouis Dionne void operator()(B) const; 25631191e15SLouis Dionne }; 25731191e15SLouis Dionne static_assert(std::regular_invocable<multiple_overloads, multiple_overloads::A>); 25831191e15SLouis Dionne static_assert(std::regular_invocable<multiple_overloads, multiple_overloads::B>); 25931191e15SLouis Dionne static_assert(std::regular_invocable<multiple_overloads, int>); 26031191e15SLouis Dionne static_assert(!std::regular_invocable<multiple_overloads, multiple_overloads::AB>); 26131191e15SLouis Dionne static_assert(!std::regular_invocable<multiple_overloads, multiple_overloads::O>); 26231191e15SLouis Dionne } // namespace function_objects 26331191e15SLouis Dionne 26431191e15SLouis Dionne namespace pointer_to_member_functions { 26531191e15SLouis Dionne template<class Member, class T, class... Args> 26688b73a98SLouis Dionne constexpr bool check_member_is_invocable() 26731191e15SLouis Dionne { 2685a3c2763SArthur O'Dwyer constexpr bool result = std::regular_invocable<Member, T&&, Args...>; 26931191e15SLouis Dionne using uncv_t = std::remove_cvref_t<T>; 27031191e15SLouis Dionne static_assert(std::regular_invocable<Member, uncv_t*, Args...> == result); 27131191e15SLouis Dionne static_assert(std::regular_invocable<Member, std::unique_ptr<uncv_t>, Args...> == result); 27231191e15SLouis Dionne static_assert(std::regular_invocable<Member, std::reference_wrapper<uncv_t>, Args...> == result); 27331191e15SLouis Dionne static_assert(!std::regular_invocable<Member, std::nullptr_t, Args...>); 27431191e15SLouis Dionne static_assert(!std::regular_invocable<Member, int, Args...>); 27531191e15SLouis Dionne static_assert(!std::regular_invocable<Member, int*, Args...>); 27631191e15SLouis Dionne static_assert(!std::regular_invocable<Member, double*, Args...>); 27731191e15SLouis Dionne struct S2 {}; 27831191e15SLouis Dionne static_assert(!std::regular_invocable<Member, S2*, Args...>); 27931191e15SLouis Dionne return result; 28031191e15SLouis Dionne } 28131191e15SLouis Dionne 28231191e15SLouis Dionne static_assert(check_member_is_invocable<int S::*, S>()); 28331191e15SLouis Dionne static_assert(std::regular_invocable<int S::*, S&>); 28431191e15SLouis Dionne static_assert(std::regular_invocable<int S::*, S const&>); 28531191e15SLouis Dionne static_assert(std::regular_invocable<int S::*, S volatile&>); 28631191e15SLouis Dionne static_assert(std::regular_invocable<int S::*, S const volatile&>); 28731191e15SLouis Dionne static_assert(std::regular_invocable<int S::*, S&&>); 28831191e15SLouis Dionne static_assert(std::regular_invocable<int S::*, S const&&>); 28931191e15SLouis Dionne static_assert(std::regular_invocable<int S::*, S volatile&&>); 29031191e15SLouis Dionne static_assert(std::regular_invocable<int S::*, S const volatile&&>); 29131191e15SLouis Dionne 29231191e15SLouis Dionne static_assert(check_member_is_invocable<int (S::*)(int), S, int>()); 29331191e15SLouis Dionne static_assert(!check_member_is_invocable<int (S::*)(int), S>()); 29431191e15SLouis Dionne using unqualified = void (S::*)(); 29531191e15SLouis Dionne static_assert(std::regular_invocable<unqualified, S&>); 29631191e15SLouis Dionne static_assert(!std::regular_invocable<unqualified, S const&>); 29731191e15SLouis Dionne static_assert(!std::regular_invocable<unqualified, S volatile&>); 29831191e15SLouis Dionne static_assert(!std::regular_invocable<unqualified, S const volatile&>); 29931191e15SLouis Dionne static_assert(std::regular_invocable<unqualified, S&&>); 30031191e15SLouis Dionne static_assert(!std::regular_invocable<unqualified, S const&&>); 30131191e15SLouis Dionne static_assert(!std::regular_invocable<unqualified, S volatile&&>); 30231191e15SLouis Dionne static_assert(!std::regular_invocable<unqualified, S const volatile&&>); 30331191e15SLouis Dionne 30431191e15SLouis Dionne static_assert(check_member_is_invocable<int (S::*)(double) const, S, double>()); 30531191e15SLouis Dionne using const_qualified = void (S::*)() const; 30631191e15SLouis Dionne static_assert(std::regular_invocable<const_qualified, S&>); 30731191e15SLouis Dionne static_assert(std::regular_invocable<const_qualified, S const&>); 30831191e15SLouis Dionne static_assert(!std::regular_invocable<const_qualified, S volatile&>); 30931191e15SLouis Dionne static_assert(!std::regular_invocable<const_qualified, S const volatile&>); 31031191e15SLouis Dionne static_assert(std::regular_invocable<const_qualified, S&&>); 31131191e15SLouis Dionne static_assert(std::regular_invocable<const_qualified, S const&&>); 31231191e15SLouis Dionne static_assert(!std::regular_invocable<const_qualified, S volatile&&>); 31331191e15SLouis Dionne static_assert(!std::regular_invocable<const_qualified, S const volatile&&>); 31431191e15SLouis Dionne 31531191e15SLouis Dionne static_assert( 31631191e15SLouis Dionne check_member_is_invocable<int (S::*)(double[]) volatile, S, double*>()); 31731191e15SLouis Dionne using volatile_qualified = void (S::*)() volatile; 31831191e15SLouis Dionne static_assert(std::regular_invocable<volatile_qualified, S&>); 31931191e15SLouis Dionne static_assert(!std::regular_invocable<volatile_qualified, S const&>); 32031191e15SLouis Dionne static_assert(std::regular_invocable<volatile_qualified, S volatile&>); 32131191e15SLouis Dionne static_assert(!std::regular_invocable<volatile_qualified, S const volatile&>); 32231191e15SLouis Dionne static_assert(std::regular_invocable<volatile_qualified, S&&>); 32331191e15SLouis Dionne static_assert(!std::regular_invocable<volatile_qualified, S const&&>); 32431191e15SLouis Dionne static_assert(std::regular_invocable<volatile_qualified, S volatile&&>); 32531191e15SLouis Dionne static_assert(!std::regular_invocable<volatile_qualified, S const volatile&&>); 32631191e15SLouis Dionne 32731191e15SLouis Dionne static_assert(check_member_is_invocable<int (S::*)(int, S&) const volatile, S, 32831191e15SLouis Dionne int, S&>()); 32931191e15SLouis Dionne using cv_qualified = void (S::*)() const volatile; 33031191e15SLouis Dionne static_assert(std::regular_invocable<cv_qualified, S&>); 33131191e15SLouis Dionne static_assert(std::regular_invocable<cv_qualified, S const&>); 33231191e15SLouis Dionne static_assert(std::regular_invocable<cv_qualified, S volatile&>); 33331191e15SLouis Dionne static_assert(std::regular_invocable<cv_qualified, S const volatile&>); 33431191e15SLouis Dionne static_assert(std::regular_invocable<cv_qualified, S&&>); 33531191e15SLouis Dionne static_assert(std::regular_invocable<cv_qualified, S const&&>); 33631191e15SLouis Dionne static_assert(std::regular_invocable<cv_qualified, S volatile&&>); 33731191e15SLouis Dionne static_assert(std::regular_invocable<cv_qualified, S const volatile&&>); 33831191e15SLouis Dionne 33931191e15SLouis Dionne static_assert(check_member_is_invocable<int (S::*)() &, S&>()); 34031191e15SLouis Dionne using lvalue_qualified = void (S::*)() &; 34131191e15SLouis Dionne static_assert(std::regular_invocable<lvalue_qualified, S&>); 34231191e15SLouis Dionne static_assert(!std::regular_invocable<lvalue_qualified, S const&>); 34331191e15SLouis Dionne static_assert(!std::regular_invocable<lvalue_qualified, S volatile&>); 34431191e15SLouis Dionne static_assert(!std::regular_invocable<lvalue_qualified, S const volatile&>); 34531191e15SLouis Dionne static_assert(!std::regular_invocable<lvalue_qualified, S&&>); 34631191e15SLouis Dionne static_assert(!std::regular_invocable<lvalue_qualified, S const&&>); 34731191e15SLouis Dionne static_assert(!std::regular_invocable<lvalue_qualified, S volatile&&>); 34831191e15SLouis Dionne static_assert(!std::regular_invocable<lvalue_qualified, S const volatile&&>); 34931191e15SLouis Dionne 35031191e15SLouis Dionne static_assert(check_member_is_invocable<int (S::*)() const&, S>()); 35131191e15SLouis Dionne using lvalue_const_qualified = void (S::*)() const&; 35231191e15SLouis Dionne static_assert(std::regular_invocable<lvalue_const_qualified, S&>); 35331191e15SLouis Dionne static_assert(std::regular_invocable<lvalue_const_qualified, S const&>); 35431191e15SLouis Dionne static_assert(!std::regular_invocable<lvalue_const_qualified, S volatile&>); 35531191e15SLouis Dionne static_assert( 35631191e15SLouis Dionne !std::regular_invocable<lvalue_const_qualified, S const volatile&>); 35731191e15SLouis Dionne static_assert(std::regular_invocable<lvalue_const_qualified, S&&>); 35831191e15SLouis Dionne static_assert(std::regular_invocable<lvalue_const_qualified, S const&&>); 35931191e15SLouis Dionne static_assert(!std::regular_invocable<lvalue_const_qualified, S volatile&&>); 36031191e15SLouis Dionne static_assert( 36131191e15SLouis Dionne !std::regular_invocable<lvalue_const_qualified, S const volatile&&>); 36231191e15SLouis Dionne 36331191e15SLouis Dionne static_assert(check_member_is_invocable<int (S::*)() volatile&, S&>()); 36431191e15SLouis Dionne using lvalue_volatile_qualified = void (S::*)() volatile&; 36531191e15SLouis Dionne static_assert(std::regular_invocable<lvalue_volatile_qualified, S&>); 36631191e15SLouis Dionne static_assert(!std::regular_invocable<lvalue_volatile_qualified, S const&>); 36731191e15SLouis Dionne static_assert(std::regular_invocable<lvalue_volatile_qualified, S volatile&>); 36831191e15SLouis Dionne static_assert( 36931191e15SLouis Dionne !std::regular_invocable<lvalue_volatile_qualified, S const volatile&>); 37031191e15SLouis Dionne static_assert(!std::regular_invocable<lvalue_volatile_qualified, S&&>); 37131191e15SLouis Dionne static_assert(!std::regular_invocable<lvalue_volatile_qualified, S const&&>); 37231191e15SLouis Dionne static_assert(!std::regular_invocable<lvalue_volatile_qualified, S volatile&&>); 37331191e15SLouis Dionne static_assert( 37431191e15SLouis Dionne !std::regular_invocable<lvalue_volatile_qualified, S const volatile&&>); 37531191e15SLouis Dionne 37631191e15SLouis Dionne static_assert(check_member_is_invocable<int (S::*)() const volatile&, S&>()); 37731191e15SLouis Dionne using lvalue_cv_qualified = void (S::*)() const volatile&; 37831191e15SLouis Dionne static_assert(std::regular_invocable<lvalue_cv_qualified, S&>); 37931191e15SLouis Dionne static_assert(std::regular_invocable<lvalue_cv_qualified, S const&>); 38031191e15SLouis Dionne static_assert(std::regular_invocable<lvalue_cv_qualified, S volatile&>); 38131191e15SLouis Dionne static_assert(std::regular_invocable<lvalue_cv_qualified, S const volatile&>); 38231191e15SLouis Dionne static_assert(!std::regular_invocable<lvalue_cv_qualified, S&&>); 38331191e15SLouis Dionne static_assert(!std::regular_invocable<lvalue_cv_qualified, S const&&>); 38431191e15SLouis Dionne static_assert(!std::regular_invocable<lvalue_cv_qualified, S volatile&&>); 38531191e15SLouis Dionne static_assert(!std::regular_invocable<lvalue_cv_qualified, S const volatile&&>); 38631191e15SLouis Dionne 38731191e15SLouis Dionne using rvalue_unqualified = void (S::*)() &&; 38831191e15SLouis Dionne static_assert(!std::regular_invocable<rvalue_unqualified, S&>); 38931191e15SLouis Dionne static_assert(!std::regular_invocable<rvalue_unqualified, S const&>); 39031191e15SLouis Dionne static_assert(!std::regular_invocable<rvalue_unqualified, S volatile&>); 39131191e15SLouis Dionne static_assert(!std::regular_invocable<rvalue_unqualified, S const volatile&>); 39231191e15SLouis Dionne static_assert(std::regular_invocable<rvalue_unqualified, S&&>); 39331191e15SLouis Dionne static_assert(!std::regular_invocable<rvalue_unqualified, S const&&>); 39431191e15SLouis Dionne static_assert(!std::regular_invocable<rvalue_unqualified, S volatile&&>); 39531191e15SLouis Dionne static_assert(!std::regular_invocable<rvalue_unqualified, S const volatile&&>); 39631191e15SLouis Dionne 39731191e15SLouis Dionne using rvalue_const_unqualified = void (S::*)() const&&; 39831191e15SLouis Dionne static_assert(!std::regular_invocable<rvalue_const_unqualified, S&>); 39931191e15SLouis Dionne static_assert(!std::regular_invocable<rvalue_const_unqualified, S const&>); 40031191e15SLouis Dionne static_assert(!std::regular_invocable<rvalue_const_unqualified, S volatile&>); 40131191e15SLouis Dionne static_assert( 40231191e15SLouis Dionne !std::regular_invocable<rvalue_const_unqualified, S const volatile&>); 40331191e15SLouis Dionne static_assert(std::regular_invocable<rvalue_const_unqualified, S&&>); 40431191e15SLouis Dionne static_assert(std::regular_invocable<rvalue_const_unqualified, S const&&>); 40531191e15SLouis Dionne static_assert(!std::regular_invocable<rvalue_const_unqualified, S volatile&&>); 40631191e15SLouis Dionne static_assert( 40731191e15SLouis Dionne !std::regular_invocable<rvalue_const_unqualified, S const volatile&&>); 40831191e15SLouis Dionne 40931191e15SLouis Dionne using rvalue_volatile_unqualified = void (S::*)() volatile&&; 41031191e15SLouis Dionne static_assert(!std::regular_invocable<rvalue_volatile_unqualified, S&>); 41131191e15SLouis Dionne static_assert(!std::regular_invocable<rvalue_volatile_unqualified, S const&>); 41231191e15SLouis Dionne static_assert( 41331191e15SLouis Dionne !std::regular_invocable<rvalue_volatile_unqualified, S volatile&>); 41431191e15SLouis Dionne static_assert( 41531191e15SLouis Dionne !std::regular_invocable<rvalue_volatile_unqualified, S const volatile&>); 41631191e15SLouis Dionne static_assert(std::regular_invocable<rvalue_volatile_unqualified, S&&>); 41731191e15SLouis Dionne static_assert(!std::regular_invocable<rvalue_volatile_unqualified, S const&&>); 41831191e15SLouis Dionne static_assert( 41931191e15SLouis Dionne std::regular_invocable<rvalue_volatile_unqualified, S volatile&&>); 42031191e15SLouis Dionne static_assert( 42131191e15SLouis Dionne !std::regular_invocable<rvalue_volatile_unqualified, S const volatile&&>); 42231191e15SLouis Dionne 42331191e15SLouis Dionne using rvalue_cv_unqualified = void (S::*)() const volatile&&; 42431191e15SLouis Dionne static_assert(!std::regular_invocable<rvalue_cv_unqualified, S&>); 42531191e15SLouis Dionne static_assert(!std::regular_invocable<rvalue_cv_unqualified, S const&>); 42631191e15SLouis Dionne static_assert(!std::regular_invocable<rvalue_cv_unqualified, S volatile&>); 42731191e15SLouis Dionne static_assert( 42831191e15SLouis Dionne !std::regular_invocable<rvalue_cv_unqualified, S const volatile&>); 42931191e15SLouis Dionne static_assert(std::regular_invocable<rvalue_cv_unqualified, S&&>); 43031191e15SLouis Dionne static_assert(std::regular_invocable<rvalue_cv_unqualified, S const&&>); 43131191e15SLouis Dionne static_assert(std::regular_invocable<rvalue_cv_unqualified, S volatile&&>); 43231191e15SLouis Dionne static_assert( 43331191e15SLouis Dionne std::regular_invocable<rvalue_cv_unqualified, S const volatile&&>); 43431191e15SLouis Dionne } // namespace pointer_to_member_functions 43531191e15SLouis Dionne 43631191e15SLouis Dionne // Check the concept with closure types (and also check for subsumption) 43731191e15SLouis Dionne template<class F, class... Args> 43831191e15SLouis Dionne constexpr bool is_regular_invocable(F, Args&&...) { 43931191e15SLouis Dionne return false; 44031191e15SLouis Dionne } 44131191e15SLouis Dionne 44231191e15SLouis Dionne template<class F, class... Args> 44331191e15SLouis Dionne requires std::invocable<F, Args...> 44431191e15SLouis Dionne constexpr bool is_regular_invocable(F, Args&&...) { 44531191e15SLouis Dionne return false; 44631191e15SLouis Dionne } 44731191e15SLouis Dionne 44831191e15SLouis Dionne template<class F, class... Args> 44931191e15SLouis Dionne requires std::regular_invocable<F, Args...> && true 45031191e15SLouis Dionne constexpr bool is_regular_invocable(F, Args&&...) { 45131191e15SLouis Dionne return true; 45231191e15SLouis Dionne } 45331191e15SLouis Dionne 45431191e15SLouis Dionne static_assert(is_regular_invocable([] {})); 45531191e15SLouis Dionne static_assert(is_regular_invocable([](int) {}, 0)); 45631191e15SLouis Dionne static_assert(is_regular_invocable([](int) {}, 0L)); 45731191e15SLouis Dionne static_assert(!is_regular_invocable([](int) {}, nullptr)); 45831191e15SLouis Dionne 45931191e15SLouis Dionne int i = 0; 46031191e15SLouis Dionne static_assert(is_regular_invocable([](int&) {}, i)); 461