From c57e8403770c62c438a0663b39a18a17423e7f1c Mon Sep 17 00:00:00 2001 From: Tobias Schwinger Date: Fri, 13 Jul 2007 16:29:45 +0000 Subject: [PATCH] adds const correctness, simplifies code, fixes nullary member function invocation [SVN r38204] --- .../fusion/functional/invocation/invoke.hpp | 147 ++++++++---------- 1 file changed, 62 insertions(+), 85 deletions(-) diff --git a/include/boost/fusion/functional/invocation/invoke.hpp b/include/boost/fusion/functional/invocation/invoke.hpp index 4e156d20..259b83b7 100644 --- a/include/boost/fusion/functional/invocation/invoke.hpp +++ b/include/boost/fusion/functional/invocation/invoke.hpp @@ -22,15 +22,9 @@ #include #include #include -#include -#include -#include -#include #include #include -#include - #include #include #include @@ -39,10 +33,10 @@ #include #include +#include #include #include #include -#include #include @@ -81,45 +75,53 @@ namespace boost { namespace fusion 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; - }; + struct invoke_impl; - template struct invoke_param_types; + 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 - { }; + template + struct invoke_data_member; - // 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 - { }; + template + struct invoke_mem_fn; #define BOOST_PP_FILENAME_1 #define BOOST_PP_ITERATION_LIMITS (0, BOOST_FUSION_INVOKE_MAX_ARITY) #include BOOST_PP_ITERATE() + template + struct invoke_nonmember_builtin + // use same implementation as for function objects but... + : invoke_impl< // ...work around boost::result_of bugs + typename mpl::eval_if< ft::is_function, + boost::add_reference, boost::remove_cv >::type, + Sequence, N, false, RandomAccess > + { }; + + template + struct invoke_impl + : mpl::if_< ft::is_member_function_pointer, + invoke_mem_fn, + invoke_nonmember_builtin + >::type + { }; + + template + struct invoke_impl + : mpl::eval_if< ft::is_member_pointer, + mpl::if_< ft::is_member_function_pointer, + invoke_mem_fn, + invoke_data_member >, + mpl::identity< invoke_nonmember_builtin< + Function,Sequence,1,RandomAccess> > + >::type + { }; + template - struct invoke_data_member + struct invoke_data_member< T C::*, Sequence > { private: @@ -137,37 +139,25 @@ namespace boost { namespace fusion public: - template - struct result - : boost::add_reference - { }; + typedef typename boost::add_reference::type + result_type; - static inline typename result<>::type call(T C::* f, Sequence & s) + static inline 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< + { + typedef typename detail::invoke_impl< typename boost::remove_reference::type, Sequence - >::template result<> - { }; + >::result_type type; + }; } template @@ -199,23 +189,18 @@ namespace boost { namespace fusion /////////////////////////////////////////////////////////////////////////////// #define N BOOST_PP_ITERATION() - template - struct invoke_impl + template + struct invoke_impl { - private: - typedef typename invoke_result_of_prep::type func; public: - template - struct result - : invoke_result< Function, mpl::size_t, CBI, + typedef typename boost::result_of< #define M(z,j,data) typename result_of::at_c::type - func(BOOST_PP_ENUM(N,M,~)) > + Function(BOOST_PP_ENUM(N,M,~)) >::type result_type; #undef M - { }; template - static inline typename result::type + static inline result_type call(F & f, Sequence & s) { #define M(z,j,data) fusion::at_c(s) @@ -223,19 +208,17 @@ namespace boost { namespace fusion } }; + #if N > 0 template - struct invoke_impl + struct invoke_mem_fn { public: - template - struct result - : invoke_result< Function, mpl::size_t > - { }; + typedef typename ft::result_type::type result_type; template - static inline typename result::type + static inline result_type call(F & f, Sequence & s) { return (that_ptr - struct invoke_impl + 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)) > - { }; + typedef typename boost::result_of< + Function(BOOST_PP_ENUM_PARAMS(N,typename seq::T)) + >::type result_type; template - static inline typename result::type + static inline result_type call(F & f, Sequence & s) { #if N > 0 @@ -279,19 +259,16 @@ namespace boost { namespace fusion #if N > 0 template - struct invoke_impl + struct invoke_mem_fn { private: typedef invoke_param_types seq; public: - template - struct result - : invoke_result< Function, mpl::size_t > - { }; + typedef typename ft::result_type::type result_type; template - static inline typename result::type + static inline result_type call(F & f, Sequence & s) { typename seq::I0 i0 = fusion::begin(s);