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

source code of libcxx/test/std/concepts/concepts.callable/concept.regularinvocable/regular_invocable.compile.pass.cpp