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>
19 #include <type_traits>
21 template <class R
, class... Args
>
22 constexpr bool check_invocable() {
23 constexpr bool result
= std::invocable
<R(Args
...), Args
...>;
24 static_assert(std::invocable
<R(Args
...) noexcept
, Args
...> == result
);
25 static_assert(std::invocable
<R (*)(Args
...), Args
...> == result
);
26 static_assert(std::invocable
<R (*)(Args
...) noexcept
, Args
...> == result
);
27 static_assert(std::invocable
<R (&)(Args
...), Args
...> == result
);
28 static_assert(std::invocable
<R (&)(Args
...) noexcept
, Args
...> == result
);
33 static_assert(check_invocable
<void>());
34 static_assert(check_invocable
<void, int>());
35 static_assert(check_invocable
<void, int&>());
36 static_assert(check_invocable
<void, int*, double>());
37 static_assert(check_invocable
<int>());
38 static_assert(check_invocable
<int, int[]>());
41 static_assert(check_invocable
<int, int S::*, std::nullptr_t
>());
42 static_assert(check_invocable
<int, int (S::*)(), int (S::*)(int), int>());
43 static_assert(std::invocable
<void (*)(int const&), int&>);
44 static_assert(std::invocable
<void (*)(int const&), int&&>);
45 static_assert(std::invocable
<void (*)(int volatile&), int&>);
46 static_assert(std::invocable
<void (*)(int const volatile&), int&>);
48 static_assert(!std::invocable
<void(), int>);
49 static_assert(!std::invocable
<void(int)>);
50 static_assert(!std::invocable
<void(int*), double*>);
51 static_assert(!std::invocable
<void (*)(int&), double*>);
52 static_assert(std::invocable
<int S::*, std::unique_ptr
<S
> >);
53 static_assert(std::invocable
<int S::*, std::shared_ptr
<S
> >);
54 static_assert(!std::invocable
<void (*)(int&&), int&>);
55 static_assert(!std::invocable
<void (*)(int&&), int const&>);
57 static_assert(!std::invocable
<void>);
58 static_assert(!std::invocable
<void*>);
59 static_assert(!std::invocable
<int>);
60 static_assert(!std::invocable
<int&>);
61 static_assert(!std::invocable
<int&&>);
63 namespace function_objects
{
64 struct function_object
{
67 static_assert(std::invocable
<function_object
>);
68 static_assert(!std::invocable
<function_object
const>);
69 static_assert(!std::invocable
<function_object
volatile>);
70 static_assert(!std::invocable
<function_object
const volatile>);
71 static_assert(std::invocable
<function_object
&>);
72 static_assert(!std::invocable
<function_object
const&>);
73 static_assert(!std::invocable
<function_object
volatile&>);
74 static_assert(!std::invocable
<function_object
const volatile&>);
76 struct const_function_object
{
77 void operator()(int) const;
79 static_assert(std::invocable
<const_function_object
, int>);
80 static_assert(std::invocable
<const_function_object
const, int>);
81 static_assert(!std::invocable
<const_function_object
volatile, int>);
82 static_assert(!std::invocable
<const_function_object
const volatile, int>);
83 static_assert(std::invocable
<const_function_object
&, int>);
84 static_assert(std::invocable
<const_function_object
const&, int>);
85 static_assert(!std::invocable
<const_function_object
volatile&, int>);
86 static_assert(!std::invocable
<const_function_object
const volatile&, int>);
88 struct volatile_function_object
{
89 void operator()(int, int) volatile;
91 static_assert(std::invocable
<volatile_function_object
, int, int>);
92 static_assert(!std::invocable
<volatile_function_object
const, int, int>);
93 static_assert(std::invocable
<volatile_function_object
volatile, int, int>);
95 !std::invocable
<volatile_function_object
const volatile, int, int>);
96 static_assert(std::invocable
<volatile_function_object
&, int, int>);
97 static_assert(!std::invocable
<volatile_function_object
const&, int, int>);
98 static_assert(std::invocable
<volatile_function_object
volatile&, int, int>);
100 !std::invocable
<volatile_function_object
const volatile&, int, int>);
102 struct cv_function_object
{
103 void operator()(int[]) const volatile;
105 static_assert(std::invocable
<cv_function_object
, int*>);
106 static_assert(std::invocable
<cv_function_object
const, int*>);
107 static_assert(std::invocable
<cv_function_object
volatile, int*>);
108 static_assert(std::invocable
<cv_function_object
const volatile, int*>);
109 static_assert(std::invocable
<cv_function_object
&, int*>);
110 static_assert(std::invocable
<cv_function_object
const&, int*>);
111 static_assert(std::invocable
<cv_function_object
volatile&, int*>);
112 static_assert(std::invocable
<cv_function_object
const volatile&, int*>);
114 struct lvalue_function_object
{
117 static_assert(!std::invocable
<lvalue_function_object
>);
118 static_assert(!std::invocable
<lvalue_function_object
const>);
119 static_assert(!std::invocable
<lvalue_function_object
volatile>);
120 static_assert(!std::invocable
<lvalue_function_object
const volatile>);
121 static_assert(std::invocable
<lvalue_function_object
&>);
122 static_assert(!std::invocable
<lvalue_function_object
const&>);
123 static_assert(!std::invocable
<lvalue_function_object
volatile&>);
124 static_assert(!std::invocable
<lvalue_function_object
const volatile&>);
126 struct lvalue_const_function_object
{
127 void operator()(int) const&;
129 static_assert(std::invocable
<lvalue_const_function_object
, int>);
130 static_assert(std::invocable
<lvalue_const_function_object
const, int>);
131 static_assert(!std::invocable
<lvalue_const_function_object
volatile, int>);
133 !std::invocable
<lvalue_const_function_object
const volatile, int>);
134 static_assert(std::invocable
<lvalue_const_function_object
&, int>);
135 static_assert(std::invocable
<lvalue_const_function_object
const&, int>);
136 static_assert(!std::invocable
<lvalue_const_function_object
volatile&, int>);
138 !std::invocable
<lvalue_const_function_object
const volatile&, int>);
140 struct lvalue_volatile_function_object
{
141 void operator()(int, int) volatile&;
143 static_assert(!std::invocable
<lvalue_volatile_function_object
, int, int>);
144 static_assert(!std::invocable
<lvalue_volatile_function_object
const, int, int>);
146 !std::invocable
<lvalue_volatile_function_object
volatile, int, int>);
148 !std::invocable
<lvalue_volatile_function_object
const volatile, int, int>);
149 static_assert(std::invocable
<lvalue_volatile_function_object
&, int, int>);
151 !std::invocable
<lvalue_volatile_function_object
const&, int, int>);
153 std::invocable
<lvalue_volatile_function_object
volatile&, int, int>);
155 !std::invocable
<lvalue_volatile_function_object
const volatile&, int, int>);
157 struct lvalue_cv_function_object
{
158 void operator()(int[]) const volatile&;
160 static_assert(!std::invocable
<lvalue_cv_function_object
, int*>);
161 static_assert(!std::invocable
<lvalue_cv_function_object
const, int*>);
162 static_assert(!std::invocable
<lvalue_cv_function_object
volatile, int*>);
163 static_assert(!std::invocable
<lvalue_cv_function_object
const volatile, int*>);
164 static_assert(std::invocable
<lvalue_cv_function_object
&, int*>);
165 static_assert(std::invocable
<lvalue_cv_function_object
const&, int*>);
166 static_assert(std::invocable
<lvalue_cv_function_object
volatile&, int*>);
167 static_assert(std::invocable
<lvalue_cv_function_object
const volatile&, int*>);
169 struct rvalue_function_object
{
170 void operator()() &&;
172 static_assert(std::invocable
<rvalue_function_object
>);
173 static_assert(!std::invocable
<rvalue_function_object
const>);
174 static_assert(!std::invocable
<rvalue_function_object
volatile>);
175 static_assert(!std::invocable
<rvalue_function_object
const volatile>);
176 static_assert(!std::invocable
<rvalue_function_object
&>);
177 static_assert(!std::invocable
<rvalue_function_object
const&>);
178 static_assert(!std::invocable
<rvalue_function_object
volatile&>);
179 static_assert(!std::invocable
<rvalue_function_object
const volatile&>);
181 struct rvalue_const_function_object
{
182 void operator()(int) const&&;
184 static_assert(std::invocable
<rvalue_const_function_object
, int>);
185 static_assert(std::invocable
<rvalue_const_function_object
const, int>);
186 static_assert(!std::invocable
<rvalue_const_function_object
volatile, int>);
188 !std::invocable
<rvalue_const_function_object
const volatile, int>);
189 static_assert(!std::invocable
<rvalue_const_function_object
&, int>);
190 static_assert(!std::invocable
<rvalue_const_function_object
const&, int>);
191 static_assert(!std::invocable
<rvalue_const_function_object
volatile&, int>);
193 !std::invocable
<rvalue_const_function_object
const volatile&, int>);
195 struct rvalue_volatile_function_object
{
196 void operator()(int, int) volatile&&;
198 static_assert(std::invocable
<rvalue_volatile_function_object
, int, int>);
199 static_assert(!std::invocable
<rvalue_volatile_function_object
const, int, int>);
201 std::invocable
<rvalue_volatile_function_object
volatile, int, int>);
203 !std::invocable
<rvalue_volatile_function_object
const volatile, int, int>);
204 static_assert(!std::invocable
<rvalue_volatile_function_object
&, int, int>);
206 !std::invocable
<rvalue_volatile_function_object
const&, int, int>);
208 !std::invocable
<rvalue_volatile_function_object
volatile&, int, int>);
210 !std::invocable
<rvalue_volatile_function_object
const volatile&, int, int>);
212 struct rvalue_cv_function_object
{
213 void operator()(int[]) const volatile&&;
215 static_assert(std::invocable
<rvalue_cv_function_object
, int*>);
216 static_assert(std::invocable
<rvalue_cv_function_object
const, int*>);
217 static_assert(std::invocable
<rvalue_cv_function_object
volatile, int*>);
218 static_assert(std::invocable
<rvalue_cv_function_object
const volatile, int*>);
219 static_assert(!std::invocable
<rvalue_cv_function_object
&, int*>);
220 static_assert(!std::invocable
<rvalue_cv_function_object
const&, int*>);
221 static_assert(!std::invocable
<rvalue_cv_function_object
volatile&, int*>);
222 static_assert(!std::invocable
<rvalue_cv_function_object
const volatile&, int*>);
224 struct multiple_overloads
{
226 struct B
{ B(int); };
229 void operator()(A
) const;
230 void operator()(B
) const;
232 static_assert(std::invocable
<multiple_overloads
, multiple_overloads::A
>);
233 static_assert(std::invocable
<multiple_overloads
, multiple_overloads::B
>);
234 static_assert(std::invocable
<multiple_overloads
, int>);
235 static_assert(!std::invocable
<multiple_overloads
, multiple_overloads::AB
>);
236 static_assert(!std::invocable
<multiple_overloads
, multiple_overloads::O
>);
237 } // namespace function_objects
239 namespace pointer_to_member_functions
{
240 template<class Member
, class T
, class... Args
>
241 constexpr bool check_member_is_invocable()
243 constexpr bool result
= std::invocable
<Member
, T
&&, Args
...>;
244 using uncv_t
= std::remove_cvref_t
<T
>;
245 static_assert(std::invocable
<Member
, uncv_t
*, Args
...> == result
);
246 static_assert(std::invocable
<Member
, std::unique_ptr
<uncv_t
>, Args
...> == result
);
247 static_assert(std::invocable
<Member
, std::reference_wrapper
<uncv_t
>, Args
...> == result
);
248 static_assert(!std::invocable
<Member
, std::nullptr_t
, Args
...>);
249 static_assert(!std::invocable
<Member
, int, Args
...>);
250 static_assert(!std::invocable
<Member
, int*, Args
...>);
251 static_assert(!std::invocable
<Member
, double*, Args
...>);
253 static_assert(!std::invocable
<Member
, S2
*, Args
...>);
257 static_assert(check_member_is_invocable
<int S::*, S
>());
258 static_assert(std::invocable
<int S::*, S
&>);
259 static_assert(std::invocable
<int S::*, S
const&>);
260 static_assert(std::invocable
<int S::*, S
volatile&>);
261 static_assert(std::invocable
<int S::*, S
const volatile&>);
262 static_assert(std::invocable
<int S::*, S
&&>);
263 static_assert(std::invocable
<int S::*, S
const&&>);
264 static_assert(std::invocable
<int S::*, S
volatile&&>);
265 static_assert(std::invocable
<int S::*, S
const volatile&&>);
267 static_assert(check_member_is_invocable
<int (S::*)(int), S
, int>());
268 static_assert(!check_member_is_invocable
<int (S::*)(int), S
>());
269 using unqualified
= void (S::*)();
270 static_assert(std::invocable
<unqualified
, S
&>);
271 static_assert(!std::invocable
<unqualified
, S
const&>);
272 static_assert(!std::invocable
<unqualified
, S
volatile&>);
273 static_assert(!std::invocable
<unqualified
, S
const volatile&>);
274 static_assert(std::invocable
<unqualified
, S
&&>);
275 static_assert(!std::invocable
<unqualified
, S
const&&>);
276 static_assert(!std::invocable
<unqualified
, S
volatile&&>);
277 static_assert(!std::invocable
<unqualified
, S
const volatile&&>);
279 static_assert(check_member_is_invocable
<int (S::*)(double) const, S
, double>());
280 using const_qualified
= void (S::*)() const;
281 static_assert(std::invocable
<const_qualified
, S
&>);
282 static_assert(std::invocable
<const_qualified
, S
const&>);
283 static_assert(!std::invocable
<const_qualified
, S
volatile&>);
284 static_assert(!std::invocable
<const_qualified
, S
const volatile&>);
285 static_assert(std::invocable
<const_qualified
, S
&&>);
286 static_assert(std::invocable
<const_qualified
, S
const&&>);
287 static_assert(!std::invocable
<const_qualified
, S
volatile&&>);
288 static_assert(!std::invocable
<const_qualified
, S
const volatile&&>);
291 check_member_is_invocable
<int (S::*)(double[]) volatile, S
, double*>());
292 using volatile_qualified
= void (S::*)() volatile;
293 static_assert(std::invocable
<volatile_qualified
, S
&>);
294 static_assert(!std::invocable
<volatile_qualified
, S
const&>);
295 static_assert(std::invocable
<volatile_qualified
, S
volatile&>);
296 static_assert(!std::invocable
<volatile_qualified
, S
const volatile&>);
297 static_assert(std::invocable
<volatile_qualified
, S
&&>);
298 static_assert(!std::invocable
<volatile_qualified
, S
const&&>);
299 static_assert(std::invocable
<volatile_qualified
, S
volatile&&>);
300 static_assert(!std::invocable
<volatile_qualified
, S
const volatile&&>);
302 static_assert(check_member_is_invocable
<int (S::*)(int, S
&) const volatile, S
,
304 using cv_qualified
= void (S::*)() const volatile;
305 static_assert(std::invocable
<cv_qualified
, S
&>);
306 static_assert(std::invocable
<cv_qualified
, S
const&>);
307 static_assert(std::invocable
<cv_qualified
, S
volatile&>);
308 static_assert(std::invocable
<cv_qualified
, S
const volatile&>);
309 static_assert(std::invocable
<cv_qualified
, S
&&>);
310 static_assert(std::invocable
<cv_qualified
, S
const&&>);
311 static_assert(std::invocable
<cv_qualified
, S
volatile&&>);
312 static_assert(std::invocable
<cv_qualified
, S
const volatile&&>);
314 static_assert(check_member_is_invocable
<int (S::*)() &, S
&>());
315 using lvalue_qualified
= void (S::*)() &;
316 static_assert(std::invocable
<lvalue_qualified
, S
&>);
317 static_assert(!std::invocable
<lvalue_qualified
, S
const&>);
318 static_assert(!std::invocable
<lvalue_qualified
, S
volatile&>);
319 static_assert(!std::invocable
<lvalue_qualified
, S
const volatile&>);
320 static_assert(!std::invocable
<lvalue_qualified
, S
&&>);
321 static_assert(!std::invocable
<lvalue_qualified
, S
const&&>);
322 static_assert(!std::invocable
<lvalue_qualified
, S
volatile&&>);
323 static_assert(!std::invocable
<lvalue_qualified
, S
const volatile&&>);
325 static_assert(check_member_is_invocable
<int (S::*)() const&, S
>());
326 using lvalue_const_qualified
= void (S::*)() const&;
327 static_assert(std::invocable
<lvalue_const_qualified
, S
&>);
328 static_assert(std::invocable
<lvalue_const_qualified
, S
const&>);
329 static_assert(!std::invocable
<lvalue_const_qualified
, S
volatile&>);
330 static_assert(!std::invocable
<lvalue_const_qualified
, S
const volatile&>);
331 static_assert(std::invocable
<lvalue_const_qualified
, S
&&>);
332 static_assert(std::invocable
<lvalue_const_qualified
, S
const&&>);
333 static_assert(!std::invocable
<lvalue_const_qualified
, S
volatile&&>);
334 static_assert(!std::invocable
<lvalue_const_qualified
, S
const volatile&&>);
336 static_assert(check_member_is_invocable
<int (S::*)() volatile&, S
&>());
337 using lvalue_volatile_qualified
= void (S::*)() volatile&;
338 static_assert(std::invocable
<lvalue_volatile_qualified
, S
&>);
339 static_assert(!std::invocable
<lvalue_volatile_qualified
, S
const&>);
340 static_assert(std::invocable
<lvalue_volatile_qualified
, S
volatile&>);
341 static_assert(!std::invocable
<lvalue_volatile_qualified
, S
const volatile&>);
342 static_assert(!std::invocable
<lvalue_volatile_qualified
, S
&&>);
343 static_assert(!std::invocable
<lvalue_volatile_qualified
, S
const&&>);
344 static_assert(!std::invocable
<lvalue_volatile_qualified
, S
volatile&&>);
345 static_assert(!std::invocable
<lvalue_volatile_qualified
, S
const volatile&&>);
347 static_assert(check_member_is_invocable
<int (S::*)() const volatile&, S
&>());
348 using lvalue_cv_qualified
= void (S::*)() const volatile&;
349 static_assert(std::invocable
<lvalue_cv_qualified
, S
&>);
350 static_assert(std::invocable
<lvalue_cv_qualified
, S
const&>);
351 static_assert(std::invocable
<lvalue_cv_qualified
, S
volatile&>);
352 static_assert(std::invocable
<lvalue_cv_qualified
, S
const volatile&>);
353 static_assert(!std::invocable
<lvalue_cv_qualified
, S
&&>);
354 static_assert(!std::invocable
<lvalue_cv_qualified
, S
const&&>);
355 static_assert(!std::invocable
<lvalue_cv_qualified
, S
volatile&&>);
356 static_assert(!std::invocable
<lvalue_cv_qualified
, S
const volatile&&>);
358 using rvalue_unqualified
= void (S::*)() &&;
359 static_assert(!std::invocable
<rvalue_unqualified
, S
&>);
360 static_assert(!std::invocable
<rvalue_unqualified
, S
const&>);
361 static_assert(!std::invocable
<rvalue_unqualified
, S
volatile&>);
362 static_assert(!std::invocable
<rvalue_unqualified
, S
const volatile&>);
363 static_assert(std::invocable
<rvalue_unqualified
, S
&&>);
364 static_assert(!std::invocable
<rvalue_unqualified
, S
const&&>);
365 static_assert(!std::invocable
<rvalue_unqualified
, S
volatile&&>);
366 static_assert(!std::invocable
<rvalue_unqualified
, S
const volatile&&>);
368 using rvalue_const_unqualified
= void (S::*)() const&&;
369 static_assert(!std::invocable
<rvalue_const_unqualified
, S
&>);
370 static_assert(!std::invocable
<rvalue_const_unqualified
, S
const&>);
371 static_assert(!std::invocable
<rvalue_const_unqualified
, S
volatile&>);
372 static_assert(!std::invocable
<rvalue_const_unqualified
, S
const volatile&>);
373 static_assert(std::invocable
<rvalue_const_unqualified
, S
&&>);
374 static_assert(std::invocable
<rvalue_const_unqualified
, S
const&&>);
375 static_assert(!std::invocable
<rvalue_const_unqualified
, S
volatile&&>);
376 static_assert(!std::invocable
<rvalue_const_unqualified
, S
const volatile&&>);
378 using rvalue_volatile_unqualified
= void (S::*)() volatile&&;
379 static_assert(!std::invocable
<rvalue_volatile_unqualified
, S
&>);
380 static_assert(!std::invocable
<rvalue_volatile_unqualified
, S
const&>);
381 static_assert(!std::invocable
<rvalue_volatile_unqualified
, S
volatile&>);
382 static_assert(!std::invocable
<rvalue_volatile_unqualified
, S
const volatile&>);
383 static_assert(std::invocable
<rvalue_volatile_unqualified
, S
&&>);
384 static_assert(!std::invocable
<rvalue_volatile_unqualified
, S
const&&>);
385 static_assert(std::invocable
<rvalue_volatile_unqualified
, S
volatile&&>);
386 static_assert(!std::invocable
<rvalue_volatile_unqualified
, S
const volatile&&>);
388 using rvalue_cv_unqualified
= void (S::*)() const volatile&&;
389 static_assert(!std::invocable
<rvalue_cv_unqualified
, S
&>);
390 static_assert(!std::invocable
<rvalue_cv_unqualified
, S
const&>);
391 static_assert(!std::invocable
<rvalue_cv_unqualified
, S
volatile&>);
392 static_assert(!std::invocable
<rvalue_cv_unqualified
, S
const volatile&>);
393 static_assert(std::invocable
<rvalue_cv_unqualified
, S
&&>);
394 static_assert(std::invocable
<rvalue_cv_unqualified
, S
const&&>);
395 static_assert(std::invocable
<rvalue_cv_unqualified
, S
volatile&&>);
396 static_assert(std::invocable
<rvalue_cv_unqualified
, S
const volatile&&>);
397 } // namespace pointer_to_member_functions
399 // std::invocable-specific
400 static_assert(std::invocable
<std::uniform_int_distribution
<>, std::mt19937_64
&>);
402 // Check the concept with closure types
403 template<class F
, class... Args
>
404 constexpr bool is_invocable(F
, Args
&&...) {
405 return std::invocable
<F
, Args
...>;
408 static_assert(is_invocable([] {}));
409 static_assert(is_invocable([](int) {}, 0));
410 static_assert(is_invocable([](int) {}, 0L));
411 static_assert(!is_invocable([](int) {}, nullptr));
413 static_assert(is_invocable([](int&) {}, i
));