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