Mercurial > hg > vamp-build-and-test
comparison DEPENDENCIES/generic/include/boost/fusion/functional/invocation/invoke.hpp @ 16:2665513ce2d3
Add boost headers
author | Chris Cannam |
---|---|
date | Tue, 05 Aug 2014 11:11:38 +0100 |
parents | |
children | c530137014c0 |
comparison
equal
deleted
inserted
replaced
15:663ca0da4350 | 16:2665513ce2d3 |
---|---|
1 /*============================================================================= | |
2 Copyright (c) 2005-2006 Joao Abecasis | |
3 Copyright (c) 2006-2007 Tobias Schwinger | |
4 | |
5 Use modification and distribution are subject to the Boost Software | |
6 License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at | |
7 http://www.boost.org/LICENSE_1_0.txt). | |
8 ==============================================================================*/ | |
9 | |
10 #if !defined(BOOST_FUSION_FUNCTIONAL_INVOCATION_INVOKE_HPP_INCLUDED) | |
11 #if !defined(BOOST_PP_IS_ITERATING) | |
12 | |
13 #include <boost/preprocessor/cat.hpp> | |
14 #include <boost/preprocessor/iteration/iterate.hpp> | |
15 #include <boost/preprocessor/arithmetic/dec.hpp> | |
16 #include <boost/preprocessor/repetition/repeat_from_to.hpp> | |
17 #include <boost/preprocessor/repetition/enum.hpp> | |
18 #include <boost/preprocessor/repetition/enum_shifted.hpp> | |
19 #include <boost/preprocessor/repetition/enum_params.hpp> | |
20 #include <boost/preprocessor/repetition/enum_shifted_params.hpp> | |
21 | |
22 #include <boost/mpl/if.hpp> | |
23 #include <boost/mpl/eval_if.hpp> | |
24 #include <boost/mpl/or.hpp> | |
25 #include <boost/mpl/front.hpp> | |
26 #include <boost/mpl/identity.hpp> | |
27 | |
28 #include <boost/type_traits/add_const.hpp> | |
29 #include <boost/type_traits/remove_cv.hpp> | |
30 #include <boost/type_traits/add_reference.hpp> | |
31 #include <boost/type_traits/remove_reference.hpp> | |
32 #include <boost/type_traits/is_convertible.hpp> | |
33 | |
34 #include <boost/function_types/is_function.hpp> | |
35 #include <boost/function_types/is_callable_builtin.hpp> | |
36 #include <boost/function_types/is_member_pointer.hpp> | |
37 #include <boost/function_types/is_member_function_pointer.hpp> | |
38 #include <boost/function_types/result_type.hpp> | |
39 #include <boost/function_types/parameter_types.hpp> | |
40 | |
41 #include <boost/utility/result_of.hpp> | |
42 | |
43 #include <boost/fusion/support/category_of.hpp> | |
44 #include <boost/fusion/sequence/intrinsic/at.hpp> | |
45 #include <boost/fusion/sequence/intrinsic/size.hpp> | |
46 #include <boost/fusion/sequence/intrinsic/front.hpp> | |
47 #include <boost/fusion/sequence/intrinsic/begin.hpp> | |
48 #include <boost/fusion/iterator/next.hpp> | |
49 #include <boost/fusion/iterator/deref.hpp> | |
50 #include <boost/fusion/functional/invocation/limits.hpp> | |
51 #include <boost/fusion/functional/invocation/detail/that_ptr.hpp> | |
52 | |
53 namespace boost { namespace fusion | |
54 { | |
55 namespace result_of | |
56 { | |
57 template <typename Function, class Sequence> struct invoke; | |
58 } | |
59 | |
60 //~ template <typename Function, class Sequence> | |
61 //~ inline typename result_of::invoke<Function, Sequence>::type | |
62 //~ invoke(Function, Sequence &); | |
63 | |
64 //~ template <typename Function, class Sequence> | |
65 //~ inline typename result_of::invoke<Function, Sequence const>::type | |
66 //~ invoke(Function, Sequence const &); | |
67 | |
68 //----- ---- --- -- - - - - | |
69 | |
70 namespace detail | |
71 { | |
72 namespace ft = function_types; | |
73 | |
74 template< | |
75 typename Function, class Sequence, | |
76 int N = result_of::size<Sequence>::value, | |
77 bool CBI = ft::is_callable_builtin<Function>::value, | |
78 bool RandomAccess = traits::is_random_access<Sequence>::value | |
79 > | |
80 struct invoke_impl; | |
81 | |
82 template <class Sequence, int N> | |
83 struct invoke_param_types; | |
84 | |
85 template <typename T, class Sequence> | |
86 struct invoke_data_member; | |
87 | |
88 template <typename Function, class Sequence, int N, bool RandomAccess> | |
89 struct invoke_fn_ptr; | |
90 | |
91 template <typename Function, class Sequence, int N, bool RandomAccess> | |
92 struct invoke_mem_fn; | |
93 | |
94 #define BOOST_PP_FILENAME_1 <boost/fusion/functional/invocation/invoke.hpp> | |
95 #define BOOST_PP_ITERATION_LIMITS (0, BOOST_FUSION_INVOKE_MAX_ARITY) | |
96 #include BOOST_PP_ITERATE() | |
97 | |
98 template <typename F, class Sequence, int N, bool RandomAccess> | |
99 struct invoke_nonmember_builtin | |
100 // use same implementation as for function objects but... | |
101 : invoke_fn_ptr< // ...work around boost::result_of bugs | |
102 typename mpl::eval_if< ft::is_function<F>, | |
103 boost::add_reference<F>, boost::remove_cv<F> >::type, | |
104 Sequence, N, RandomAccess > | |
105 { }; | |
106 | |
107 template <typename Function, class Sequence, int N, bool RandomAccess> | |
108 struct invoke_impl<Function,Sequence,N,true,RandomAccess> | |
109 : mpl::if_< ft::is_member_function_pointer<Function>, | |
110 invoke_mem_fn<Function,Sequence,N,RandomAccess>, | |
111 invoke_nonmember_builtin<Function,Sequence,N,RandomAccess> | |
112 >::type | |
113 { }; | |
114 | |
115 template <typename Function, class Sequence, bool RandomAccess> | |
116 struct invoke_impl<Function,Sequence,1,true,RandomAccess> | |
117 : mpl::eval_if< ft::is_member_pointer<Function>, | |
118 mpl::if_< ft::is_member_function_pointer<Function>, | |
119 invoke_mem_fn<Function,Sequence,1,RandomAccess>, | |
120 invoke_data_member<Function, Sequence> >, | |
121 mpl::identity< invoke_nonmember_builtin< | |
122 Function,Sequence,1,RandomAccess> > | |
123 >::type | |
124 { }; | |
125 | |
126 template <typename T, class C, class Sequence> | |
127 struct invoke_data_member< T C::*, Sequence > | |
128 { | |
129 private: | |
130 | |
131 typedef typename result_of::front<Sequence>::type that; | |
132 | |
133 typedef mpl::or_< boost::is_convertible<that,C*>, | |
134 boost::is_convertible<that,C&>, | |
135 non_const_pointee<that> > non_const_cond; | |
136 | |
137 typedef typename mpl::eval_if< non_const_cond, | |
138 mpl::identity<C>, add_const<C> >::type qualified_class; | |
139 | |
140 typedef typename mpl::eval_if< non_const_cond, | |
141 mpl::identity<T>, add_const<T> >::type qualified_type; | |
142 | |
143 public: | |
144 | |
145 typedef typename boost::add_reference<qualified_type>::type | |
146 result_type; | |
147 | |
148 static inline result_type call(T C::* f, Sequence & s) | |
149 { | |
150 typename result_of::front<Sequence>::type c = fusion::front(s); | |
151 return that_ptr<qualified_class>::get(c)->*f; | |
152 } | |
153 }; | |
154 } | |
155 | |
156 namespace result_of | |
157 { | |
158 template <typename Function, class Sequence> struct invoke | |
159 { | |
160 typedef typename detail::invoke_impl< | |
161 typename boost::remove_reference<Function>::type, Sequence | |
162 >::result_type type; | |
163 }; | |
164 } | |
165 | |
166 template <typename Function, class Sequence> | |
167 inline typename result_of::invoke<Function,Sequence>::type | |
168 invoke(Function f, Sequence & s) | |
169 { | |
170 return detail::invoke_impl< | |
171 typename boost::remove_reference<Function>::type,Sequence | |
172 >::call(f,s); | |
173 } | |
174 | |
175 template <typename Function, class Sequence> | |
176 inline typename result_of::invoke<Function,Sequence const>::type | |
177 invoke(Function f, Sequence const & s) | |
178 { | |
179 return detail::invoke_impl< | |
180 typename boost::remove_reference<Function>::type,Sequence const | |
181 >::call(f,s); | |
182 } | |
183 | |
184 }} | |
185 | |
186 #define BOOST_FUSION_FUNCTIONAL_INVOCATION_INVOKE_HPP_INCLUDED | |
187 #else // defined(BOOST_PP_IS_ITERATING) | |
188 /////////////////////////////////////////////////////////////////////////////// | |
189 // | |
190 // Preprocessor vertical repetition code | |
191 // | |
192 /////////////////////////////////////////////////////////////////////////////// | |
193 #define N BOOST_PP_ITERATION() | |
194 | |
195 template <typename Function, class Sequence> | |
196 struct invoke_impl<Function,Sequence,N,false,true> | |
197 { | |
198 public: | |
199 | |
200 typedef typename boost::result_of< | |
201 #define M(z,j,data) typename result_of::at_c<Sequence,j>::type | |
202 Function(BOOST_PP_ENUM(N,M,~)) >::type result_type; | |
203 #undef M | |
204 | |
205 #if N > 0 | |
206 | |
207 template <typename F> | |
208 static inline result_type | |
209 call(F & f, Sequence & s) | |
210 { | |
211 #define M(z,j,data) fusion::at_c<j>(s) | |
212 return f( BOOST_PP_ENUM(N,M,~) ); | |
213 } | |
214 | |
215 #else | |
216 template <typename F> | |
217 static inline result_type | |
218 call(F & f, Sequence & /*s*/) | |
219 { | |
220 return f(); | |
221 } | |
222 | |
223 #endif | |
224 | |
225 }; | |
226 | |
227 template <typename Function, class Sequence> | |
228 struct invoke_fn_ptr<Function,Sequence,N,true> | |
229 { | |
230 public: | |
231 | |
232 typedef typename ft::result_type<Function>::type result_type; | |
233 | |
234 #if N > 0 | |
235 | |
236 template <typename F> | |
237 static inline result_type | |
238 call(F & f, Sequence & s) | |
239 { | |
240 #define M(z,j,data) fusion::at_c<j>(s) | |
241 return f( BOOST_PP_ENUM(N,M,~) ); | |
242 } | |
243 | |
244 #else | |
245 template <typename F> | |
246 static inline result_type | |
247 call(F & f, Sequence & /*s*/) | |
248 { | |
249 return f(); | |
250 } | |
251 | |
252 #endif | |
253 | |
254 }; | |
255 | |
256 | |
257 #if N > 0 | |
258 template <typename Function, class Sequence> | |
259 struct invoke_mem_fn<Function,Sequence,N,true> | |
260 { | |
261 public: | |
262 | |
263 typedef typename ft::result_type<Function>::type result_type; | |
264 | |
265 template <typename F> | |
266 static inline result_type | |
267 call(F & f, Sequence & s) | |
268 { | |
269 return (that_ptr<typename mpl::front< | |
270 ft::parameter_types<Function> >::type | |
271 >::get(fusion::at_c<0>(s))->*f)(BOOST_PP_ENUM_SHIFTED(N,M,~)); | |
272 } | |
273 }; | |
274 #endif | |
275 | |
276 #undef M | |
277 | |
278 #define M(z,j,data) \ | |
279 typename seq::I##j i##j = \ | |
280 fusion::next(BOOST_PP_CAT(i,BOOST_PP_DEC(j))); | |
281 | |
282 template <typename Function, class Sequence> | |
283 struct invoke_impl<Function,Sequence,N,false,false> | |
284 { | |
285 private: | |
286 typedef invoke_param_types<Sequence,N> seq; | |
287 public: | |
288 | |
289 typedef typename boost::result_of< | |
290 Function(BOOST_PP_ENUM_PARAMS(N,typename seq::T)) | |
291 >::type result_type; | |
292 | |
293 #if N > 0 | |
294 | |
295 template <typename F> | |
296 static inline result_type | |
297 call(F & f, Sequence & s) | |
298 { | |
299 typename seq::I0 i0 = fusion::begin(s); | |
300 BOOST_PP_REPEAT_FROM_TO(1,N,M,~) | |
301 return f( BOOST_PP_ENUM_PARAMS(N,*i) ); | |
302 } | |
303 | |
304 #else | |
305 | |
306 template <typename F> | |
307 static inline result_type | |
308 call(F & f, Sequence & /*s*/) | |
309 { | |
310 return f(); | |
311 } | |
312 | |
313 #endif | |
314 | |
315 }; | |
316 | |
317 template <typename Function, class Sequence> | |
318 struct invoke_fn_ptr<Function,Sequence,N,false> | |
319 { | |
320 private: | |
321 typedef invoke_param_types<Sequence,N> seq; | |
322 public: | |
323 | |
324 typedef typename ft::result_type<Function>::type result_type; | |
325 | |
326 #if N > 0 | |
327 | |
328 template <typename F> | |
329 static inline result_type | |
330 call(F & f, Sequence & s) | |
331 { | |
332 typename seq::I0 i0 = fusion::begin(s); | |
333 BOOST_PP_REPEAT_FROM_TO(1,N,M,~) | |
334 return f( BOOST_PP_ENUM_PARAMS(N,*i) ); | |
335 } | |
336 | |
337 #else | |
338 | |
339 template <typename F> | |
340 static inline result_type | |
341 call(F & f, Sequence & /*s*/) | |
342 { | |
343 return f(); | |
344 } | |
345 | |
346 #endif | |
347 | |
348 }; | |
349 | |
350 #if N > 0 | |
351 template <typename Function, class Sequence> | |
352 struct invoke_mem_fn<Function,Sequence,N,false> | |
353 { | |
354 private: | |
355 typedef invoke_param_types<Sequence,N> seq; | |
356 public: | |
357 | |
358 typedef typename ft::result_type<Function>::type result_type; | |
359 | |
360 template <typename F> | |
361 static inline result_type | |
362 call(F & f, Sequence & s) | |
363 { | |
364 typename seq::I0 i0 = fusion::begin(s); | |
365 BOOST_PP_REPEAT_FROM_TO(1,N,M,~) | |
366 | |
367 return (that_ptr< typename mpl::front< | |
368 ft::parameter_types<Function> >::type | |
369 >::get(*i0)->*f)(BOOST_PP_ENUM_SHIFTED_PARAMS(N,*i)); | |
370 } | |
371 }; | |
372 #endif | |
373 | |
374 #undef M | |
375 | |
376 template <class Sequence> struct invoke_param_types<Sequence,N> | |
377 { | |
378 #if N > 0 | |
379 typedef typename result_of::begin<Sequence>::type I0; | |
380 typedef typename result_of::deref<I0>::type T0; | |
381 | |
382 #define M(z,i,data) \ | |
383 typedef typename result_of::next< \ | |
384 BOOST_PP_CAT(I,BOOST_PP_DEC(i))>::type I##i; \ | |
385 typedef typename result_of::deref<I##i>::type T##i; | |
386 | |
387 BOOST_PP_REPEAT_FROM_TO(1,N,M,~) | |
388 #undef M | |
389 #endif | |
390 }; | |
391 | |
392 | |
393 #undef N | |
394 #endif // defined(BOOST_PP_IS_ITERATING) | |
395 #endif | |
396 |