File indexing completed on 2025-01-18 09:34:40
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #if !defined(BOOST_FUSION_FUNCTIONAL_INVOCATION_INVOKE_HPP_INCLUDED)
0011 #if !defined(BOOST_PP_IS_ITERATING)
0012
0013 #include <boost/preprocessor/cat.hpp>
0014 #include <boost/preprocessor/iteration/iterate.hpp>
0015 #include <boost/preprocessor/arithmetic/dec.hpp>
0016 #include <boost/preprocessor/repetition/repeat_from_to.hpp>
0017 #include <boost/preprocessor/repetition/enum.hpp>
0018 #include <boost/preprocessor/repetition/enum_shifted.hpp>
0019 #include <boost/preprocessor/repetition/enum_params.hpp>
0020 #include <boost/preprocessor/repetition/enum_shifted_params.hpp>
0021
0022 #include <boost/mpl/if.hpp>
0023 #include <boost/mpl/eval_if.hpp>
0024 #include <boost/mpl/or.hpp>
0025 #include <boost/mpl/front.hpp>
0026 #include <boost/mpl/identity.hpp>
0027
0028 #include <boost/type_traits/add_const.hpp>
0029 #include <boost/type_traits/remove_cv.hpp>
0030 #include <boost/type_traits/add_reference.hpp>
0031 #include <boost/type_traits/remove_reference.hpp>
0032 #include <boost/type_traits/is_convertible.hpp>
0033
0034 #include <boost/function_types/is_function.hpp>
0035 #include <boost/function_types/is_callable_builtin.hpp>
0036 #include <boost/function_types/is_member_pointer.hpp>
0037 #include <boost/function_types/is_member_function_pointer.hpp>
0038 #include <boost/function_types/result_type.hpp>
0039 #include <boost/function_types/parameter_types.hpp>
0040
0041 #include <boost/utility/result_of.hpp>
0042 #include <boost/core/enable_if.hpp>
0043
0044 #include <boost/fusion/support/category_of.hpp>
0045 #include <boost/fusion/sequence/intrinsic/at.hpp>
0046 #include <boost/fusion/sequence/intrinsic/size.hpp>
0047 #include <boost/fusion/sequence/intrinsic/front.hpp>
0048 #include <boost/fusion/sequence/intrinsic/begin.hpp>
0049 #include <boost/fusion/iterator/next.hpp>
0050 #include <boost/fusion/iterator/deref.hpp>
0051 #include <boost/fusion/functional/invocation/limits.hpp>
0052 #include <boost/fusion/functional/invocation/detail/that_ptr.hpp>
0053
0054 namespace boost { namespace fusion
0055 {
0056 namespace detail
0057 {
0058 namespace ft = function_types;
0059
0060 template<
0061 typename Function, class Sequence,
0062 int N = result_of::size<Sequence>::value,
0063 bool CBI = ft::is_callable_builtin<Function>::value,
0064 bool RandomAccess = traits::is_random_access<Sequence>::value,
0065 typename Enable = void
0066 >
0067 struct invoke_impl;
0068
0069 template <class Sequence, int N>
0070 struct invoke_param_types;
0071
0072 template <typename T, class Sequence>
0073 struct invoke_data_member;
0074
0075 template <typename Function, class Sequence, int N, bool RandomAccess>
0076 struct invoke_fn_ptr;
0077
0078 template <typename Function, class Sequence, int N, bool RandomAccess>
0079 struct invoke_mem_fn;
0080
0081 #define BOOST_PP_FILENAME_1 <boost/fusion/functional/invocation/invoke.hpp>
0082 #define BOOST_PP_ITERATION_LIMITS (0, BOOST_FUSION_INVOKE_MAX_ARITY)
0083 #include BOOST_PP_ITERATE()
0084
0085 template <typename F, class Sequence, int N, bool RandomAccess>
0086 struct invoke_nonmember_builtin
0087
0088 : invoke_fn_ptr<
0089 typename mpl::eval_if< ft::is_function<F>,
0090 boost::add_reference<F>, boost::remove_cv<F> >::type,
0091 Sequence, N, RandomAccess >
0092 { };
0093
0094 template <typename Function, class Sequence, int N, bool RandomAccess, typename Enable>
0095 struct invoke_impl<Function,Sequence,N,true,RandomAccess,Enable>
0096 : mpl::if_< ft::is_member_function_pointer<Function>,
0097 invoke_mem_fn<Function,Sequence,N,RandomAccess>,
0098 invoke_nonmember_builtin<Function,Sequence,N,RandomAccess>
0099 >::type
0100 { };
0101
0102 template <typename Function, class Sequence, bool RandomAccess, typename Enable>
0103 struct invoke_impl<Function,Sequence,1,true,RandomAccess,Enable>
0104 : mpl::eval_if< ft::is_member_pointer<Function>,
0105 mpl::if_< ft::is_member_function_pointer<Function>,
0106 invoke_mem_fn<Function,Sequence,1,RandomAccess>,
0107 invoke_data_member<Function, Sequence> >,
0108 mpl::identity< invoke_nonmember_builtin<
0109 Function,Sequence,1,RandomAccess> >
0110 >::type
0111 { };
0112
0113 template <typename T, class C, class Sequence>
0114 struct invoke_data_member< T C::*, Sequence >
0115 {
0116 private:
0117
0118 typedef typename result_of::front<Sequence>::type that;
0119
0120 typedef mpl::or_< boost::is_convertible<that,C*>,
0121 boost::is_convertible<that,C&>,
0122 non_const_pointee<that> > non_const_cond;
0123
0124 typedef typename mpl::eval_if< non_const_cond,
0125 mpl::identity<C>, add_const<C> >::type qualified_class;
0126
0127 typedef typename mpl::eval_if< non_const_cond,
0128 mpl::identity<T>, add_const<T> >::type qualified_type;
0129
0130 public:
0131
0132 typedef typename boost::add_reference<qualified_type>::type
0133 result_type;
0134
0135 BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
0136 static inline result_type call(T C::* f, Sequence & s)
0137 {
0138 typename result_of::front<Sequence>::type c = fusion::front(s);
0139 return that_ptr<qualified_class>::get(c)->*f;
0140 }
0141 };
0142 }
0143
0144 namespace result_of
0145 {
0146 template <typename Function, class Sequence, typename = void>
0147 struct invoke;
0148
0149 template <typename Function, class Sequence>
0150 struct invoke<Function, Sequence,
0151 typename enable_if_has_type<
0152 typename detail::invoke_impl<
0153 typename boost::remove_reference<Function>::type, Sequence
0154 >::result_type
0155 >::type>
0156 {
0157 typedef typename detail::invoke_impl<
0158 typename boost::remove_reference<Function>::type, Sequence
0159 >::result_type type;
0160 };
0161 }
0162
0163 template <typename Function, class Sequence>
0164 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
0165 inline typename result_of::invoke<Function,Sequence>::type
0166 invoke(Function f, Sequence & s)
0167 {
0168 return detail::invoke_impl<
0169 typename boost::remove_reference<Function>::type,Sequence
0170 >::call(f,s);
0171 }
0172
0173 template <typename Function, class Sequence>
0174 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
0175 inline typename result_of::invoke<Function,Sequence const>::type
0176 invoke(Function f, Sequence const & s)
0177 {
0178 return detail::invoke_impl<
0179 typename boost::remove_reference<Function>::type,Sequence const
0180 >::call(f,s);
0181 }
0182
0183 }}
0184
0185 #define BOOST_FUSION_FUNCTIONAL_INVOCATION_INVOKE_HPP_INCLUDED
0186 #else
0187
0188
0189
0190
0191
0192 #define N BOOST_PP_ITERATION()
0193
0194 #define M(z,j,data) typename result_of::at_c<Sequence,j>::type
0195
0196 template <typename Function, class Sequence>
0197 struct invoke_impl<Function,Sequence,N,false,true,
0198 typename enable_if_has_type<
0199 typename boost::result_of<Function(BOOST_PP_ENUM(N,M,~)) >::type
0200 >::type>
0201 {
0202 public:
0203
0204 typedef typename boost::result_of<
0205 Function(BOOST_PP_ENUM(N,M,~)) >::type result_type;
0206 #undef M
0207
0208 #if N > 0
0209
0210 template <typename F>
0211 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
0212 static inline result_type
0213 call(F & f, Sequence & s)
0214 {
0215 #define M(z,j,data) fusion::at_c<j>(s)
0216 return f( BOOST_PP_ENUM(N,M,~) );
0217 }
0218
0219 #else
0220 template <typename F>
0221 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
0222 static inline result_type
0223 call(F & f, Sequence & )
0224 {
0225 return f();
0226 }
0227
0228 #endif
0229
0230 };
0231
0232 template <typename Function, class Sequence>
0233 struct invoke_fn_ptr<Function,Sequence,N,true>
0234 {
0235 public:
0236
0237 typedef typename ft::result_type<Function>::type result_type;
0238
0239 #if N > 0
0240
0241 template <typename F>
0242 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
0243 static inline result_type
0244 call(F & f, Sequence & s)
0245 {
0246 #define M(z,j,data) fusion::at_c<j>(s)
0247 return f( BOOST_PP_ENUM(N,M,~) );
0248 }
0249
0250 #else
0251 template <typename F>
0252 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
0253 static inline result_type
0254 call(F & f, Sequence & )
0255 {
0256 return f();
0257 }
0258
0259 #endif
0260
0261 };
0262
0263
0264 #if N > 0
0265 template <typename Function, class Sequence>
0266 struct invoke_mem_fn<Function,Sequence,N,true>
0267 {
0268 public:
0269
0270 typedef typename ft::result_type<Function>::type result_type;
0271
0272 template <typename F>
0273 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
0274 static inline result_type
0275 call(F & f, Sequence & s)
0276 {
0277 return (that_ptr<typename mpl::front<
0278 ft::parameter_types<Function> >::type
0279 >::get(fusion::at_c<0>(s))->*f)(BOOST_PP_ENUM_SHIFTED(N,M,~));
0280 }
0281 };
0282 #endif
0283
0284 #undef M
0285
0286 #define M(z,j,data) \
0287 typename seq::I##j i##j = \
0288 fusion::next(BOOST_PP_CAT(i,BOOST_PP_DEC(j)));
0289
0290 template <typename Function, class Sequence>
0291 struct invoke_impl<Function,Sequence,N,false,false,
0292 typename enable_if_has_type<
0293 #define L(z,j,data) typename invoke_param_types<Sequence,N>::BOOST_PP_CAT(T, j)
0294 typename boost::result_of<Function(BOOST_PP_ENUM(N,L,~))>::type
0295 >::type>
0296 #undef L
0297 {
0298 private:
0299 typedef invoke_param_types<Sequence,N> seq;
0300 public:
0301
0302 typedef typename boost::result_of<
0303 Function(BOOST_PP_ENUM_PARAMS(N,typename seq::T))
0304 >::type result_type;
0305
0306 #if N > 0
0307
0308 template <typename F>
0309 BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
0310 static inline result_type
0311 call(F & f, Sequence & s)
0312 {
0313 typename seq::I0 i0 = fusion::begin(s);
0314 BOOST_PP_REPEAT_FROM_TO(1,N,M,~)
0315 return f( BOOST_PP_ENUM_PARAMS(N,*i) );
0316 }
0317
0318 #else
0319
0320 template <typename F>
0321 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
0322 static inline result_type
0323 call(F & f, Sequence & )
0324 {
0325 return f();
0326 }
0327
0328 #endif
0329
0330 };
0331
0332 template <typename Function, class Sequence>
0333 struct invoke_fn_ptr<Function,Sequence,N,false>
0334 {
0335 private:
0336 typedef invoke_param_types<Sequence,N> seq;
0337 public:
0338
0339 typedef typename ft::result_type<Function>::type result_type;
0340
0341 #if N > 0
0342
0343 template <typename F>
0344 BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
0345 static inline result_type
0346 call(F & f, Sequence & s)
0347 {
0348 typename seq::I0 i0 = fusion::begin(s);
0349 BOOST_PP_REPEAT_FROM_TO(1,N,M,~)
0350 return f( BOOST_PP_ENUM_PARAMS(N,*i) );
0351 }
0352
0353 #else
0354
0355 template <typename F>
0356 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
0357 static inline result_type
0358 call(F & f, Sequence & )
0359 {
0360 return f();
0361 }
0362
0363 #endif
0364
0365 };
0366
0367 #if N > 0
0368 template <typename Function, class Sequence>
0369 struct invoke_mem_fn<Function,Sequence,N,false>
0370 {
0371 private:
0372 typedef invoke_param_types<Sequence,N> seq;
0373 public:
0374
0375 typedef typename ft::result_type<Function>::type result_type;
0376
0377 template <typename F>
0378 BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
0379 static inline result_type
0380 call(F & f, Sequence & s)
0381 {
0382 typename seq::I0 i0 = fusion::begin(s);
0383 BOOST_PP_REPEAT_FROM_TO(1,N,M,~)
0384
0385 return (that_ptr< typename mpl::front<
0386 ft::parameter_types<Function> >::type
0387 >::get(*i0)->*f)(BOOST_PP_ENUM_SHIFTED_PARAMS(N,*i));
0388 }
0389 };
0390 #endif
0391
0392 #undef M
0393
0394 template <class Sequence> struct invoke_param_types<Sequence,N>
0395 {
0396 #if N > 0
0397 typedef typename result_of::begin<Sequence>::type I0;
0398 typedef typename result_of::deref<I0>::type T0;
0399
0400 #define M(z,i,data) \
0401 typedef typename result_of::next< \
0402 BOOST_PP_CAT(I,BOOST_PP_DEC(i))>::type I##i; \
0403 typedef typename result_of::deref<I##i>::type T##i;
0404
0405 BOOST_PP_REPEAT_FROM_TO(1,N,M,~)
0406 #undef M
0407 #endif
0408 };
0409
0410
0411 #undef N
0412 #endif
0413 #endif
0414