Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:34:40

0001 /*=============================================================================
0002     Copyright (c) 2005-2006 Joao Abecasis
0003     Copyright (c) 2006-2007 Tobias Schwinger
0004 
0005     Use modification and distribution are subject to the Boost Software
0006     License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
0007     http://www.boost.org/LICENSE_1_0.txt).
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         // use same implementation as for function objects but...
0088             : invoke_fn_ptr< // ...work around boost::result_of bugs
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 // defined(BOOST_PP_IS_ITERATING)
0187 ///////////////////////////////////////////////////////////////////////////////
0188 //
0189 //  Preprocessor vertical repetition code
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 & /*s*/)
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 & /*s*/)
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 & /*s*/)
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 & /*s*/)
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 // defined(BOOST_PP_IS_ITERATING)
0413 #endif
0414