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