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
14 //gcc < 4.9 doesn't like the invoke_case pattern used here
main()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>
operator ()invoke_case26 void operator()(tag<Callable>) const {
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...>()));
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
34 #else
35 CT_ASSERT((Expect == boost::callable_traits::is_invocable<Callable, Args...>()));
36 # ifndef BOOST_CLBL_TRTS_DISABLE_VARIABLE_TEMPLATES
37 CT_ASSERT((Expect == boost::callable_traits::is_invocable_v<Callable, Args...>));
38 # endif
39 #endif
40
41 }
42 };
43
44 template<typename Callable, typename... InvokeCases>
run_tests()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
main()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
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
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 >();
348 #endif
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
388