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

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