/*============================================================================= Copyright (c) 2005-2006 João Abecasis Copyright (c) 2006-2007 Tobias Schwinger Use modification and distribution are subject to the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt). ==============================================================================*/ #if !defined(BOOST_FUSION_FUNCTIONAL_INVOCATION_INVOKE_HPP_INCLUDED) #if !defined(BOOST_PP_IS_ITERATING) #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace boost { namespace fusion { namespace result_of { template struct invoke; } template inline typename result_of::invoke::type invoke(Function, Sequence &); template inline typename result_of::invoke::type invoke(Function, Sequence const &); //----- ---- --- -- - - - - namespace detail { namespace ft = function_types; template< typename Function, class Sequence, int N = result_of::size::value, bool CBI = ft::is_callable_builtin::value, bool MFP = ft::is_member_function_pointer::value, bool RandomAccess = traits::is_random_access::value > struct invoke_impl { typedef boost::blank result; }; template struct invoke_param_types; template // contains type member with the result, empty on error struct invoke_result : mpl::if_< mpl::or_< mpl::equal_to< ft::function_arity, N >, mpl::and_< ft::is_callable_builtin, mpl::less< ft::function_arity, N > > >, ft::result_type, boost::blank >::type { }; template struct invoke_result : boost::result_of { }; // Transform for F so that boost::result_of< F(...) > works template struct invoke_result_of_prep : mpl::if_< ft::is_function, boost::add_reference, boost::remove_cv >::type { }; #define BOOST_PP_FILENAME_1 #define BOOST_PP_ITERATION_LIMITS (0, BOOST_FUSION_INVOKE_MAX_ARITY) #include BOOST_PP_ITERATE() template struct invoke_data_member { private: typedef typename result_of::front::type that; typedef mpl::or_< is_convertible, is_convertible, non_const_pointee > non_const_cond; typedef typename mpl::eval_if< non_const_cond, mpl::identity, add_const >::type qualified_class; typedef typename mpl::eval_if< non_const_cond, mpl::identity, add_const >::type qualified_type; public: template struct result : boost::add_reference { }; static inline typename result<>::type call(T C::* f, Sequence & s) { typename result_of::front::type c = fusion::front(s); return that_ptr::get(c)->*f; } }; template struct invoke_impl : detail::invoke_data_member { }; template struct invoke_impl : detail::invoke_data_member { }; } namespace result_of { template struct invoke : detail::invoke_impl< typename boost::remove_reference::type, Sequence >::template result<> { }; } template inline typename result_of::invoke::type invoke(Function f, Sequence & s) { return detail::invoke_impl< typename boost::remove_reference::type,Sequence >::call(f,s); } template inline typename result_of::invoke::type invoke(Function f, Sequence const & s) { return detail::invoke_impl< typename boost::remove_reference::type,Sequence const >::call(f,s); } }} #define BOOST_FUSION_FUNCTIONAL_INVOCATION_INVOKE_HPP_INCLUDED #else // defined(BOOST_PP_IS_ITERATING) /////////////////////////////////////////////////////////////////////////////// // // Preprocessor vertical repetition code // /////////////////////////////////////////////////////////////////////////////// #define N BOOST_PP_ITERATION() template struct invoke_impl { private: typedef typename invoke_result_of_prep::type func; public: template struct result : invoke_result< Function, mpl::size_t, CBI, #define M(z,j,data) typename result_of::at_c::type func(BOOST_PP_ENUM(N,M,~)) > #undef M { }; template static inline typename result::type call(F & f, Sequence & s) { #define M(z,j,data) fusion::at_c(s) return f( BOOST_PP_ENUM(N,M,~) ); } }; #if N > 0 template struct invoke_impl { public: template struct result : invoke_result< Function, mpl::size_t > { }; template static inline typename result::type call(F & f, Sequence & s) { return (that_ptr >::type >::get(fusion::at_c<0>(s))->*f)(BOOST_PP_ENUM_SHIFTED(N,M,~)); } }; #endif #undef M #define M(z,j,data) \ typename seq::I##j i##j = \ fusion::next(BOOST_PP_CAT(i,BOOST_PP_DEC(j))); template struct invoke_impl { private: typedef typename invoke_result_of_prep::type func; typedef invoke_param_types seq; public: template struct result : invoke_result< Function, mpl::size_t, CBI, func(BOOST_PP_ENUM_PARAMS(N,typename seq::T)) > { }; template static inline typename result::type call(F & f, Sequence & s) { #if N > 0 typename seq::I0 i0 = fusion::begin(s); BOOST_PP_REPEAT_FROM_TO(1,N,M,~) #endif return f( BOOST_PP_ENUM_PARAMS(N,*i) ); } }; #if N > 0 template struct invoke_impl { private: typedef invoke_param_types seq; public: template struct result : invoke_result< Function, mpl::size_t > { }; template static inline typename result::type call(F & f, Sequence & s) { typename seq::I0 i0 = fusion::begin(s); BOOST_PP_REPEAT_FROM_TO(1,N,M,~) return (that_ptr< typename mpl::front< ft::parameter_types >::type >::get(*i0)->*f)(BOOST_PP_ENUM_SHIFTED_PARAMS(N,*i)); } }; #endif #undef M template struct invoke_param_types { #if N > 0 typedef typename result_of::begin::type I0; typedef typename result_of::deref::type T0; #define M(z,i,data) \ typedef typename result_of::next< \ BOOST_PP_CAT(I,BOOST_PP_DEC(i))>::type I##i; \ typedef typename result_of::deref::type T##i; BOOST_PP_REPEAT_FROM_TO(1,N,M,~) #undef M #endif }; #undef N #endif // defined(BOOST_PP_IS_ITERATING) #endif