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