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

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