• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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