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 | |
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...> == |
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 | |
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[]>()); |
40 | |
41 | struct S; |
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&>); |
48 | |
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&>); |
57 | |
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&&>); |
63 | |
64 | namespace function_objects { |
65 | struct function_object { |
66 | void operator()(); |
67 | }; |
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&>); |
76 | |
77 | struct const_function_object { |
78 | void operator()(int) const; |
79 | }; |
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>); |
83 | static_assert( |
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>); |
88 | static_assert( |
89 | !std::regular_invocable<const_function_object const volatile&, int>); |
90 | |
91 | struct volatile_function_object { |
92 | void operator()(int, int) volatile; |
93 | }; |
94 | static_assert(std::regular_invocable<volatile_function_object, int, int>); |
95 | static_assert( |
96 | !std::regular_invocable<volatile_function_object const, int, int>); |
97 | static_assert( |
98 | std::regular_invocable<volatile_function_object volatile, int, int>); |
99 | static_assert( |
100 | !std::regular_invocable<volatile_function_object const volatile, int, int>); |
101 | static_assert(std::regular_invocable<volatile_function_object&, int, int>); |
102 | static_assert( |
103 | !std::regular_invocable<volatile_function_object const&, int, int>); |
104 | static_assert( |
105 | std::regular_invocable<volatile_function_object volatile&, int, int>); |
106 | static_assert(!std::regular_invocable<volatile_function_object const volatile&, |
107 | int, int>); |
108 | |
109 | struct cv_function_object { |
110 | void operator()(int[]) const volatile; |
111 | }; |
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*>); |
120 | |
121 | struct lvalue_function_object { |
122 | void operator()() &; |
123 | }; |
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&>); |
132 | |
133 | struct lvalue_const_function_object { |
134 | void operator()(int) const&; |
135 | }; |
136 | static_assert(std::regular_invocable<lvalue_const_function_object, int>); |
137 | static_assert(std::regular_invocable<lvalue_const_function_object const, int>); |
138 | static_assert( |
139 | !std::regular_invocable<lvalue_const_function_object volatile, int>); |
140 | static_assert( |
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>); |
144 | static_assert( |
145 | !std::regular_invocable<lvalue_const_function_object volatile&, int>); |
146 | static_assert( |
147 | !std::regular_invocable<lvalue_const_function_object const volatile&, int>); |
148 | |
149 | struct lvalue_volatile_function_object { |
150 | void operator()(int, int) volatile&; |
151 | }; |
152 | static_assert( |
153 | !std::regular_invocable<lvalue_volatile_function_object, int, int>); |
154 | static_assert( |
155 | !std::regular_invocable<lvalue_volatile_function_object const, int, int>); |
156 | static_assert(!std::regular_invocable<lvalue_volatile_function_object volatile, |
157 | int, int>); |
158 | static_assert(!std::regular_invocable< |
159 | lvalue_volatile_function_object const volatile, int, int>); |
160 | static_assert( |
161 | std::regular_invocable<lvalue_volatile_function_object&, int, int>); |
162 | static_assert( |
163 | !std::regular_invocable<lvalue_volatile_function_object const&, int, int>); |
164 | static_assert(std::regular_invocable<lvalue_volatile_function_object volatile&, |
165 | int, int>); |
166 | static_assert(!std::regular_invocable< |
167 | lvalue_volatile_function_object const volatile&, int, int>); |
168 | |
169 | struct lvalue_cv_function_object { |
170 | void operator()(int[]) const volatile&; |
171 | }; |
172 | static_assert(!std::regular_invocable<lvalue_cv_function_object, int*>); |
173 | static_assert(!std::regular_invocable<lvalue_cv_function_object const, int*>); |
174 | static_assert( |
175 | !std::regular_invocable<lvalue_cv_function_object volatile, int*>); |
176 | static_assert( |
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*>); |
180 | static_assert( |
181 | std::regular_invocable<lvalue_cv_function_object volatile&, int*>); |
182 | static_assert( |
183 | std::regular_invocable<lvalue_cv_function_object const volatile&, int*>); |
184 | // |
185 | struct rvalue_function_object { |
186 | void operator()() &&; |
187 | }; |
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&>); |
196 | |
197 | struct rvalue_const_function_object { |
198 | void operator()(int) const&&; |
199 | }; |
200 | static_assert(std::regular_invocable<rvalue_const_function_object, int>); |
201 | static_assert(std::regular_invocable<rvalue_const_function_object const, int>); |
202 | static_assert( |
203 | !std::regular_invocable<rvalue_const_function_object volatile, int>); |
204 | static_assert( |
205 | !std::regular_invocable<rvalue_const_function_object const volatile, int>); |
206 | static_assert(!std::regular_invocable<rvalue_const_function_object&, int>); |
207 | static_assert( |
208 | !std::regular_invocable<rvalue_const_function_object const&, int>); |
209 | static_assert( |
210 | !std::regular_invocable<rvalue_const_function_object volatile&, int>); |
211 | static_assert( |
212 | !std::regular_invocable<rvalue_const_function_object const volatile&, int>); |
213 | |
214 | struct rvalue_volatile_function_object { |
215 | void operator()(int, int) volatile&&; |
216 | }; |
217 | static_assert( |
218 | std::regular_invocable<rvalue_volatile_function_object, int, int>); |
219 | static_assert( |
220 | !std::regular_invocable<rvalue_volatile_function_object const, int, int>); |
221 | static_assert( |
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>); |
225 | static_assert( |
226 | !std::regular_invocable<rvalue_volatile_function_object&, int, int>); |
227 | static_assert( |
228 | !std::regular_invocable<rvalue_volatile_function_object const&, int, int>); |
229 | static_assert(!std::regular_invocable<rvalue_volatile_function_object volatile&, |
230 | int, int>); |
231 | static_assert(!std::regular_invocable< |
232 | rvalue_volatile_function_object const volatile&, int, int>); |
233 | |
234 | struct rvalue_cv_function_object { |
235 | void operator()(int[]) const volatile&&; |
236 | }; |
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*>); |
240 | static_assert( |
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*>); |
244 | static_assert( |
245 | !std::regular_invocable<rvalue_cv_function_object volatile&, int*>); |
246 | static_assert( |
247 | !std::regular_invocable<rvalue_cv_function_object const volatile&, int*>); |
248 | |
249 | struct 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 | }; |
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 |
263 | |
264 | namespace 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 | |
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&&>); |
291 | |
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&&>); |
303 | |
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&&>); |
314 | |
315 | static_assert( |
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&&>); |
326 | |
327 | static_assert(check_member_is_invocable<int (S::*)(int, S&) const volatile, S, |
328 | int, 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&&>); |
338 | |
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&&>); |
349 | |
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&>); |
355 | static_assert( |
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&&>); |
360 | static_assert( |
361 | !std::regular_invocable<lvalue_const_qualified, S const volatile&&>); |
362 | |
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&>); |
368 | static_assert( |
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&&>); |
373 | static_assert( |
374 | !std::regular_invocable<lvalue_volatile_qualified, S const volatile&&>); |
375 | |
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&&>); |
386 | |
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&&>); |
396 | |
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&>); |
401 | static_assert( |
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&&>); |
406 | static_assert( |
407 | !std::regular_invocable<rvalue_const_unqualified, S const volatile&&>); |
408 | |
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&>); |
412 | static_assert( |
413 | !std::regular_invocable<rvalue_volatile_unqualified, S volatile&>); |
414 | static_assert( |
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&&>); |
418 | static_assert( |
419 | std::regular_invocable<rvalue_volatile_unqualified, S volatile&&>); |
420 | static_assert( |
421 | !std::regular_invocable<rvalue_volatile_unqualified, S const volatile&&>); |
422 | |
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&>); |
427 | static_assert( |
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&&>); |
432 | static_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) |
437 | template<class F, class... Args> |
438 | constexpr bool is_regular_invocable(F, Args&&...) { |
439 | return false; |
440 | } |
441 | |
442 | template<class F, class... Args> |
443 | requires std::invocable<F, Args...> |
444 | constexpr bool is_regular_invocable(F, Args&&...) { |
445 | return false; |
446 | } |
447 | |
448 | template<class F, class... Args> |
449 | requires std::regular_invocable<F, Args...> && true |
450 | constexpr bool is_regular_invocable(F, Args&&...) { |
451 | return true; |
452 | } |
453 | |
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)); |
458 | |
459 | int i = 0; |
460 | static_assert(is_regular_invocable([](int&) {}, i)); |
461 | |