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