• 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 Ret, 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_r<Ret, Callable, Args...>() == boost::callable_traits::is_invocable_r<Ret, Callable, Args...>()));
31 #  ifndef BOOST_CLBL_TRTS_DISABLE_VARIABLE_TEMPLATES
32         CT_ASSERT((std::is_invocable_r_v<Ret, Callable, Args...> == boost::callable_traits::is_invocable_r_v<Ret, Callable, Args...>));
33 #  endif
34 #else
35         CT_ASSERT((Expect == boost::callable_traits::is_invocable_r<Ret, Callable, Args...>()));
36 #  ifndef BOOST_CLBL_TRTS_DISABLE_VARIABLE_TEMPLATES
37         CT_ASSERT((Expect == boost::callable_traits::is_invocable_r_v<Ret, 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, void, foo>
57         ,invoke_case<true, void, foo*>
58         ,invoke_case<true, void, foo&>
59         ,invoke_case<true, void, foo&&>
60         ,invoke_case<true, void, std::reference_wrapper<foo>>
61         ,invoke_case<false, int, foo>
62         ,invoke_case<false, int, foo*>
63         ,invoke_case<false, int, foo&>
64         ,invoke_case<false, int, foo&&>
65         ,invoke_case<false, int, std::reference_wrapper<foo>>
66         ,invoke_case<false, void, foo const>
67         ,invoke_case<false, void, foo const*>
68         ,invoke_case<false, void, foo const&>
69         ,invoke_case<false, void, foo const&&>
70         ,invoke_case<false, void, std::reference_wrapper<foo const>>
71         ,invoke_case<false, void, foo, int>
72         ,invoke_case<false, void, foo*, int>
73         ,invoke_case<false, void, foo&, int>
74         ,invoke_case<false, void, foo&&, int>
75         ,invoke_case<false, void, std::reference_wrapper<foo>, int>
76         ,invoke_case<false, int, foo const>
77         ,invoke_case<false, int, foo const*>
78         ,invoke_case<false, int, foo const&>
79         ,invoke_case<false, int, foo const&&>
80         ,invoke_case<false, int, std::reference_wrapper<foo const>>
81         ,invoke_case<false, int, foo, int>
82         ,invoke_case<false, int, foo*, int>
83         ,invoke_case<false, int, foo&, int>
84         ,invoke_case<false, int, foo&&, int>
85         ,invoke_case<false, int, std::reference_wrapper<foo>, int>
86     >();
87 
88     run_tests<char(foo::*)()
89         ,invoke_case<true, void, foo>
90         ,invoke_case<true, void, foo*>
91         ,invoke_case<true, void, foo&>
92         ,invoke_case<true, void, foo&&>
93         ,invoke_case<true, void, std::reference_wrapper<foo>>
94         ,invoke_case<true, int, foo>
95         ,invoke_case<true, int, foo*>
96         ,invoke_case<true, int, foo&>
97         ,invoke_case<true, int, foo&&>
98         ,invoke_case<true, int, std::reference_wrapper<foo>>
99     >();
100 
101     run_tests<void(foo::*)() LREF
102         ,invoke_case<false, void, foo>
103         ,invoke_case<true, void, foo*>
104         ,invoke_case<true, void, foo&>
105         ,invoke_case<false, int, foo*>
106         ,invoke_case<false, int, foo&>
107         ,invoke_case<false, void, foo&&>
108         ,invoke_case<true, void, std::reference_wrapper<foo>>
109         ,invoke_case<false, int, std::reference_wrapper<foo>>
110         ,invoke_case<false, void, foo const>
111         ,invoke_case<false, void, foo const*>
112         ,invoke_case<false, void, foo const&>
113         ,invoke_case<false, void, foo const&&>
114         ,invoke_case<false, void, std::reference_wrapper<foo const>>
115         ,invoke_case<false, void, foo, int>
116         ,invoke_case<false, void, foo*, int>
117         ,invoke_case<false, void, foo&, int>
118         ,invoke_case<false, void, foo&&, int>
119         ,invoke_case<false, void, std::reference_wrapper<foo>, int>
120     >();
121 
122     run_tests<void(foo::*)() RREF
123         ,invoke_case<true, void, foo>
124         ,invoke_case<false, int, foo>
125         ,invoke_case<false, void, foo*>
126         ,invoke_case<false, void, foo&>
127         ,invoke_case<true, void, foo&&>
128         ,invoke_case<false, int, foo&&>
129         ,invoke_case<false, void, std::reference_wrapper<foo>>
130         ,invoke_case<false, void, foo const>
131         ,invoke_case<false, void, foo const*>
132         ,invoke_case<false, void, foo const&>
133         ,invoke_case<false, void, foo const&&>
134         ,invoke_case<false, void, std::reference_wrapper<foo const>>
135         ,invoke_case<false, void, foo, int>
136         ,invoke_case<false, void, foo*, int>
137         ,invoke_case<false, void, foo&, int>
138         ,invoke_case<false, void, foo&&, int>
139         ,invoke_case<false, void, std::reference_wrapper<foo>, int>
140     >();
141 
142     run_tests<void(foo::*)() const
143         ,invoke_case<true, void, foo>
144         ,invoke_case<true, void, foo*>
145         ,invoke_case<true, void, foo&>
146         ,invoke_case<true, void, foo&&>
147         ,invoke_case<true, void, std::reference_wrapper<foo>>
148         ,invoke_case<true, void, foo const>
149         ,invoke_case<true, void, foo const*>
150         ,invoke_case<true, void, foo const&>
151         ,invoke_case<true, void, foo const&&>
152         ,invoke_case<true, void, std::reference_wrapper<foo const>>
153         ,invoke_case<false, int, foo>
154         ,invoke_case<false, int, foo*>
155         ,invoke_case<false, int, foo&>
156         ,invoke_case<false, int, foo&&>
157         ,invoke_case<false, int, std::reference_wrapper<foo>>
158         ,invoke_case<false, int, foo const>
159         ,invoke_case<false, int, foo const*>
160         ,invoke_case<false, int, foo const&>
161         ,invoke_case<false, int, foo const&&>
162         ,invoke_case<false, int, std::reference_wrapper<foo const>>
163         ,invoke_case<false, void, foo, int>
164         ,invoke_case<false, void, foo*, int>
165         ,invoke_case<false, void, foo&, int>
166         ,invoke_case<false, void, foo&&, int>
167         ,invoke_case<false, void, std::reference_wrapper<foo>, int>
168     >();
169 
170 // MSVC doesn't handle cv + ref qualifiers in expression sfinae correctly
171 #ifndef BOOST_CLBL_TRTS_MSVC
172 
173     run_tests<void(foo::*)() const LREF
174         ,invoke_case<false, void, foo>
175         ,invoke_case<true, void, foo*>
176         ,invoke_case<true, void, foo&>
177         ,invoke_case<false, int, foo*>
178         ,invoke_case<false, int, foo&>
179         ,invoke_case<false, void, foo&&>
180         ,invoke_case<true, void, std::reference_wrapper<foo>>
181         ,invoke_case<false, int, std::reference_wrapper<foo>>
182         ,invoke_case<false, void, foo const>
183         ,invoke_case<true, void, foo const*>
184         ,invoke_case<true, void, foo const&>
185         ,invoke_case<false, int, foo const*>
186         ,invoke_case<false, int, foo const&>
187         ,invoke_case<false, void, foo const&&>
188         ,invoke_case<true, void, std::reference_wrapper<foo const>>
189         ,invoke_case<false, int, std::reference_wrapper<foo const>>
190         ,invoke_case<false, void, foo, int>
191         ,invoke_case<false, void, foo*, int>
192         ,invoke_case<false, void, foo&, int>
193         ,invoke_case<false, void, foo&&, int>
194         ,invoke_case<false, void, std::reference_wrapper<foo>, int>
195     >();
196 
197     run_tests<void(foo::*)() const RREF
198         ,invoke_case<true, void, foo>
199         ,invoke_case<false, int, foo>
200         ,invoke_case<false, void, foo*>
201         ,invoke_case<false, void, foo&>
202         ,invoke_case<true, void, foo&&>
203         ,invoke_case<false, int, foo&&>
204         ,invoke_case<false, void, std::reference_wrapper<foo>>
205         ,invoke_case<true, void, foo const>
206         ,invoke_case<false, int, foo const>
207         ,invoke_case<false, void, foo const*>
208         ,invoke_case<false, void, foo const&>
209         ,invoke_case<true, void, foo const&&>
210         ,invoke_case<false, int, foo const&&>
211         ,invoke_case<false, void, std::reference_wrapper<foo const>>
212         ,invoke_case<false, void, foo, int>
213         ,invoke_case<false, void, foo*, int>
214         ,invoke_case<false, void, foo&, int>
215         ,invoke_case<false, void, foo&&, int>
216         ,invoke_case<false, void, std::reference_wrapper<foo>, int>
217     >();
218 
219 #endif // #ifndef BOOST_CLBL_TRTS_MSVC
220 
221     run_tests<int
222         ,invoke_case<false, void, foo>
223         ,invoke_case<false, void, foo*>
224         ,invoke_case<false, void, foo&>
225         ,invoke_case<false, void, foo&&>
226         ,invoke_case<false, void, std::reference_wrapper<foo>>
227         ,invoke_case<false, void, foo const>
228         ,invoke_case<false, void, foo const*>
229         ,invoke_case<false, void, foo const&>
230         ,invoke_case<false, void, foo const&&>
231         ,invoke_case<false, void, std::reference_wrapper<foo const>>
232         ,invoke_case<false, void, foo, int>
233         ,invoke_case<false, void, foo*, int>
234         ,invoke_case<false, void, foo&, int>
235         ,invoke_case<false, void, foo&&, int>
236         ,invoke_case<false, void, std::reference_wrapper<foo>, int>
237     >();
238 
239     auto f = [](int){};
240 
241     run_tests<decltype(f)
242         ,invoke_case<true, void, int>
243         ,invoke_case<true, void, char>
244         ,invoke_case<false, int, int>
245         ,invoke_case<false, int, char>
246         ,invoke_case<false, void, void*>
247     >();
248 
249     auto g = [](){};
250 
251     run_tests<decltype(g)
252         ,invoke_case<true, void>
253         ,invoke_case<true, void>
254         ,invoke_case<false, void, int>
255         ,invoke_case<false, void, char>
256         ,invoke_case<false, int, int>
257         ,invoke_case<false, int, char>
258         ,invoke_case<false, void, void*>
259     >();
260 
261 // libc++ requires constructible types be passed to std::is_invocable
262 #ifndef  _LIBCPP_VERSION
263 
264     run_tests<void(int)
265         ,invoke_case<true, void, int>
266         ,invoke_case<true, void, char>
267         ,invoke_case<false, int, int>
268         ,invoke_case<false, int, char>
269         ,invoke_case<false, void, void*>
270     >();
271 
272     run_tests<void()
273         ,invoke_case<false, void, int>
274         ,invoke_case<false, void, char>
275         ,invoke_case<false, void, void*>
276     >();
277 
278     run_tests<void
279         ,invoke_case<false, void, foo>
280         ,invoke_case<false, void, foo*>
281         ,invoke_case<false, void, foo&>
282         ,invoke_case<false, void, foo&&>
283         ,invoke_case<false, void, std::reference_wrapper<foo>>
284         ,invoke_case<false, void, foo const>
285         ,invoke_case<false, void, foo const*>
286         ,invoke_case<false, void, foo const&>
287         ,invoke_case<false, void, foo const&&>
288         ,invoke_case<false, void, std::reference_wrapper<foo const>>
289         ,invoke_case<false, void, foo, int>
290         ,invoke_case<false, void, foo*, int>
291         ,invoke_case<false, void, foo&, int>
292         ,invoke_case<false, void, foo&&, int>
293         ,invoke_case<false, void, std::reference_wrapper<foo>, int>
294     >();
295 #endif
296 
297     run_tests<int
298         ,invoke_case<false, void, foo>
299         ,invoke_case<false, void, foo*>
300         ,invoke_case<false, void, foo&>
301         ,invoke_case<false, void, foo&&>
302         ,invoke_case<false, void, std::reference_wrapper<foo>>
303         ,invoke_case<false, void, foo const>
304         ,invoke_case<false, void, foo const*>
305         ,invoke_case<false, void, foo const&>
306         ,invoke_case<false, void, foo const&&>
307         ,invoke_case<false, void, std::reference_wrapper<foo const>>
308         ,invoke_case<false, void, foo, int>
309         ,invoke_case<false, void, foo*, int>
310         ,invoke_case<false, void, foo&, int>
311         ,invoke_case<false, void, foo&&, int>
312         ,invoke_case<false, void, std::reference_wrapper<foo>, int>
313     >();
314 
315     run_tests<void*
316         ,invoke_case<false, void, foo>
317         ,invoke_case<false, void, foo*>
318         ,invoke_case<false, void, foo&>
319         ,invoke_case<false, void, foo&&>
320         ,invoke_case<false, void, std::reference_wrapper<foo>>
321         ,invoke_case<false, void, foo const>
322         ,invoke_case<false, void, foo const*>
323         ,invoke_case<false, void, foo const&>
324         ,invoke_case<false, void, foo const&&>
325         ,invoke_case<false, void, std::reference_wrapper<foo const>>
326         ,invoke_case<false, void, foo, int>
327         ,invoke_case<false, void, foo*, int>
328         ,invoke_case<false, void, foo&, int>
329         ,invoke_case<false, void, foo&&, int>
330         ,invoke_case<false, void, std::reference_wrapper<foo>, int>
331     >();
332 }
333 
334 #endif //#ifdef BOOST_CLBL_TRTS_GCC_OLDER_THAN_4_9_2
335