Index: unfused.hpp =================================================================== --- unfused.hpp (revision 64741) +++ unfused.hpp (working copy) @@ -31,58 +31,47 @@ namespace boost { namespace fusion { - template - class unfused; + template class Result, bool AllowNullary = true> + class unfuse_interface; //----- ---- --- -- - - - - - template - class unfused - : public unfused + template class Result> + class unfuse_interface + : public unfuse_interface { - typedef typename detail::qf_c::type function_c; - typedef typename detail::qf::type function; - typedef typename detail::call_param::type func_const_fwd_t; public: + using unfuse_interface::operator(); - using unfused::operator(); + template + struct result + : unfuse_interface::result{}; - inline explicit unfused(func_const_fwd_t f = function()) - : unfused(f) - { } + template + struct result + : Result &)>{}; - typedef typename boost::result_of< - function_c(fusion::vector0<> &) >::type call_const_0_result; + template + struct result + : Result &)>{}; - inline call_const_0_result operator()() const + inline typename result::type operator()() const { fusion::vector0<> arg; - return this->fnc_transformed(arg); + return static_cast(this)->call(arg); } - typedef typename boost::result_of< - function(fusion::vector0<> &) >::type call_0_result; - - inline call_0_result operator()() + inline typename result::type operator()() { fusion::vector0<> arg; - return this->fnc_transformed(arg); + return static_cast(this)->call(arg); } }; - template class unfused + template class Result> + class unfuse_interface { - protected: - Function fnc_transformed; - typedef typename detail::qf_c::type function_c; - typedef typename detail::qf::type function; - typedef typename detail::call_param::type func_const_fwd_t; public: - - inline explicit unfused(func_const_fwd_t f = function()) - : fnc_transformed(f) - { } - template struct result; @@ -91,27 +80,85 @@ #define BOOST_PP_ITERATION_LIMITS \ (1,BOOST_FUSION_UNFUSED_MAX_ARITY) #include BOOST_PP_ITERATE() + + //perfect forwarding for up to 2 arguments: + template + inline typename result< Derived const (T0 const &,T1 &) >::type + operator()(T0 const &a0,T1 &a1) const{ + fusion::vector2 arg(a0,a1); + return static_cast(this)->call(arg); + } + template + inline typename result< Derived const (T0 const &,T1 &) >::type + operator()(T0 const &a0,T1 &a1){ + fusion::vector2 arg(a0,a1); + return static_cast(this)->call(arg); + } + template + inline typename result< Derived const (T0 &,T1 const &) >::type + operator()(T0 &a0,T1 const &a1) const{ + fusion::vector2 arg(a0,a1); + return static_cast(this)->call(arg); + } + template + inline typename result< Derived const (T0 &,T1 const &) >::type + operator()(T0 &a0,T1 const &a1){ + fusion::vector2 arg(a0,a1); + return static_cast(this)->call(arg); + } }; + + namespace detail{ + + template + struct fused_result{ + typedef typename detail::qf_c::type function_c; + typedef typename detail::qf::type function; + template + struct result; + template + struct result + : boost::result_of< function_c (Seq &) >{}; + template + struct result + : boost::result_of< function (Seq &) >{}; + }; + } + + template + class unfused + : public unfuse_interface< + unfused, + typename detail::fused_result::template result, + AllowNullary>{ + typedef typename detail::call_param::type func_const_fwd_t; + public: + inline explicit unfused(func_const_fwd_t f = function()) + : fnc_transformed(f) + { } + private: + Function fnc_transformed; + template class,bool> + friend class unfuse_interface; + template + typename detail::fused_result::template result::type + call(Seq &seq){ + return fnc_transformed(seq); + } + template + typename detail::fused_result::template result::type + call(Seq &seq) const{ + return fnc_transformed(seq); + } + + }; + }} #if defined (BOOST_MSVC) # pragma warning(pop) #endif -namespace boost -{ - template - struct result_of< boost::fusion::unfused const () > - { - typedef typename boost::fusion::unfused::call_const_0_result type; - }; - template - struct result_of< boost::fusion::unfused() > - { - typedef typename boost::fusion::unfused::call_0_result type; - }; -} - #define BOOST_FUSION_FUNCTIONAL_ADAPTER_UNFUSED_HPP_INCLUDED #else // defined(BOOST_PP_IS_ITERATING) //////////////////////////////////////////////////////////////////////////////// @@ -122,40 +169,55 @@ #define N BOOST_PP_ITERATION() template - struct result< Self const (BOOST_PP_ENUM_PARAMS(N,T)) > - : boost::result_of< function_c( + struct result< Self (BOOST_PP_ENUM_PARAMS(N,T)) > + : Result< Self ( BOOST_PP_CAT(fusion::vector,N)< BOOST_PP_ENUM_BINARY_PARAMS(N, typename detail::mref::type BOOST_PP_INTERCEPT) > & )> { }; - template - struct result< Self(BOOST_PP_ENUM_PARAMS(N,T)) > - : boost::result_of< function( - BOOST_PP_CAT(fusion::vector,N)< BOOST_PP_ENUM_BINARY_PARAMS(N, - typename detail::mref::type BOOST_PP_INTERCEPT) > & )> - { }; - + //const interface, non-const arguments template - inline typename boost::result_of & )>::type + inline typename result< Derived const (BOOST_PP_ENUM_BINARY_PARAMS(N,T,& BOOST_PP_INTERCEPT)) >::type operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,T,& a)) const { BOOST_PP_CAT(fusion::vector,N)< BOOST_PP_ENUM_BINARY_PARAMS(N,T,& BOOST_PP_INTERCEPT) > - arg(BOOST_PP_ENUM_PARAMS(N,a)); - return this->fnc_transformed(arg); + arg(BOOST_PP_ENUM_PARAMS(N,a)); + return static_cast(this)->call(arg); } + //non-const interface, non-const arguments template - inline typename boost::result_of & )>::type + inline typename result< Derived (BOOST_PP_ENUM_BINARY_PARAMS(N,T,& BOOST_PP_INTERCEPT)) >::type operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,T,& a)) { BOOST_PP_CAT(fusion::vector,N)< BOOST_PP_ENUM_BINARY_PARAMS(N,T,& BOOST_PP_INTERCEPT) > arg(BOOST_PP_ENUM_PARAMS(N,a)); - return this->fnc_transformed(arg); + return static_cast(this)->call(arg); } + + //const interface, const arguments + template + inline typename result< Derived const (BOOST_PP_ENUM_BINARY_PARAMS(N,T,const & BOOST_PP_INTERCEPT)) >::type + operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,T,const & a)) const + { + BOOST_PP_CAT(fusion::vector,N)< + BOOST_PP_ENUM_BINARY_PARAMS(N,T,const & BOOST_PP_INTERCEPT) > + arg(BOOST_PP_ENUM_PARAMS(N,a)); + return static_cast(this)->call(arg); + } + + //non-const interface, const arguments + template + inline typename result< Derived (BOOST_PP_ENUM_BINARY_PARAMS(N,T,const & BOOST_PP_INTERCEPT)) >::type + operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,T,const & a)) + { + BOOST_PP_CAT(fusion::vector,N)< + BOOST_PP_ENUM_BINARY_PARAMS(N,T,const & BOOST_PP_INTERCEPT) > + arg(BOOST_PP_ENUM_PARAMS(N,a)); + return static_cast(this)->call(arg); + } #undef N #endif // defined(BOOST_PP_IS_ITERATING) #endif