124dd2d2fSChristopher Di Bella //===----------------------------------------------------------------------===//
224dd2d2fSChristopher Di Bella //
324dd2d2fSChristopher Di Bella // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
424dd2d2fSChristopher Di Bella // See https://llvm.org/LICENSE.txt for license information.
524dd2d2fSChristopher Di Bella // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
624dd2d2fSChristopher Di Bella //
724dd2d2fSChristopher Di Bella //===----------------------------------------------------------------------===//
824dd2d2fSChristopher Di Bella 
924dd2d2fSChristopher Di Bella // UNSUPPORTED: c++03, c++11, c++14, c++17
1024dd2d2fSChristopher Di Bella 
1124dd2d2fSChristopher Di Bella // template<class T, class U>
1224dd2d2fSChristopher Di Bella // concept invocable;
1324dd2d2fSChristopher Di Bella 
1424dd2d2fSChristopher Di Bella #include <concepts>
15*e99c4906SNikolas Klauser #include <cstddef>
1634f73804SNikolas Klauser #include <functional>
1724dd2d2fSChristopher Di Bella #include <memory>
1824dd2d2fSChristopher Di Bella #include <random>
1924dd2d2fSChristopher Di Bella #include <type_traits>
2024dd2d2fSChristopher Di Bella 
21e06f1a8eSChristopher Di Bella template <class R, class... Args>
2288b73a98SLouis Dionne constexpr bool check_invocable() {
23e06f1a8eSChristopher Di Bella   constexpr bool result = std::invocable<R(Args...), Args...>;
24e06f1a8eSChristopher Di Bella   static_assert(std::invocable<R(Args...) noexcept, Args...> == result);
25e06f1a8eSChristopher Di Bella   static_assert(std::invocable<R (*)(Args...), Args...> == result);
26e06f1a8eSChristopher Di Bella   static_assert(std::invocable<R (*)(Args...) noexcept, Args...> == result);
27e06f1a8eSChristopher Di Bella   static_assert(std::invocable<R (&)(Args...), Args...> == result);
28e06f1a8eSChristopher Di Bella   static_assert(std::invocable<R (&)(Args...) noexcept, Args...> == result);
2924dd2d2fSChristopher Di Bella 
30e06f1a8eSChristopher Di Bella   return result;
31e06f1a8eSChristopher Di Bella }
3224dd2d2fSChristopher Di Bella 
33e06f1a8eSChristopher Di Bella static_assert(check_invocable<void>());
34e06f1a8eSChristopher Di Bella static_assert(check_invocable<void, int>());
35e06f1a8eSChristopher Di Bella static_assert(check_invocable<void, int&>());
36e06f1a8eSChristopher Di Bella static_assert(check_invocable<void, int*, double>());
37e06f1a8eSChristopher Di Bella static_assert(check_invocable<int>());
38e06f1a8eSChristopher Di Bella static_assert(check_invocable<int, int[]>());
39e06f1a8eSChristopher Di Bella 
40e06f1a8eSChristopher Di Bella struct S;
41e06f1a8eSChristopher Di Bella static_assert(check_invocable<int, int S::*, std::nullptr_t>());
42e06f1a8eSChristopher Di Bella static_assert(check_invocable<int, int (S::*)(), int (S::*)(int), int>());
43e06f1a8eSChristopher Di Bella static_assert(std::invocable<void (*)(int const&), int&>);
44e06f1a8eSChristopher Di Bella static_assert(std::invocable<void (*)(int const&), int&&>);
45e06f1a8eSChristopher Di Bella static_assert(std::invocable<void (*)(int volatile&), int&>);
46e06f1a8eSChristopher Di Bella static_assert(std::invocable<void (*)(int const volatile&), int&>);
47e06f1a8eSChristopher Di Bella 
48e06f1a8eSChristopher Di Bella static_assert(!std::invocable<void(), int>);
49e06f1a8eSChristopher Di Bella static_assert(!std::invocable<void(int)>);
50e06f1a8eSChristopher Di Bella static_assert(!std::invocable<void(int*), double*>);
51e06f1a8eSChristopher Di Bella static_assert(!std::invocable<void (*)(int&), double*>);
52e06f1a8eSChristopher Di Bella static_assert(std::invocable<int S::*, std::unique_ptr<S> >);
53e06f1a8eSChristopher Di Bella static_assert(std::invocable<int S::*, std::shared_ptr<S> >);
54e06f1a8eSChristopher Di Bella static_assert(!std::invocable<void (*)(int&&), int&>);
55e06f1a8eSChristopher Di Bella static_assert(!std::invocable<void (*)(int&&), int const&>);
5624dd2d2fSChristopher Di Bella 
5724dd2d2fSChristopher Di Bella static_assert(!std::invocable<void>);
5824dd2d2fSChristopher Di Bella static_assert(!std::invocable<void*>);
5924dd2d2fSChristopher Di Bella static_assert(!std::invocable<int>);
6024dd2d2fSChristopher Di Bella static_assert(!std::invocable<int&>);
6124dd2d2fSChristopher Di Bella static_assert(!std::invocable<int&&>);
6224dd2d2fSChristopher Di Bella 
63e06f1a8eSChristopher Di Bella namespace function_objects {
64e06f1a8eSChristopher Di Bella struct function_object {
65e06f1a8eSChristopher Di Bella   void operator()();
66e06f1a8eSChristopher Di Bella };
67e06f1a8eSChristopher Di Bella static_assert(std::invocable<function_object>);
68e06f1a8eSChristopher Di Bella static_assert(!std::invocable<function_object const>);
69e06f1a8eSChristopher Di Bella static_assert(!std::invocable<function_object volatile>);
70e06f1a8eSChristopher Di Bella static_assert(!std::invocable<function_object const volatile>);
71e06f1a8eSChristopher Di Bella static_assert(std::invocable<function_object&>);
72e06f1a8eSChristopher Di Bella static_assert(!std::invocable<function_object const&>);
73e06f1a8eSChristopher Di Bella static_assert(!std::invocable<function_object volatile&>);
74e06f1a8eSChristopher Di Bella static_assert(!std::invocable<function_object const volatile&>);
75e06f1a8eSChristopher Di Bella 
76e06f1a8eSChristopher Di Bella struct const_function_object {
77e06f1a8eSChristopher Di Bella   void operator()(int) const;
78e06f1a8eSChristopher Di Bella };
79e06f1a8eSChristopher Di Bella static_assert(std::invocable<const_function_object, int>);
80e06f1a8eSChristopher Di Bella static_assert(std::invocable<const_function_object const, int>);
81e06f1a8eSChristopher Di Bella static_assert(!std::invocable<const_function_object volatile, int>);
82e06f1a8eSChristopher Di Bella static_assert(!std::invocable<const_function_object const volatile, int>);
83e06f1a8eSChristopher Di Bella static_assert(std::invocable<const_function_object&, int>);
84e06f1a8eSChristopher Di Bella static_assert(std::invocable<const_function_object const&, int>);
85e06f1a8eSChristopher Di Bella static_assert(!std::invocable<const_function_object volatile&, int>);
86e06f1a8eSChristopher Di Bella static_assert(!std::invocable<const_function_object const volatile&, int>);
87e06f1a8eSChristopher Di Bella 
88e06f1a8eSChristopher Di Bella struct volatile_function_object {
89e06f1a8eSChristopher Di Bella   void operator()(int, int) volatile;
90e06f1a8eSChristopher Di Bella };
91e06f1a8eSChristopher Di Bella static_assert(std::invocable<volatile_function_object, int, int>);
92e06f1a8eSChristopher Di Bella static_assert(!std::invocable<volatile_function_object const, int, int>);
93e06f1a8eSChristopher Di Bella static_assert(std::invocable<volatile_function_object volatile, int, int>);
94e06f1a8eSChristopher Di Bella static_assert(
95e06f1a8eSChristopher Di Bella     !std::invocable<volatile_function_object const volatile, int, int>);
96e06f1a8eSChristopher Di Bella static_assert(std::invocable<volatile_function_object&, int, int>);
97e06f1a8eSChristopher Di Bella static_assert(!std::invocable<volatile_function_object const&, int, int>);
98e06f1a8eSChristopher Di Bella static_assert(std::invocable<volatile_function_object volatile&, int, int>);
99e06f1a8eSChristopher Di Bella static_assert(
100e06f1a8eSChristopher Di Bella     !std::invocable<volatile_function_object const volatile&, int, int>);
101e06f1a8eSChristopher Di Bella 
102e06f1a8eSChristopher Di Bella struct cv_function_object {
103e06f1a8eSChristopher Di Bella   void operator()(int[]) const volatile;
104e06f1a8eSChristopher Di Bella };
105e06f1a8eSChristopher Di Bella static_assert(std::invocable<cv_function_object, int*>);
106e06f1a8eSChristopher Di Bella static_assert(std::invocable<cv_function_object const, int*>);
107e06f1a8eSChristopher Di Bella static_assert(std::invocable<cv_function_object volatile, int*>);
108e06f1a8eSChristopher Di Bella static_assert(std::invocable<cv_function_object const volatile, int*>);
109e06f1a8eSChristopher Di Bella static_assert(std::invocable<cv_function_object&, int*>);
110e06f1a8eSChristopher Di Bella static_assert(std::invocable<cv_function_object const&, int*>);
111e06f1a8eSChristopher Di Bella static_assert(std::invocable<cv_function_object volatile&, int*>);
112e06f1a8eSChristopher Di Bella static_assert(std::invocable<cv_function_object const volatile&, int*>);
113e06f1a8eSChristopher Di Bella 
114e06f1a8eSChristopher Di Bella struct lvalue_function_object {
115e06f1a8eSChristopher Di Bella   void operator()() &;
116e06f1a8eSChristopher Di Bella };
117e06f1a8eSChristopher Di Bella static_assert(!std::invocable<lvalue_function_object>);
118e06f1a8eSChristopher Di Bella static_assert(!std::invocable<lvalue_function_object const>);
119e06f1a8eSChristopher Di Bella static_assert(!std::invocable<lvalue_function_object volatile>);
120e06f1a8eSChristopher Di Bella static_assert(!std::invocable<lvalue_function_object const volatile>);
121e06f1a8eSChristopher Di Bella static_assert(std::invocable<lvalue_function_object&>);
122e06f1a8eSChristopher Di Bella static_assert(!std::invocable<lvalue_function_object const&>);
123e06f1a8eSChristopher Di Bella static_assert(!std::invocable<lvalue_function_object volatile&>);
124e06f1a8eSChristopher Di Bella static_assert(!std::invocable<lvalue_function_object const volatile&>);
125e06f1a8eSChristopher Di Bella 
126e06f1a8eSChristopher Di Bella struct lvalue_const_function_object {
127e06f1a8eSChristopher Di Bella   void operator()(int) const&;
128e06f1a8eSChristopher Di Bella };
129e06f1a8eSChristopher Di Bella static_assert(std::invocable<lvalue_const_function_object, int>);
130e06f1a8eSChristopher Di Bella static_assert(std::invocable<lvalue_const_function_object const, int>);
131e06f1a8eSChristopher Di Bella static_assert(!std::invocable<lvalue_const_function_object volatile, int>);
132e06f1a8eSChristopher Di Bella static_assert(
133e06f1a8eSChristopher Di Bella     !std::invocable<lvalue_const_function_object const volatile, int>);
134e06f1a8eSChristopher Di Bella static_assert(std::invocable<lvalue_const_function_object&, int>);
135e06f1a8eSChristopher Di Bella static_assert(std::invocable<lvalue_const_function_object const&, int>);
136e06f1a8eSChristopher Di Bella static_assert(!std::invocable<lvalue_const_function_object volatile&, int>);
137e06f1a8eSChristopher Di Bella static_assert(
138e06f1a8eSChristopher Di Bella     !std::invocable<lvalue_const_function_object const volatile&, int>);
139e06f1a8eSChristopher Di Bella 
140e06f1a8eSChristopher Di Bella struct lvalue_volatile_function_object {
141e06f1a8eSChristopher Di Bella   void operator()(int, int) volatile&;
142e06f1a8eSChristopher Di Bella };
143e06f1a8eSChristopher Di Bella static_assert(!std::invocable<lvalue_volatile_function_object, int, int>);
144e06f1a8eSChristopher Di Bella static_assert(!std::invocable<lvalue_volatile_function_object const, int, int>);
145e06f1a8eSChristopher Di Bella static_assert(
146e06f1a8eSChristopher Di Bella     !std::invocable<lvalue_volatile_function_object volatile, int, int>);
147e06f1a8eSChristopher Di Bella static_assert(
148e06f1a8eSChristopher Di Bella     !std::invocable<lvalue_volatile_function_object const volatile, int, int>);
149e06f1a8eSChristopher Di Bella static_assert(std::invocable<lvalue_volatile_function_object&, int, int>);
150e06f1a8eSChristopher Di Bella static_assert(
151e06f1a8eSChristopher Di Bella     !std::invocable<lvalue_volatile_function_object const&, int, int>);
152e06f1a8eSChristopher Di Bella static_assert(
153e06f1a8eSChristopher Di Bella     std::invocable<lvalue_volatile_function_object volatile&, int, int>);
154e06f1a8eSChristopher Di Bella static_assert(
155e06f1a8eSChristopher Di Bella     !std::invocable<lvalue_volatile_function_object const volatile&, int, int>);
156e06f1a8eSChristopher Di Bella 
157e06f1a8eSChristopher Di Bella struct lvalue_cv_function_object {
158e06f1a8eSChristopher Di Bella   void operator()(int[]) const volatile&;
159e06f1a8eSChristopher Di Bella };
160e06f1a8eSChristopher Di Bella static_assert(!std::invocable<lvalue_cv_function_object, int*>);
161e06f1a8eSChristopher Di Bella static_assert(!std::invocable<lvalue_cv_function_object const, int*>);
162e06f1a8eSChristopher Di Bella static_assert(!std::invocable<lvalue_cv_function_object volatile, int*>);
163e06f1a8eSChristopher Di Bella static_assert(!std::invocable<lvalue_cv_function_object const volatile, int*>);
164e06f1a8eSChristopher Di Bella static_assert(std::invocable<lvalue_cv_function_object&, int*>);
165e06f1a8eSChristopher Di Bella static_assert(std::invocable<lvalue_cv_function_object const&, int*>);
166e06f1a8eSChristopher Di Bella static_assert(std::invocable<lvalue_cv_function_object volatile&, int*>);
167e06f1a8eSChristopher Di Bella static_assert(std::invocable<lvalue_cv_function_object const volatile&, int*>);
168e06f1a8eSChristopher Di Bella //
169e06f1a8eSChristopher Di Bella struct rvalue_function_object {
170e06f1a8eSChristopher Di Bella   void operator()() &&;
171e06f1a8eSChristopher Di Bella };
172e06f1a8eSChristopher Di Bella static_assert(std::invocable<rvalue_function_object>);
173e06f1a8eSChristopher Di Bella static_assert(!std::invocable<rvalue_function_object const>);
174e06f1a8eSChristopher Di Bella static_assert(!std::invocable<rvalue_function_object volatile>);
175e06f1a8eSChristopher Di Bella static_assert(!std::invocable<rvalue_function_object const volatile>);
176e06f1a8eSChristopher Di Bella static_assert(!std::invocable<rvalue_function_object&>);
177e06f1a8eSChristopher Di Bella static_assert(!std::invocable<rvalue_function_object const&>);
178e06f1a8eSChristopher Di Bella static_assert(!std::invocable<rvalue_function_object volatile&>);
179e06f1a8eSChristopher Di Bella static_assert(!std::invocable<rvalue_function_object const volatile&>);
180e06f1a8eSChristopher Di Bella 
181e06f1a8eSChristopher Di Bella struct rvalue_const_function_object {
182e06f1a8eSChristopher Di Bella   void operator()(int) const&&;
183e06f1a8eSChristopher Di Bella };
184e06f1a8eSChristopher Di Bella static_assert(std::invocable<rvalue_const_function_object, int>);
185e06f1a8eSChristopher Di Bella static_assert(std::invocable<rvalue_const_function_object const, int>);
186e06f1a8eSChristopher Di Bella static_assert(!std::invocable<rvalue_const_function_object volatile, int>);
187e06f1a8eSChristopher Di Bella static_assert(
188e06f1a8eSChristopher Di Bella     !std::invocable<rvalue_const_function_object const volatile, int>);
189e06f1a8eSChristopher Di Bella static_assert(!std::invocable<rvalue_const_function_object&, int>);
190e06f1a8eSChristopher Di Bella static_assert(!std::invocable<rvalue_const_function_object const&, int>);
191e06f1a8eSChristopher Di Bella static_assert(!std::invocable<rvalue_const_function_object volatile&, int>);
192e06f1a8eSChristopher Di Bella static_assert(
193e06f1a8eSChristopher Di Bella     !std::invocable<rvalue_const_function_object const volatile&, int>);
194e06f1a8eSChristopher Di Bella 
195e06f1a8eSChristopher Di Bella struct rvalue_volatile_function_object {
196e06f1a8eSChristopher Di Bella   void operator()(int, int) volatile&&;
197e06f1a8eSChristopher Di Bella };
198e06f1a8eSChristopher Di Bella static_assert(std::invocable<rvalue_volatile_function_object, int, int>);
199e06f1a8eSChristopher Di Bella static_assert(!std::invocable<rvalue_volatile_function_object const, int, int>);
200e06f1a8eSChristopher Di Bella static_assert(
201e06f1a8eSChristopher Di Bella     std::invocable<rvalue_volatile_function_object volatile, int, int>);
202e06f1a8eSChristopher Di Bella static_assert(
203e06f1a8eSChristopher Di Bella     !std::invocable<rvalue_volatile_function_object const volatile, int, int>);
204e06f1a8eSChristopher Di Bella static_assert(!std::invocable<rvalue_volatile_function_object&, int, int>);
205e06f1a8eSChristopher Di Bella static_assert(
206e06f1a8eSChristopher Di Bella     !std::invocable<rvalue_volatile_function_object const&, int, int>);
207e06f1a8eSChristopher Di Bella static_assert(
208e06f1a8eSChristopher Di Bella     !std::invocable<rvalue_volatile_function_object volatile&, int, int>);
209e06f1a8eSChristopher Di Bella static_assert(
210e06f1a8eSChristopher Di Bella     !std::invocable<rvalue_volatile_function_object const volatile&, int, int>);
211e06f1a8eSChristopher Di Bella 
212e06f1a8eSChristopher Di Bella struct rvalue_cv_function_object {
213e06f1a8eSChristopher Di Bella   void operator()(int[]) const volatile&&;
214e06f1a8eSChristopher Di Bella };
215e06f1a8eSChristopher Di Bella static_assert(std::invocable<rvalue_cv_function_object, int*>);
216e06f1a8eSChristopher Di Bella static_assert(std::invocable<rvalue_cv_function_object const, int*>);
217e06f1a8eSChristopher Di Bella static_assert(std::invocable<rvalue_cv_function_object volatile, int*>);
218e06f1a8eSChristopher Di Bella static_assert(std::invocable<rvalue_cv_function_object const volatile, int*>);
219e06f1a8eSChristopher Di Bella static_assert(!std::invocable<rvalue_cv_function_object&, int*>);
220e06f1a8eSChristopher Di Bella static_assert(!std::invocable<rvalue_cv_function_object const&, int*>);
221e06f1a8eSChristopher Di Bella static_assert(!std::invocable<rvalue_cv_function_object volatile&, int*>);
222e06f1a8eSChristopher Di Bella static_assert(!std::invocable<rvalue_cv_function_object const volatile&, int*>);
223e06f1a8eSChristopher Di Bella 
224e06f1a8eSChristopher Di Bella struct multiple_overloads {
22591d6debbSMartin Storsjö   struct A {};
22691d6debbSMartin Storsjö   struct B { B(int); };
22791d6debbSMartin Storsjö   struct AB : A, B {};
22891d6debbSMartin Storsjö   struct O {};
229ae318bebSArthur O'Dwyer   void operator()(A) const;
230ae318bebSArthur O'Dwyer   void operator()(B) const;
231e06f1a8eSChristopher Di Bella };
232ae318bebSArthur O'Dwyer static_assert(std::invocable<multiple_overloads, multiple_overloads::A>);
233ae318bebSArthur O'Dwyer static_assert(std::invocable<multiple_overloads, multiple_overloads::B>);
234ae318bebSArthur O'Dwyer static_assert(std::invocable<multiple_overloads, int>);
235ae318bebSArthur O'Dwyer static_assert(!std::invocable<multiple_overloads, multiple_overloads::AB>);
236ae318bebSArthur O'Dwyer static_assert(!std::invocable<multiple_overloads, multiple_overloads::O>);
237e06f1a8eSChristopher Di Bella } // namespace function_objects
238e06f1a8eSChristopher Di Bella 
239e06f1a8eSChristopher Di Bella namespace pointer_to_member_functions {
240e06f1a8eSChristopher Di Bella   template<class Member, class T, class... Args>
24188b73a98SLouis Dionne   constexpr bool check_member_is_invocable()
24224dd2d2fSChristopher Di Bella   {
2435a3c2763SArthur O'Dwyer     constexpr bool result = std::invocable<Member, T&&, Args...>;
244e06f1a8eSChristopher Di Bella     using uncv_t = std::remove_cvref_t<T>;
245e06f1a8eSChristopher Di Bella     static_assert(std::invocable<Member, uncv_t*, Args...> == result);
246e06f1a8eSChristopher Di Bella     static_assert(std::invocable<Member, std::unique_ptr<uncv_t>, Args...> == result);
247e06f1a8eSChristopher Di Bella     static_assert(std::invocable<Member, std::reference_wrapper<uncv_t>, Args...> == result);
248e06f1a8eSChristopher Di Bella     static_assert(!std::invocable<Member, std::nullptr_t, Args...>);
249e06f1a8eSChristopher Di Bella     static_assert(!std::invocable<Member, int, Args...>);
250e06f1a8eSChristopher Di Bella     static_assert(!std::invocable<Member, int*, Args...>);
251e06f1a8eSChristopher Di Bella     static_assert(!std::invocable<Member, double*, Args...>);
252e06f1a8eSChristopher Di Bella     struct S2 {};
253e06f1a8eSChristopher Di Bella     static_assert(!std::invocable<Member, S2*, Args...>);
254e06f1a8eSChristopher Di Bella     return result;
255e06f1a8eSChristopher Di Bella   }
25624dd2d2fSChristopher Di Bella 
257e06f1a8eSChristopher Di Bella static_assert(check_member_is_invocable<int S::*, S>());
258e06f1a8eSChristopher Di Bella static_assert(std::invocable<int S::*, S&>);
259e06f1a8eSChristopher Di Bella static_assert(std::invocable<int S::*, S const&>);
260e06f1a8eSChristopher Di Bella static_assert(std::invocable<int S::*, S volatile&>);
261e06f1a8eSChristopher Di Bella static_assert(std::invocable<int S::*, S const volatile&>);
262e06f1a8eSChristopher Di Bella static_assert(std::invocable<int S::*, S&&>);
263e06f1a8eSChristopher Di Bella static_assert(std::invocable<int S::*, S const&&>);
264e06f1a8eSChristopher Di Bella static_assert(std::invocable<int S::*, S volatile&&>);
265e06f1a8eSChristopher Di Bella static_assert(std::invocable<int S::*, S const volatile&&>);
26624dd2d2fSChristopher Di Bella 
267e06f1a8eSChristopher Di Bella static_assert(check_member_is_invocable<int (S::*)(int), S, int>());
268e06f1a8eSChristopher Di Bella static_assert(!check_member_is_invocable<int (S::*)(int), S>());
269e06f1a8eSChristopher Di Bella using unqualified = void (S::*)();
270e06f1a8eSChristopher Di Bella static_assert(std::invocable<unqualified, S&>);
271e06f1a8eSChristopher Di Bella static_assert(!std::invocable<unqualified, S const&>);
272e06f1a8eSChristopher Di Bella static_assert(!std::invocable<unqualified, S volatile&>);
273e06f1a8eSChristopher Di Bella static_assert(!std::invocable<unqualified, S const volatile&>);
274e06f1a8eSChristopher Di Bella static_assert(std::invocable<unqualified, S&&>);
275e06f1a8eSChristopher Di Bella static_assert(!std::invocable<unqualified, S const&&>);
276e06f1a8eSChristopher Di Bella static_assert(!std::invocable<unqualified, S volatile&&>);
277e06f1a8eSChristopher Di Bella static_assert(!std::invocable<unqualified, S const volatile&&>);
27824dd2d2fSChristopher Di Bella 
279e06f1a8eSChristopher Di Bella static_assert(check_member_is_invocable<int (S::*)(double) const, S, double>());
280e06f1a8eSChristopher Di Bella using const_qualified = void (S::*)() const;
281e06f1a8eSChristopher Di Bella static_assert(std::invocable<const_qualified, S&>);
282e06f1a8eSChristopher Di Bella static_assert(std::invocable<const_qualified, S const&>);
283e06f1a8eSChristopher Di Bella static_assert(!std::invocable<const_qualified, S volatile&>);
284e06f1a8eSChristopher Di Bella static_assert(!std::invocable<const_qualified, S const volatile&>);
285e06f1a8eSChristopher Di Bella static_assert(std::invocable<const_qualified, S&&>);
286e06f1a8eSChristopher Di Bella static_assert(std::invocable<const_qualified, S const&&>);
287e06f1a8eSChristopher Di Bella static_assert(!std::invocable<const_qualified, S volatile&&>);
288e06f1a8eSChristopher Di Bella static_assert(!std::invocable<const_qualified, S const volatile&&>);
28924dd2d2fSChristopher Di Bella 
290e06f1a8eSChristopher Di Bella static_assert(
291e06f1a8eSChristopher Di Bella     check_member_is_invocable<int (S::*)(double[]) volatile, S, double*>());
292e06f1a8eSChristopher Di Bella using volatile_qualified = void (S::*)() volatile;
293e06f1a8eSChristopher Di Bella static_assert(std::invocable<volatile_qualified, S&>);
294e06f1a8eSChristopher Di Bella static_assert(!std::invocable<volatile_qualified, S const&>);
295e06f1a8eSChristopher Di Bella static_assert(std::invocable<volatile_qualified, S volatile&>);
296e06f1a8eSChristopher Di Bella static_assert(!std::invocable<volatile_qualified, S const volatile&>);
297e06f1a8eSChristopher Di Bella static_assert(std::invocable<volatile_qualified, S&&>);
298e06f1a8eSChristopher Di Bella static_assert(!std::invocable<volatile_qualified, S const&&>);
299e06f1a8eSChristopher Di Bella static_assert(std::invocable<volatile_qualified, S volatile&&>);
300e06f1a8eSChristopher Di Bella static_assert(!std::invocable<volatile_qualified, S const volatile&&>);
301e06f1a8eSChristopher Di Bella 
302e06f1a8eSChristopher Di Bella static_assert(check_member_is_invocable<int (S::*)(int, S&) const volatile, S,
303e06f1a8eSChristopher Di Bella                                         int, S&>());
304e06f1a8eSChristopher Di Bella using cv_qualified = void (S::*)() const volatile;
305e06f1a8eSChristopher Di Bella static_assert(std::invocable<cv_qualified, S&>);
306e06f1a8eSChristopher Di Bella static_assert(std::invocable<cv_qualified, S const&>);
307e06f1a8eSChristopher Di Bella static_assert(std::invocable<cv_qualified, S volatile&>);
308e06f1a8eSChristopher Di Bella static_assert(std::invocable<cv_qualified, S const volatile&>);
309e06f1a8eSChristopher Di Bella static_assert(std::invocable<cv_qualified, S&&>);
310e06f1a8eSChristopher Di Bella static_assert(std::invocable<cv_qualified, S const&&>);
311e06f1a8eSChristopher Di Bella static_assert(std::invocable<cv_qualified, S volatile&&>);
312e06f1a8eSChristopher Di Bella static_assert(std::invocable<cv_qualified, S const volatile&&>);
313e06f1a8eSChristopher Di Bella 
314e06f1a8eSChristopher Di Bella static_assert(check_member_is_invocable<int (S::*)() &, S&>());
315e06f1a8eSChristopher Di Bella using lvalue_qualified = void (S::*)() &;
316e06f1a8eSChristopher Di Bella static_assert(std::invocable<lvalue_qualified, S&>);
317e06f1a8eSChristopher Di Bella static_assert(!std::invocable<lvalue_qualified, S const&>);
318e06f1a8eSChristopher Di Bella static_assert(!std::invocable<lvalue_qualified, S volatile&>);
319e06f1a8eSChristopher Di Bella static_assert(!std::invocable<lvalue_qualified, S const volatile&>);
320e06f1a8eSChristopher Di Bella static_assert(!std::invocable<lvalue_qualified, S&&>);
321e06f1a8eSChristopher Di Bella static_assert(!std::invocable<lvalue_qualified, S const&&>);
322e06f1a8eSChristopher Di Bella static_assert(!std::invocable<lvalue_qualified, S volatile&&>);
323e06f1a8eSChristopher Di Bella static_assert(!std::invocable<lvalue_qualified, S const volatile&&>);
324e06f1a8eSChristopher Di Bella 
325e06f1a8eSChristopher Di Bella static_assert(check_member_is_invocable<int (S::*)() const&, S>());
326e06f1a8eSChristopher Di Bella using lvalue_const_qualified = void (S::*)() const&;
327e06f1a8eSChristopher Di Bella static_assert(std::invocable<lvalue_const_qualified, S&>);
328e06f1a8eSChristopher Di Bella static_assert(std::invocable<lvalue_const_qualified, S const&>);
329e06f1a8eSChristopher Di Bella static_assert(!std::invocable<lvalue_const_qualified, S volatile&>);
330e06f1a8eSChristopher Di Bella static_assert(!std::invocable<lvalue_const_qualified, S const volatile&>);
331e06f1a8eSChristopher Di Bella static_assert(std::invocable<lvalue_const_qualified, S&&>);
332e06f1a8eSChristopher Di Bella static_assert(std::invocable<lvalue_const_qualified, S const&&>);
333e06f1a8eSChristopher Di Bella static_assert(!std::invocable<lvalue_const_qualified, S volatile&&>);
334e06f1a8eSChristopher Di Bella static_assert(!std::invocable<lvalue_const_qualified, S const volatile&&>);
335e06f1a8eSChristopher Di Bella 
336e06f1a8eSChristopher Di Bella static_assert(check_member_is_invocable<int (S::*)() volatile&, S&>());
337e06f1a8eSChristopher Di Bella using lvalue_volatile_qualified = void (S::*)() volatile&;
338e06f1a8eSChristopher Di Bella static_assert(std::invocable<lvalue_volatile_qualified, S&>);
339e06f1a8eSChristopher Di Bella static_assert(!std::invocable<lvalue_volatile_qualified, S const&>);
340e06f1a8eSChristopher Di Bella static_assert(std::invocable<lvalue_volatile_qualified, S volatile&>);
341e06f1a8eSChristopher Di Bella static_assert(!std::invocable<lvalue_volatile_qualified, S const volatile&>);
342e06f1a8eSChristopher Di Bella static_assert(!std::invocable<lvalue_volatile_qualified, S&&>);
343e06f1a8eSChristopher Di Bella static_assert(!std::invocable<lvalue_volatile_qualified, S const&&>);
344e06f1a8eSChristopher Di Bella static_assert(!std::invocable<lvalue_volatile_qualified, S volatile&&>);
345e06f1a8eSChristopher Di Bella static_assert(!std::invocable<lvalue_volatile_qualified, S const volatile&&>);
346e06f1a8eSChristopher Di Bella 
347e06f1a8eSChristopher Di Bella static_assert(check_member_is_invocable<int (S::*)() const volatile&, S&>());
348e06f1a8eSChristopher Di Bella using lvalue_cv_qualified = void (S::*)() const volatile&;
349e06f1a8eSChristopher Di Bella static_assert(std::invocable<lvalue_cv_qualified, S&>);
350e06f1a8eSChristopher Di Bella static_assert(std::invocable<lvalue_cv_qualified, S const&>);
351e06f1a8eSChristopher Di Bella static_assert(std::invocable<lvalue_cv_qualified, S volatile&>);
352e06f1a8eSChristopher Di Bella static_assert(std::invocable<lvalue_cv_qualified, S const volatile&>);
353e06f1a8eSChristopher Di Bella static_assert(!std::invocable<lvalue_cv_qualified, S&&>);
354e06f1a8eSChristopher Di Bella static_assert(!std::invocable<lvalue_cv_qualified, S const&&>);
355e06f1a8eSChristopher Di Bella static_assert(!std::invocable<lvalue_cv_qualified, S volatile&&>);
356e06f1a8eSChristopher Di Bella static_assert(!std::invocable<lvalue_cv_qualified, S const volatile&&>);
357e06f1a8eSChristopher Di Bella 
358e06f1a8eSChristopher Di Bella using rvalue_unqualified = void (S::*)() &&;
359e06f1a8eSChristopher Di Bella static_assert(!std::invocable<rvalue_unqualified, S&>);
360e06f1a8eSChristopher Di Bella static_assert(!std::invocable<rvalue_unqualified, S const&>);
361e06f1a8eSChristopher Di Bella static_assert(!std::invocable<rvalue_unqualified, S volatile&>);
362e06f1a8eSChristopher Di Bella static_assert(!std::invocable<rvalue_unqualified, S const volatile&>);
363e06f1a8eSChristopher Di Bella static_assert(std::invocable<rvalue_unqualified, S&&>);
364e06f1a8eSChristopher Di Bella static_assert(!std::invocable<rvalue_unqualified, S const&&>);
365e06f1a8eSChristopher Di Bella static_assert(!std::invocable<rvalue_unqualified, S volatile&&>);
366e06f1a8eSChristopher Di Bella static_assert(!std::invocable<rvalue_unqualified, S const volatile&&>);
367e06f1a8eSChristopher Di Bella 
368e06f1a8eSChristopher Di Bella using rvalue_const_unqualified = void (S::*)() const&&;
369e06f1a8eSChristopher Di Bella static_assert(!std::invocable<rvalue_const_unqualified, S&>);
370e06f1a8eSChristopher Di Bella static_assert(!std::invocable<rvalue_const_unqualified, S const&>);
371e06f1a8eSChristopher Di Bella static_assert(!std::invocable<rvalue_const_unqualified, S volatile&>);
372e06f1a8eSChristopher Di Bella static_assert(!std::invocable<rvalue_const_unqualified, S const volatile&>);
373e06f1a8eSChristopher Di Bella static_assert(std::invocable<rvalue_const_unqualified, S&&>);
374e06f1a8eSChristopher Di Bella static_assert(std::invocable<rvalue_const_unqualified, S const&&>);
375e06f1a8eSChristopher Di Bella static_assert(!std::invocable<rvalue_const_unqualified, S volatile&&>);
376e06f1a8eSChristopher Di Bella static_assert(!std::invocable<rvalue_const_unqualified, S const volatile&&>);
377e06f1a8eSChristopher Di Bella 
378e06f1a8eSChristopher Di Bella using rvalue_volatile_unqualified = void (S::*)() volatile&&;
379e06f1a8eSChristopher Di Bella static_assert(!std::invocable<rvalue_volatile_unqualified, S&>);
380e06f1a8eSChristopher Di Bella static_assert(!std::invocable<rvalue_volatile_unqualified, S const&>);
381e06f1a8eSChristopher Di Bella static_assert(!std::invocable<rvalue_volatile_unqualified, S volatile&>);
382e06f1a8eSChristopher Di Bella static_assert(!std::invocable<rvalue_volatile_unqualified, S const volatile&>);
383e06f1a8eSChristopher Di Bella static_assert(std::invocable<rvalue_volatile_unqualified, S&&>);
384e06f1a8eSChristopher Di Bella static_assert(!std::invocable<rvalue_volatile_unqualified, S const&&>);
385e06f1a8eSChristopher Di Bella static_assert(std::invocable<rvalue_volatile_unqualified, S volatile&&>);
386e06f1a8eSChristopher Di Bella static_assert(!std::invocable<rvalue_volatile_unqualified, S const volatile&&>);
387e06f1a8eSChristopher Di Bella 
388e06f1a8eSChristopher Di Bella using rvalue_cv_unqualified = void (S::*)() const volatile&&;
389e06f1a8eSChristopher Di Bella static_assert(!std::invocable<rvalue_cv_unqualified, S&>);
390e06f1a8eSChristopher Di Bella static_assert(!std::invocable<rvalue_cv_unqualified, S const&>);
391e06f1a8eSChristopher Di Bella static_assert(!std::invocable<rvalue_cv_unqualified, S volatile&>);
392e06f1a8eSChristopher Di Bella static_assert(!std::invocable<rvalue_cv_unqualified, S const volatile&>);
393e06f1a8eSChristopher Di Bella static_assert(std::invocable<rvalue_cv_unqualified, S&&>);
394e06f1a8eSChristopher Di Bella static_assert(std::invocable<rvalue_cv_unqualified, S const&&>);
395e06f1a8eSChristopher Di Bella static_assert(std::invocable<rvalue_cv_unqualified, S volatile&&>);
396e06f1a8eSChristopher Di Bella static_assert(std::invocable<rvalue_cv_unqualified, S const volatile&&>);
397e06f1a8eSChristopher Di Bella } // namespace pointer_to_member_functions
398e06f1a8eSChristopher Di Bella 
399e06f1a8eSChristopher Di Bella // std::invocable-specific
40031191e15SLouis Dionne static_assert(std::invocable<std::uniform_int_distribution<>, std::mt19937_64&>);
401e06f1a8eSChristopher Di Bella 
40231191e15SLouis Dionne // Check the concept with closure types
403e06f1a8eSChristopher Di Bella template<class F, class... Args>
40431191e15SLouis Dionne constexpr bool is_invocable(F, Args&&...) {
40531191e15SLouis Dionne   return std::invocable<F, Args...>;
406e06f1a8eSChristopher Di Bella }
40724dd2d2fSChristopher Di Bella 
40831191e15SLouis Dionne static_assert(is_invocable([] {}));
40931191e15SLouis Dionne static_assert(is_invocable([](int) {}, 0));
41031191e15SLouis Dionne static_assert(is_invocable([](int) {}, 0L));
41131191e15SLouis Dionne static_assert(!is_invocable([](int) {}, nullptr));
412e06f1a8eSChristopher Di Bella int i = 0;
41331191e15SLouis Dionne static_assert(is_invocable([](int&) {}, i));
414