]>
Commit | Line | Data |
---|---|---|
b32b8144 FG |
1 | /* |
2 | Copyright Barrett Adair 2016-2017 | |
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 TL |
27 | |
28 | // when available, test parity with std implementation (c++2a breaks our expectations but we still match std impl) | |
29 | #if defined(__cpp_lib_is_invocable) || __cplusplus >= 201707L | |
30 | CT_ASSERT((std::is_invocable<Callable, Args...>() == boost::callable_traits::is_invocable<Callable, Args...>())); | |
20effc67 TL |
31 | # ifndef BOOST_CLBL_TRTS_DISABLE_VARIABLE_TEMPLATES |
32 | CT_ASSERT((std::is_invocable_v<Callable, Args...> == boost::callable_traits::is_invocable_v<Callable, Args...>)); | |
33 | # endif | |
92f5a8d4 | 34 | #else |
b32b8144 | 35 | CT_ASSERT((Expect == boost::callable_traits::is_invocable<Callable, Args...>())); |
20effc67 TL |
36 | # ifndef BOOST_CLBL_TRTS_DISABLE_VARIABLE_TEMPLATES |
37 | CT_ASSERT((Expect == 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 | ||
127 | // MSVC doesn't handle cv + ref qualifiers in expression sfinae correctly | |
128 | #ifndef BOOST_CLBL_TRTS_MSVC | |
129 | ||
130 | run_tests<void(foo::*)() const LREF | |
131 | ,invoke_case<false, foo> | |
132 | ,invoke_case<true, foo*> | |
133 | ,invoke_case<true, foo&> | |
134 | ,invoke_case<false, foo&&> | |
135 | ,invoke_case<true, std::reference_wrapper<foo>> | |
136 | ,invoke_case<false, foo const> | |
137 | ,invoke_case<true, foo const*> | |
138 | ,invoke_case<true, foo const&> | |
139 | ,invoke_case<false, foo const&&> | |
140 | ,invoke_case<true, std::reference_wrapper<foo const>> | |
141 | ,invoke_case<false, foo, int> | |
142 | ,invoke_case<false, foo*, int> | |
143 | ,invoke_case<false, foo&, int> | |
144 | ,invoke_case<false, foo&&, int> | |
145 | ,invoke_case<false, std::reference_wrapper<foo>, int> | |
146 | >(); | |
147 | ||
148 | run_tests<void(foo::*)() const RREF | |
149 | ,invoke_case<true, foo> | |
150 | ,invoke_case<false, foo*> | |
151 | ,invoke_case<false, foo&> | |
152 | ,invoke_case<true, foo&&> | |
153 | ,invoke_case<false, std::reference_wrapper<foo>> | |
154 | ,invoke_case<true, foo const> | |
155 | ,invoke_case<false, foo const*> | |
156 | ,invoke_case<false, foo const&> | |
157 | ,invoke_case<true, foo const&&> | |
158 | ,invoke_case<false, std::reference_wrapper<foo const>> | |
159 | ,invoke_case<false, foo, int> | |
160 | ,invoke_case<false, foo*, int> | |
161 | ,invoke_case<false, foo&, int> | |
162 | ,invoke_case<false, foo&&, int> | |
163 | ,invoke_case<false, std::reference_wrapper<foo>, int> | |
164 | >(); | |
165 | ||
166 | #endif // #ifndef BOOST_CLBL_TRTS_MSVC | |
167 | ||
168 | run_tests<int | |
169 | ,invoke_case<false, foo> | |
170 | ,invoke_case<false, foo*> | |
171 | ,invoke_case<false, foo&> | |
172 | ,invoke_case<false, foo&&> | |
173 | ,invoke_case<false, std::reference_wrapper<foo>> | |
174 | ,invoke_case<false, foo const> | |
175 | ,invoke_case<false, foo const*> | |
176 | ,invoke_case<false, foo const&> | |
177 | ,invoke_case<false, foo const&&> | |
178 | ,invoke_case<false, std::reference_wrapper<foo const>> | |
179 | ,invoke_case<false, foo, int> | |
180 | ,invoke_case<false, foo*, int> | |
181 | ,invoke_case<false, foo&, int> | |
182 | ,invoke_case<false, foo&&, int> | |
183 | ,invoke_case<false, std::reference_wrapper<foo>, int> | |
184 | >(); | |
185 | ||
186 | auto f = [](int){}; | |
187 | ||
188 | run_tests<decltype(f) | |
189 | ,invoke_case<true, int> | |
190 | ,invoke_case<true, char> | |
191 | ,invoke_case<false, void*> | |
192 | >(); | |
193 | ||
194 | run_tests<decltype(f)& | |
195 | ,invoke_case<true, int> | |
196 | ,invoke_case<true, char> | |
197 | ,invoke_case<false, void*> | |
198 | >(); | |
199 | ||
200 | run_tests<decltype(std::ref(f)) | |
201 | ,invoke_case<true, int> | |
202 | ,invoke_case<true, char> | |
203 | ,invoke_case<false, void*> | |
204 | >(); | |
205 | ||
206 | run_tests<decltype(std::ref(f))& | |
207 | ,invoke_case<true, int> | |
208 | ,invoke_case<true, char> | |
209 | ,invoke_case<false, void*> | |
210 | >(); | |
211 | ||
212 | run_tests<decltype(std::ref(f))&& | |
213 | ,invoke_case<true, int> | |
214 | ,invoke_case<true, char> | |
215 | ,invoke_case<false, void*> | |
216 | >(); | |
217 | ||
218 | run_tests<decltype(std::ref(f)) const & | |
219 | ,invoke_case<true, int> | |
220 | ,invoke_case<true, char> | |
221 | ,invoke_case<false, void*> | |
222 | >(); | |
223 | ||
224 | run_tests<decltype(std::ref(f)) const && | |
225 | ,invoke_case<true, int> | |
226 | ,invoke_case<true, char> | |
227 | ,invoke_case<false, void*> | |
228 | >(); | |
229 | ||
230 | run_tests<decltype(f)&& | |
231 | ,invoke_case<true, int> | |
232 | ,invoke_case<true, char> | |
233 | ,invoke_case<false, void*> | |
234 | >(); | |
235 | ||
236 | run_tests<decltype(f) const & | |
237 | ,invoke_case<true, int> | |
238 | ,invoke_case<true, char> | |
239 | ,invoke_case<false, void*> | |
240 | >(); | |
241 | ||
242 | run_tests<decltype(f) const && | |
243 | ,invoke_case<true, int> | |
244 | ,invoke_case<true, char> | |
245 | ,invoke_case<false, void*> | |
246 | >(); | |
247 | ||
92f5a8d4 TL |
248 | auto g = [](){}; |
249 | ||
250 | run_tests<decltype(g) | |
251 | ,invoke_case<true> | |
252 | ,invoke_case<false, char> | |
253 | ,invoke_case<false, void*> | |
254 | >(); | |
255 | ||
256 | run_tests<decltype(g)& | |
257 | ,invoke_case<true> | |
258 | ,invoke_case<false, char> | |
259 | ,invoke_case<false, void*> | |
260 | >(); | |
261 | ||
262 | run_tests<decltype(std::ref(g)) | |
263 | ,invoke_case<true> | |
264 | ,invoke_case<false, char> | |
265 | ,invoke_case<false, void*> | |
266 | >(); | |
267 | ||
268 | run_tests<decltype(std::ref(g))& | |
269 | ,invoke_case<true> | |
270 | ,invoke_case<false, char> | |
271 | ,invoke_case<false, void*> | |
272 | >(); | |
273 | ||
274 | run_tests<decltype(std::ref(g))&& | |
275 | ,invoke_case<true> | |
276 | ,invoke_case<false, char> | |
277 | ,invoke_case<false, void*> | |
278 | >(); | |
279 | ||
280 | run_tests<decltype(std::ref(g)) const & | |
281 | ,invoke_case<true> | |
282 | ,invoke_case<false, char> | |
283 | ,invoke_case<false, void*> | |
284 | >(); | |
285 | ||
286 | run_tests<decltype(std::ref(g)) const && | |
287 | ,invoke_case<true> | |
288 | ,invoke_case<false, char> | |
289 | ,invoke_case<false, void*> | |
290 | >(); | |
291 | ||
292 | run_tests<decltype(g)&& | |
293 | ,invoke_case<true> | |
294 | ,invoke_case<false, char> | |
295 | ,invoke_case<false, void*> | |
296 | >(); | |
297 | ||
298 | run_tests<decltype(g) const & | |
299 | ,invoke_case<true> | |
300 | ,invoke_case<false, char> | |
301 | ,invoke_case<false, void*> | |
302 | >(); | |
303 | ||
304 | run_tests<decltype(g) const && | |
305 | ,invoke_case<true> | |
306 | ,invoke_case<false, char> | |
307 | ,invoke_case<false, void*> | |
308 | >(); | |
309 | ||
310 | // libc++ requires constructible types be passed to std::is_invocable | |
311 | #ifndef _LIBCPP_VERSION | |
312 | ||
b32b8144 FG |
313 | run_tests<void(int) |
314 | ,invoke_case<true, int> | |
315 | ,invoke_case<true, char> | |
316 | ,invoke_case<false, void*> | |
317 | >(); | |
318 | ||
319 | run_tests<void(int) const | |
320 | ,invoke_case<false, int> | |
321 | ,invoke_case<false, char> | |
322 | ,invoke_case<false, void*> | |
323 | >(); | |
324 | ||
325 | run_tests<void() | |
326 | ,invoke_case<false, int> | |
327 | ,invoke_case<false, char> | |
328 | ,invoke_case<false, void*> | |
329 | >(); | |
330 | ||
331 | run_tests<void | |
332 | ,invoke_case<false, foo> | |
333 | ,invoke_case<false, foo*> | |
334 | ,invoke_case<false, foo&> | |
335 | ,invoke_case<false, foo&&> | |
336 | ,invoke_case<false, std::reference_wrapper<foo>> | |
337 | ,invoke_case<false, foo const> | |
338 | ,invoke_case<false, foo const*> | |
339 | ,invoke_case<false, foo const&> | |
340 | ,invoke_case<false, foo const&&> | |
341 | ,invoke_case<false, std::reference_wrapper<foo const>> | |
342 | ,invoke_case<false, foo, int> | |
343 | ,invoke_case<false, foo*, int> | |
344 | ,invoke_case<false, foo&, int> | |
345 | ,invoke_case<false, foo&&, int> | |
346 | ,invoke_case<false, std::reference_wrapper<foo>, int> | |
347 | >(); | |
92f5a8d4 | 348 | #endif |
b32b8144 FG |
349 | |
350 | run_tests<int | |
351 | ,invoke_case<false, foo> | |
352 | ,invoke_case<false, foo*> | |
353 | ,invoke_case<false, foo&> | |
354 | ,invoke_case<false, foo&&> | |
355 | ,invoke_case<false, std::reference_wrapper<foo>> | |
356 | ,invoke_case<false, foo const> | |
357 | ,invoke_case<false, foo const*> | |
358 | ,invoke_case<false, foo const&> | |
359 | ,invoke_case<false, foo const&&> | |
360 | ,invoke_case<false, std::reference_wrapper<foo const>> | |
361 | ,invoke_case<false, foo, int> | |
362 | ,invoke_case<false, foo*, int> | |
363 | ,invoke_case<false, foo&, int> | |
364 | ,invoke_case<false, foo&&, int> | |
365 | ,invoke_case<false, std::reference_wrapper<foo>, int> | |
366 | >(); | |
367 | ||
368 | run_tests<void* | |
369 | ,invoke_case<false, foo> | |
370 | ,invoke_case<false, foo*> | |
371 | ,invoke_case<false, foo&> | |
372 | ,invoke_case<false, foo&&> | |
373 | ,invoke_case<false, std::reference_wrapper<foo>> | |
374 | ,invoke_case<false, foo const> | |
375 | ,invoke_case<false, foo const*> | |
376 | ,invoke_case<false, foo const&> | |
377 | ,invoke_case<false, foo const&&> | |
378 | ,invoke_case<false, std::reference_wrapper<foo const>> | |
379 | ,invoke_case<false, foo, int> | |
380 | ,invoke_case<false, foo*, int> | |
381 | ,invoke_case<false, foo&, int> | |
382 | ,invoke_case<false, foo&&, int> | |
383 | ,invoke_case<false, std::reference_wrapper<foo>, int> | |
384 | >(); | |
385 | } | |
386 | ||
387 | #endif //#ifdef BOOST_CLBL_TRTS_GCC_OLDER_THAN_4_9_2 |