]>
Commit | Line | Data |
---|---|---|
b32b8144 | 1 | /* |
1e59de90 | 2 | Copyright Barrett Adair 2016-2021 |
b32b8144 FG |
3 | Distributed under the Boost Software License, Version 1.0. |
4 | (See accompanying file LICENSE.md or copy at http ://boost.org/LICENSE_1_0.txt) | |
5 | */ | |
6 | ||
7 | #include <type_traits> | |
8 | #include <functional> | |
9 | #include <utility> | |
10 | #include <boost/callable_traits/is_invocable.hpp> | |
11 | #include "test.hpp" | |
12 | ||
13 | #ifdef BOOST_CLBL_TRTS_GCC_OLDER_THAN_4_9_2 | |
92f5a8d4 | 14 | //gcc < 4.9 doesn't like the invoke_case pattern used here |
b32b8144 FG |
15 | int main(){} |
16 | #else | |
17 | ||
18 | template<typename T> | |
19 | struct tag { | |
20 | using type = T; | |
21 | }; | |
22 | ||
23 | template<bool Expect, typename... Args> | |
24 | struct invoke_case { | |
25 | template<typename Callable> | |
26 | void operator()(tag<Callable>) const { | |
92f5a8d4 | 27 | |
1e59de90 TL |
28 | CT_ASSERT((Expect == boost::callable_traits::is_invocable<Callable, Args...>())); |
29 | #ifndef BOOST_CLBL_TRTS_DISABLE_VARIABLE_TEMPLATES | |
30 | CT_ASSERT((Expect == boost::callable_traits::is_invocable_v<Callable, Args...>)); | |
31 | #endif | |
32 | ||
33 | // when available, test parity with std implementation | |
34 | #if defined(__cpp_lib_is_invocable) | |
92f5a8d4 | 35 | CT_ASSERT((std::is_invocable<Callable, Args...>() == boost::callable_traits::is_invocable<Callable, Args...>())); |
20effc67 TL |
36 | # ifndef BOOST_CLBL_TRTS_DISABLE_VARIABLE_TEMPLATES |
37 | CT_ASSERT((std::is_invocable_v<Callable, Args...> == boost::callable_traits::is_invocable_v<Callable, Args...>)); | |
38 | # endif | |
92f5a8d4 TL |
39 | #endif |
40 | ||
b32b8144 FG |
41 | } |
42 | }; | |
43 | ||
44 | template<typename Callable, typename... InvokeCases> | |
45 | void run_tests() { | |
46 | using ignored = int[]; | |
47 | ignored x {(InvokeCases{}(tag<Callable>{}),0)..., 0}; | |
48 | (void)x; | |
49 | } | |
50 | ||
51 | struct foo {}; | |
52 | ||
53 | int main() { | |
54 | ||
55 | run_tests<void(foo::*)() | |
56 | ,invoke_case<true, foo> | |
57 | ,invoke_case<true, foo*> | |
58 | ,invoke_case<true, foo&> | |
59 | ,invoke_case<true, foo&&> | |
60 | ,invoke_case<true, std::reference_wrapper<foo>> | |
61 | ,invoke_case<false, foo const> | |
62 | ,invoke_case<false, foo const*> | |
63 | ,invoke_case<false, foo const&> | |
64 | ,invoke_case<false, foo const&&> | |
65 | ,invoke_case<false, std::reference_wrapper<foo const>> | |
66 | ,invoke_case<false, foo, int> | |
67 | ,invoke_case<false, foo*, int> | |
68 | ,invoke_case<false, foo&, int> | |
69 | ,invoke_case<false, foo&&, int> | |
70 | ,invoke_case<false, std::reference_wrapper<foo>, int> | |
71 | >(); | |
72 | ||
73 | run_tests<void(foo::*)() LREF | |
74 | ,invoke_case<false, foo> | |
75 | ,invoke_case<true, foo*> | |
76 | ,invoke_case<true, foo&> | |
77 | ,invoke_case<false, foo&&> | |
78 | ,invoke_case<true, std::reference_wrapper<foo>> | |
79 | ,invoke_case<false, foo const> | |
80 | ,invoke_case<false, foo const*> | |
81 | ,invoke_case<false, foo const&> | |
82 | ,invoke_case<false, foo const&&> | |
83 | ,invoke_case<false, std::reference_wrapper<foo const>> | |
84 | ,invoke_case<false, foo, int> | |
85 | ,invoke_case<false, foo*, int> | |
86 | ,invoke_case<false, foo&, int> | |
87 | ,invoke_case<false, foo&&, int> | |
88 | ,invoke_case<false, std::reference_wrapper<foo>, int> | |
89 | >(); | |
90 | ||
91 | run_tests<void(foo::*)() RREF | |
92 | ,invoke_case<true, foo> | |
93 | ,invoke_case<false, foo*> | |
94 | ,invoke_case<false, foo&> | |
95 | ,invoke_case<true, foo&&> | |
96 | ,invoke_case<false, std::reference_wrapper<foo>> | |
97 | ,invoke_case<false, foo const> | |
98 | ,invoke_case<false, foo const*> | |
99 | ,invoke_case<false, foo const&> | |
100 | ,invoke_case<false, foo const&&> | |
101 | ,invoke_case<false, std::reference_wrapper<foo const>> | |
102 | ,invoke_case<false, foo, int> | |
103 | ,invoke_case<false, foo*, int> | |
104 | ,invoke_case<false, foo&, int> | |
105 | ,invoke_case<false, foo&&, int> | |
106 | ,invoke_case<false, std::reference_wrapper<foo>, int> | |
107 | >(); | |
108 | ||
109 | run_tests<void(foo::*)() const | |
110 | ,invoke_case<true, foo> | |
111 | ,invoke_case<true, foo*> | |
112 | ,invoke_case<true, foo&> | |
113 | ,invoke_case<true, foo&&> | |
114 | ,invoke_case<true, std::reference_wrapper<foo>> | |
115 | ,invoke_case<true, foo const> | |
116 | ,invoke_case<true, foo const*> | |
117 | ,invoke_case<true, foo const&> | |
118 | ,invoke_case<true, foo const&&> | |
119 | ,invoke_case<true, std::reference_wrapper<foo const>> | |
120 | ,invoke_case<false, foo, int> | |
121 | ,invoke_case<false, foo*, int> | |
122 | ,invoke_case<false, foo&, int> | |
123 | ,invoke_case<false, foo&&, int> | |
124 | ,invoke_case<false, std::reference_wrapper<foo>, int> | |
125 | >(); | |
126 | ||
1e59de90 TL |
127 | // old MSVC doesn't handle cv + ref qualifiers in expression sfinae correctly |
128 | #ifndef BOOST_CLBL_TRTS_OLD_MSVC | |
129 | ||
130 | #if __cplusplus <= 201703L | |
131 | #define QUIRKY_CASE true | |
132 | #else | |
133 | #define QUIRKY_CASE false | |
134 | #endif | |
b32b8144 FG |
135 | |
136 | run_tests<void(foo::*)() const LREF | |
1e59de90 TL |
137 | |
138 | #ifndef BOOST_CLBL_TRTS_MSVC | |
139 | ,invoke_case<!QUIRKY_CASE, foo> | |
140 | ,invoke_case<!QUIRKY_CASE, foo&&> | |
141 | ,invoke_case<!QUIRKY_CASE, foo const> | |
142 | ,invoke_case<!QUIRKY_CASE, foo const&&> | |
143 | #endif | |
b32b8144 FG |
144 | ,invoke_case<true, foo*> |
145 | ,invoke_case<true, foo&> | |
b32b8144 | 146 | ,invoke_case<true, std::reference_wrapper<foo>> |
b32b8144 FG |
147 | ,invoke_case<true, foo const*> |
148 | ,invoke_case<true, foo const&> | |
b32b8144 FG |
149 | ,invoke_case<true, std::reference_wrapper<foo const>> |
150 | ,invoke_case<false, foo, int> | |
151 | ,invoke_case<false, foo*, int> | |
152 | ,invoke_case<false, foo&, int> | |
153 | ,invoke_case<false, foo&&, int> | |
154 | ,invoke_case<false, std::reference_wrapper<foo>, int> | |
155 | >(); | |
156 | ||
157 | run_tests<void(foo::*)() const RREF | |
158 | ,invoke_case<true, foo> | |
159 | ,invoke_case<false, foo*> | |
160 | ,invoke_case<false, foo&> | |
161 | ,invoke_case<true, foo&&> | |
162 | ,invoke_case<false, std::reference_wrapper<foo>> | |
163 | ,invoke_case<true, foo const> | |
164 | ,invoke_case<false, foo const*> | |
165 | ,invoke_case<false, foo const&> | |
166 | ,invoke_case<true, foo const&&> | |
167 | ,invoke_case<false, std::reference_wrapper<foo const>> | |
168 | ,invoke_case<false, foo, int> | |
169 | ,invoke_case<false, foo*, int> | |
170 | ,invoke_case<false, foo&, int> | |
171 | ,invoke_case<false, foo&&, int> | |
172 | ,invoke_case<false, std::reference_wrapper<foo>, int> | |
173 | >(); | |
174 | ||
1e59de90 | 175 | #endif // #ifndef BOOST_CLBL_TRTS_OLD_MSVC |
b32b8144 FG |
176 | |
177 | run_tests<int | |
178 | ,invoke_case<false, foo> | |
179 | ,invoke_case<false, foo*> | |
180 | ,invoke_case<false, foo&> | |
181 | ,invoke_case<false, foo&&> | |
182 | ,invoke_case<false, std::reference_wrapper<foo>> | |
183 | ,invoke_case<false, foo const> | |
184 | ,invoke_case<false, foo const*> | |
185 | ,invoke_case<false, foo const&> | |
186 | ,invoke_case<false, foo const&&> | |
187 | ,invoke_case<false, std::reference_wrapper<foo const>> | |
188 | ,invoke_case<false, foo, int> | |
189 | ,invoke_case<false, foo*, int> | |
190 | ,invoke_case<false, foo&, int> | |
191 | ,invoke_case<false, foo&&, int> | |
192 | ,invoke_case<false, std::reference_wrapper<foo>, int> | |
193 | >(); | |
194 | ||
195 | auto f = [](int){}; | |
196 | ||
197 | run_tests<decltype(f) | |
198 | ,invoke_case<true, int> | |
199 | ,invoke_case<true, char> | |
200 | ,invoke_case<false, void*> | |
201 | >(); | |
202 | ||
203 | run_tests<decltype(f)& | |
204 | ,invoke_case<true, int> | |
205 | ,invoke_case<true, char> | |
206 | ,invoke_case<false, void*> | |
207 | >(); | |
208 | ||
209 | run_tests<decltype(std::ref(f)) | |
210 | ,invoke_case<true, int> | |
211 | ,invoke_case<true, char> | |
212 | ,invoke_case<false, void*> | |
213 | >(); | |
214 | ||
215 | run_tests<decltype(std::ref(f))& | |
216 | ,invoke_case<true, int> | |
217 | ,invoke_case<true, char> | |
218 | ,invoke_case<false, void*> | |
219 | >(); | |
220 | ||
221 | run_tests<decltype(std::ref(f))&& | |
222 | ,invoke_case<true, int> | |
223 | ,invoke_case<true, char> | |
224 | ,invoke_case<false, void*> | |
225 | >(); | |
226 | ||
227 | run_tests<decltype(std::ref(f)) const & | |
228 | ,invoke_case<true, int> | |
229 | ,invoke_case<true, char> | |
230 | ,invoke_case<false, void*> | |
231 | >(); | |
232 | ||
233 | run_tests<decltype(std::ref(f)) const && | |
234 | ,invoke_case<true, int> | |
235 | ,invoke_case<true, char> | |
236 | ,invoke_case<false, void*> | |
237 | >(); | |
238 | ||
239 | run_tests<decltype(f)&& | |
240 | ,invoke_case<true, int> | |
241 | ,invoke_case<true, char> | |
242 | ,invoke_case<false, void*> | |
243 | >(); | |
244 | ||
245 | run_tests<decltype(f) const & | |
246 | ,invoke_case<true, int> | |
247 | ,invoke_case<true, char> | |
248 | ,invoke_case<false, void*> | |
249 | >(); | |
250 | ||
251 | run_tests<decltype(f) const && | |
252 | ,invoke_case<true, int> | |
253 | ,invoke_case<true, char> | |
254 | ,invoke_case<false, void*> | |
255 | >(); | |
256 | ||
92f5a8d4 TL |
257 | auto g = [](){}; |
258 | ||
259 | run_tests<decltype(g) | |
260 | ,invoke_case<true> | |
261 | ,invoke_case<false, char> | |
262 | ,invoke_case<false, void*> | |
263 | >(); | |
264 | ||
265 | run_tests<decltype(g)& | |
266 | ,invoke_case<true> | |
267 | ,invoke_case<false, char> | |
268 | ,invoke_case<false, void*> | |
269 | >(); | |
270 | ||
271 | run_tests<decltype(std::ref(g)) | |
272 | ,invoke_case<true> | |
273 | ,invoke_case<false, char> | |
274 | ,invoke_case<false, void*> | |
275 | >(); | |
276 | ||
277 | run_tests<decltype(std::ref(g))& | |
278 | ,invoke_case<true> | |
279 | ,invoke_case<false, char> | |
280 | ,invoke_case<false, void*> | |
281 | >(); | |
282 | ||
283 | run_tests<decltype(std::ref(g))&& | |
284 | ,invoke_case<true> | |
285 | ,invoke_case<false, char> | |
286 | ,invoke_case<false, void*> | |
287 | >(); | |
288 | ||
289 | run_tests<decltype(std::ref(g)) const & | |
290 | ,invoke_case<true> | |
291 | ,invoke_case<false, char> | |
292 | ,invoke_case<false, void*> | |
293 | >(); | |
294 | ||
295 | run_tests<decltype(std::ref(g)) const && | |
296 | ,invoke_case<true> | |
297 | ,invoke_case<false, char> | |
298 | ,invoke_case<false, void*> | |
299 | >(); | |
300 | ||
301 | run_tests<decltype(g)&& | |
302 | ,invoke_case<true> | |
303 | ,invoke_case<false, char> | |
304 | ,invoke_case<false, void*> | |
305 | >(); | |
306 | ||
307 | run_tests<decltype(g) const & | |
308 | ,invoke_case<true> | |
309 | ,invoke_case<false, char> | |
310 | ,invoke_case<false, void*> | |
311 | >(); | |
312 | ||
313 | run_tests<decltype(g) const && | |
314 | ,invoke_case<true> | |
315 | ,invoke_case<false, char> | |
316 | ,invoke_case<false, void*> | |
317 | >(); | |
318 | ||
319 | // libc++ requires constructible types be passed to std::is_invocable | |
320 | #ifndef _LIBCPP_VERSION | |
321 | ||
b32b8144 FG |
322 | run_tests<void(int) |
323 | ,invoke_case<true, int> | |
324 | ,invoke_case<true, char> | |
325 | ,invoke_case<false, void*> | |
326 | >(); | |
327 | ||
328 | run_tests<void(int) const | |
329 | ,invoke_case<false, int> | |
330 | ,invoke_case<false, char> | |
331 | ,invoke_case<false, void*> | |
332 | >(); | |
333 | ||
334 | run_tests<void() | |
335 | ,invoke_case<false, int> | |
336 | ,invoke_case<false, char> | |
337 | ,invoke_case<false, void*> | |
338 | >(); | |
339 | ||
340 | run_tests<void | |
341 | ,invoke_case<false, foo> | |
342 | ,invoke_case<false, foo*> | |
343 | ,invoke_case<false, foo&> | |
344 | ,invoke_case<false, foo&&> | |
345 | ,invoke_case<false, std::reference_wrapper<foo>> | |
346 | ,invoke_case<false, foo const> | |
347 | ,invoke_case<false, foo const*> | |
348 | ,invoke_case<false, foo const&> | |
349 | ,invoke_case<false, foo const&&> | |
350 | ,invoke_case<false, std::reference_wrapper<foo const>> | |
351 | ,invoke_case<false, foo, int> | |
352 | ,invoke_case<false, foo*, int> | |
353 | ,invoke_case<false, foo&, int> | |
354 | ,invoke_case<false, foo&&, int> | |
355 | ,invoke_case<false, std::reference_wrapper<foo>, int> | |
356 | >(); | |
92f5a8d4 | 357 | #endif |
b32b8144 FG |
358 | |
359 | run_tests<int | |
360 | ,invoke_case<false, foo> | |
361 | ,invoke_case<false, foo*> | |
362 | ,invoke_case<false, foo&> | |
363 | ,invoke_case<false, foo&&> | |
364 | ,invoke_case<false, std::reference_wrapper<foo>> | |
365 | ,invoke_case<false, foo const> | |
366 | ,invoke_case<false, foo const*> | |
367 | ,invoke_case<false, foo const&> | |
368 | ,invoke_case<false, foo const&&> | |
369 | ,invoke_case<false, std::reference_wrapper<foo const>> | |
370 | ,invoke_case<false, foo, int> | |
371 | ,invoke_case<false, foo*, int> | |
372 | ,invoke_case<false, foo&, int> | |
373 | ,invoke_case<false, foo&&, int> | |
374 | ,invoke_case<false, std::reference_wrapper<foo>, int> | |
375 | >(); | |
376 | ||
377 | run_tests<void* | |
378 | ,invoke_case<false, foo> | |
379 | ,invoke_case<false, foo*> | |
380 | ,invoke_case<false, foo&> | |
381 | ,invoke_case<false, foo&&> | |
382 | ,invoke_case<false, std::reference_wrapper<foo>> | |
383 | ,invoke_case<false, foo const> | |
384 | ,invoke_case<false, foo const*> | |
385 | ,invoke_case<false, foo const&> | |
386 | ,invoke_case<false, foo const&&> | |
387 | ,invoke_case<false, std::reference_wrapper<foo const>> | |
388 | ,invoke_case<false, foo, int> | |
389 | ,invoke_case<false, foo*, int> | |
390 | ,invoke_case<false, foo&, int> | |
391 | ,invoke_case<false, foo&&, int> | |
392 | ,invoke_case<false, std::reference_wrapper<foo>, int> | |
393 | >(); | |
394 | } | |
395 | ||
396 | #endif //#ifdef BOOST_CLBL_TRTS_GCC_OLDER_THAN_4_9_2 |