1 //===----------------------------------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 // UNSUPPORTED: c++03, c++11, c++14, c++17
11 // template<class T, class U>
12 // concept regular_invocable;
18 #include <type_traits>
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
...> ==
27 static_assert(std::regular_invocable
<R (&)(Args
...), Args
...> == result
);
28 static_assert(std::regular_invocable
<R (&)(Args
...) noexcept
, Args
...> ==
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[]>());
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&>);
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&>);
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&&>);
64 namespace function_objects
{
65 struct function_object
{
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&>);
77 struct const_function_object
{
78 void operator()(int) const;
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>);
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>);
89 !std::regular_invocable
<const_function_object
const volatile&, int>);
91 struct volatile_function_object
{
92 void operator()(int, int) volatile;
94 static_assert(std::regular_invocable
<volatile_function_object
, int, int>);
96 !std::regular_invocable
<volatile_function_object
const, int, int>);
98 std::regular_invocable
<volatile_function_object
volatile, int, int>);
100 !std::regular_invocable
<volatile_function_object
const volatile, int, int>);
101 static_assert(std::regular_invocable
<volatile_function_object
&, int, int>);
103 !std::regular_invocable
<volatile_function_object
const&, int, int>);
105 std::regular_invocable
<volatile_function_object
volatile&, int, int>);
106 static_assert(!std::regular_invocable
<volatile_function_object
const volatile&,
109 struct cv_function_object
{
110 void operator()(int[]) const volatile;
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*>);
121 struct lvalue_function_object
{
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&>);
133 struct lvalue_const_function_object
{
134 void operator()(int) const&;
136 static_assert(std::regular_invocable
<lvalue_const_function_object
, int>);
137 static_assert(std::regular_invocable
<lvalue_const_function_object
const, int>);
139 !std::regular_invocable
<lvalue_const_function_object
volatile, int>);
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>);
145 !std::regular_invocable
<lvalue_const_function_object
volatile&, int>);
147 !std::regular_invocable
<lvalue_const_function_object
const volatile&, int>);
149 struct lvalue_volatile_function_object
{
150 void operator()(int, int) volatile&;
153 !std::regular_invocable
<lvalue_volatile_function_object
, int, int>);
155 !std::regular_invocable
<lvalue_volatile_function_object
const, int, int>);
156 static_assert(!std::regular_invocable
<lvalue_volatile_function_object
volatile,
158 static_assert(!std::regular_invocable
<
159 lvalue_volatile_function_object
const volatile, int, int>);
161 std::regular_invocable
<lvalue_volatile_function_object
&, int, int>);
163 !std::regular_invocable
<lvalue_volatile_function_object
const&, int, int>);
164 static_assert(std::regular_invocable
<lvalue_volatile_function_object
volatile&,
166 static_assert(!std::regular_invocable
<
167 lvalue_volatile_function_object
const volatile&, int, int>);
169 struct lvalue_cv_function_object
{
170 void operator()(int[]) const volatile&;
172 static_assert(!std::regular_invocable
<lvalue_cv_function_object
, int*>);
173 static_assert(!std::regular_invocable
<lvalue_cv_function_object
const, int*>);
175 !std::regular_invocable
<lvalue_cv_function_object
volatile, int*>);
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*>);
181 std::regular_invocable
<lvalue_cv_function_object
volatile&, int*>);
183 std::regular_invocable
<lvalue_cv_function_object
const volatile&, int*>);
185 struct rvalue_function_object
{
186 void operator()() &&;
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&>);
197 struct rvalue_const_function_object
{
198 void operator()(int) const&&;
200 static_assert(std::regular_invocable
<rvalue_const_function_object
, int>);
201 static_assert(std::regular_invocable
<rvalue_const_function_object
const, int>);
203 !std::regular_invocable
<rvalue_const_function_object
volatile, int>);
205 !std::regular_invocable
<rvalue_const_function_object
const volatile, int>);
206 static_assert(!std::regular_invocable
<rvalue_const_function_object
&, int>);
208 !std::regular_invocable
<rvalue_const_function_object
const&, int>);
210 !std::regular_invocable
<rvalue_const_function_object
volatile&, int>);
212 !std::regular_invocable
<rvalue_const_function_object
const volatile&, int>);
214 struct rvalue_volatile_function_object
{
215 void operator()(int, int) volatile&&;
218 std::regular_invocable
<rvalue_volatile_function_object
, int, int>);
220 !std::regular_invocable
<rvalue_volatile_function_object
const, int, int>);
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>);
226 !std::regular_invocable
<rvalue_volatile_function_object
&, int, int>);
228 !std::regular_invocable
<rvalue_volatile_function_object
const&, int, int>);
229 static_assert(!std::regular_invocable
<rvalue_volatile_function_object
volatile&,
231 static_assert(!std::regular_invocable
<
232 rvalue_volatile_function_object
const volatile&, int, int>);
234 struct rvalue_cv_function_object
{
235 void operator()(int[]) const volatile&&;
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*>);
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*>);
245 !std::regular_invocable
<rvalue_cv_function_object
volatile&, int*>);
247 !std::regular_invocable
<rvalue_cv_function_object
const volatile&, int*>);
249 struct multiple_overloads
{
251 struct B
{ B(int); };
254 void operator()(A
) const;
255 void operator()(B
) const;
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
264 namespace pointer_to_member_functions
{
265 template<class Member
, class T
, class... Args
>
266 constexpr bool check_member_is_invocable()
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
...>);
278 static_assert(!std::regular_invocable
<Member
, S2
*, Args
...>);
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&&>);
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&&>);
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&&>);
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&&>);
327 static_assert(check_member_is_invocable
<int (S::*)(int, S
&) const volatile, 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&&>);
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&&>);
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&>);
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&&>);
361 !std::regular_invocable
<lvalue_const_qualified
, S
const volatile&&>);
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&>);
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&&>);
374 !std::regular_invocable
<lvalue_volatile_qualified
, S
const volatile&&>);
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&&>);
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&&>);
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&>);
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&&>);
407 !std::regular_invocable
<rvalue_const_unqualified
, S
const volatile&&>);
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&>);
413 !std::regular_invocable
<rvalue_volatile_unqualified
, S
volatile&>);
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&&>);
419 std::regular_invocable
<rvalue_volatile_unqualified
, S
volatile&&>);
421 !std::regular_invocable
<rvalue_volatile_unqualified
, S
const volatile&&>);
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&>);
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&&>);
433 std::regular_invocable
<rvalue_cv_unqualified
, S
const volatile&&>);
434 } // namespace pointer_to_member_functions
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
&&...) {
442 template<class F
, class... Args
>
443 requires
std::invocable
<F
, Args
...>
444 constexpr bool is_regular_invocable(F
, Args
&&...) {
448 template<class F
, class... Args
>
449 requires
std::regular_invocable
<F
, Args
...> && true
450 constexpr bool is_regular_invocable(F
, Args
&&...) {
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));
460 static_assert(is_regular_invocable([](int&) {}, i
));