Chris@16: /*============================================================================= Chris@16: Copyright (c) 2007-2008 Tobias Schwinger Chris@16: Chris@16: Use modification and distribution are subject to the Boost Software Chris@16: License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at Chris@16: http://www.boost.org/LICENSE_1_0.txt). Chris@16: ==============================================================================*/ Chris@16: Chris@16: #ifndef BOOST_FUNCTIONAL_FORWARD_ADAPTER_HPP_INCLUDED Chris@16: # ifndef BOOST_PP_IS_ITERATING Chris@16: Chris@16: # include Chris@16: # include Chris@16: Chris@16: # include Chris@16: # include Chris@16: # include Chris@16: # include Chris@16: # include Chris@16: Chris@16: # include Chris@16: Chris@16: # ifndef BOOST_FUNCTIONAL_FORWARD_ADAPTER_MAX_ARITY Chris@16: # define BOOST_FUNCTIONAL_FORWARD_ADAPTER_MAX_ARITY 6 Chris@16: # elif BOOST_FUNCTIONAL_FORWARD_ADAPTER_MAX_ARITY < 3 Chris@16: # undef BOOST_FUNCTIONAL_FORWARD_ADAPTER_MAX_ARITY Chris@16: # define BOOST_FUNCTIONAL_FORWARD_ADAPTER_MAX_ARITY 3 Chris@16: # endif Chris@16: Chris@16: Chris@16: namespace boost Chris@16: { Chris@16: template< typename Function, int Arity_Or_MinArity = -1, int MaxArity = -1 > Chris@16: class forward_adapter; Chris@16: Chris@16: //----- ---- --- -- - - - - Chris@16: Chris@16: namespace detail Chris@16: { Chris@16: template< class MostDerived, typename Function, typename FunctionConst, Chris@16: int Arity, int MinArity > Chris@16: struct forward_adapter_impl; Chris@16: Chris@16: struct forward_adapter_result Chris@16: { Chris@16: template< typename Sig > struct apply; Chris@16: Chris@16: // Utility metafunction for qualification adjustment on arguments Chris@16: template< typename T > struct q { typedef T const t; }; Chris@16: template< typename T > struct q { typedef T const t; }; Chris@16: template< typename T > struct q { typedef T t; }; Chris@16: Chris@16: // Utility metafunction to choose target function qualification Chris@16: template< typename T > struct c Chris@16: { typedef typename T::target_function_t t; }; Chris@16: template< typename T > struct c Chris@16: { typedef typename T::target_function_t t; }; Chris@16: template< typename T > struct c Chris@16: { typedef typename T::target_function_const_t t; }; Chris@16: template< typename T > struct c Chris@16: { typedef typename T::target_function_const_t t; }; Chris@16: }; Chris@16: } Chris@16: Chris@16: # define BOOST_TMP_MACRO(f,fn,fc) \ Chris@16: boost::detail::forward_adapter_impl< \ Chris@16: forward_adapter, fn, fc, \ Chris@16: (MaxArity!=-1? MaxArity :Arity_Or_MinArity!=-1? Arity_Or_MinArity \ Chris@16: :BOOST_FUNCTIONAL_FORWARD_ADAPTER_MAX_ARITY), \ Chris@16: (Arity_Or_MinArity!=-1? Arity_Or_MinArity : 0) > Chris@16: Chris@16: template< typename Function, int Arity_Or_MinArity, int MaxArity > Chris@16: class forward_adapter Chris@16: : public BOOST_TMP_MACRO(Function,Function,Function const) Chris@16: , private Function Chris@16: { Chris@16: public: Chris@16: forward_adapter(Function const& f = Function()) Chris@16: : Function(f) Chris@16: { } Chris@16: Chris@16: typedef Function target_function_t; Chris@16: typedef Function const target_function_const_t; Chris@16: Chris@16: Function & target_function() { return *this; } Chris@16: Function const & target_function() const { return *this; } Chris@16: Chris@16: template< typename Sig > struct result Chris@16: : detail::forward_adapter_result::template apply Chris@16: { }; Chris@16: Chris@16: using BOOST_TMP_MACRO(Function,Function, Function const)::operator(); Chris@16: }; Chris@16: template< typename Function, int Arity_Or_MinArity, int MaxArity > Chris@16: class forward_adapter< Function const, Arity_Or_MinArity, MaxArity > Chris@16: : public BOOST_TMP_MACRO(Function const, Function const, Function const) Chris@16: , private Function Chris@16: { Chris@16: public: Chris@16: forward_adapter(Function const& f = Function()) Chris@16: : Function(f) Chris@16: { } Chris@16: Chris@16: typedef Function const target_function_t; Chris@16: typedef Function const target_function_const_t; Chris@16: Chris@16: Function const & target_function() const { return *this; } Chris@16: Chris@16: template< typename Sig > struct result Chris@16: : detail::forward_adapter_result::template apply Chris@16: { }; Chris@16: Chris@16: using BOOST_TMP_MACRO(Function const,Function const, Function const) Chris@16: ::operator(); Chris@16: }; Chris@16: template< typename Function, int Arity_Or_MinArity, int MaxArity > Chris@16: class forward_adapter< Function &, Arity_Or_MinArity, MaxArity > Chris@16: : public BOOST_TMP_MACRO(Function&, Function, Function) Chris@16: { Chris@16: Function& ref_function; Chris@16: public: Chris@16: forward_adapter(Function& f) Chris@16: : ref_function(f) Chris@16: { } Chris@16: Chris@16: typedef Function target_function_t; Chris@16: typedef Function target_function_const_t; Chris@16: Chris@16: Function & target_function() const { return this->ref_function; } Chris@16: Chris@16: template< typename Sig > struct result Chris@16: : detail::forward_adapter_result::template apply Chris@16: { }; Chris@16: Chris@16: using BOOST_TMP_MACRO(Function&, Function, Function)::operator(); Chris@16: }; Chris@16: Chris@16: #undef BOOST_TMP_MACRO Chris@16: Chris@16: namespace detail Chris@16: { Chris@16: template< class Self > Chris@16: struct forward_adapter_result::apply< Self() > Chris@16: : boost::result_of< BOOST_DEDUCED_TYPENAME c::t() > Chris@16: { }; Chris@16: Chris@16: template< class MD, class F, class FC > Chris@16: struct forward_adapter_impl Chris@16: { Chris@16: inline typename boost::result_of< FC() >::type Chris@16: operator()() const Chris@16: { Chris@16: return static_cast(this)->target_function()(); Chris@16: } Chris@16: Chris@16: inline typename boost::result_of< F() >::type Chris@16: operator()() Chris@16: { Chris@16: return static_cast(this)->target_function()(); Chris@16: } Chris@16: Chris@16: // closing brace gets generated by preprocessing code, below Chris@16: Chris@16: # define BOOST_TMP_MACRO(tpl_params,arg_types,params,args) \ Chris@16: template< tpl_params > \ Chris@16: inline typename boost::result_of< FC(arg_types) >::type \ Chris@16: operator()(params) const \ Chris@16: { \ Chris@16: return static_cast(this)->target_function()(args); \ Chris@16: } \ Chris@16: template< tpl_params > \ Chris@16: inline typename boost::result_of< F(arg_types)>::type \ Chris@16: operator()(params) \ Chris@16: { \ Chris@16: return static_cast(this)->target_function()(args); \ Chris@16: } Chris@16: Chris@16: # // This is the total number of iterations we need Chris@16: # define count ((1 << BOOST_FUNCTIONAL_FORWARD_ADAPTER_MAX_ARITY+1)-2) Chris@16: Chris@16: # // Chain file iteration to virtually one loop Chris@16: # if BOOST_FUNCTIONAL_FORWARD_ADAPTER_MAX_ARITY <= 7 Chris@16: # define limit1 count Chris@16: # define limit2 0 Chris@16: # define limit3 0 Chris@16: # else Chris@16: # if BOOST_FUNCTIONAL_FORWARD_ADAPTER_MAX_ARITY <= 15 Chris@16: # define limit1 (count >> 8) Chris@16: # define limit2 255 Chris@16: # define limit3 0 Chris@16: # else Chris@16: # define limit1 (count >> 16) Chris@16: # define limit2 255 Chris@16: # define limit3 255 Chris@16: # endif Chris@16: # endif Chris@16: Chris@16: # define N 0 Chris@16: Chris@16: # define BOOST_PP_FILENAME_1 Chris@16: # define BOOST_PP_ITERATION_LIMITS (0,limit1) Chris@16: # include BOOST_PP_ITERATE() Chris@16: Chris@16: # undef N Chris@16: # undef limit3 Chris@16: # undef limit2 Chris@16: # undef limit1 Chris@16: # undef count Chris@16: # undef BOOST_TMP_MACRO Chris@16: Chris@16: }; Chris@16: Chris@16: } // namespace detail Chris@16: Chris@16: template Chris@16: struct result_of const ()> Chris@16: : boost::detail::forward_adapter_result::template apply< Chris@16: boost::forward_adapter const () > Chris@16: { }; Chris@16: template Chris@16: struct result_of()> Chris@16: : boost::detail::forward_adapter_result::template apply< Chris@16: boost::forward_adapter() > Chris@16: { }; Chris@16: template Chris@16: struct result_of const& ()> Chris@16: : boost::detail::forward_adapter_result::template apply< Chris@16: boost::forward_adapter const () > Chris@16: { }; Chris@16: template Chris@16: struct result_of& ()> Chris@16: : boost::detail::forward_adapter_result::template apply< Chris@16: boost::forward_adapter() > Chris@16: { }; Chris@16: } Chris@16: Chris@16: # define BOOST_FUNCTIONAL_FORWARD_ADAPTER_HPP_INCLUDED Chris@16: Chris@16: # elif BOOST_PP_ITERATION_DEPTH() == 1 && limit2 Chris@16: # define BOOST_PP_FILENAME_2 Chris@16: # define BOOST_PP_ITERATION_LIMITS (0,limit2) Chris@16: # include BOOST_PP_ITERATE() Chris@16: # elif BOOST_PP_ITERATION_DEPTH() == 2 && limit3 Chris@16: # define BOOST_PP_FILENAME_3 Chris@16: # define BOOST_PP_ITERATION_LIMITS (0,limit3) Chris@16: # include BOOST_PP_ITERATE() Chris@16: Chris@16: # else Chris@16: Chris@16: # // I is the loop counter Chris@16: # if limit2 && limit3 Chris@16: # define I (BOOST_PP_ITERATION_1 << 16 | BOOST_PP_ITERATION_2 << 8 | \ Chris@16: BOOST_PP_ITERATION_3) Chris@16: # elif limit2 Chris@16: # define I (BOOST_PP_ITERATION_1 << 8 | BOOST_PP_ITERATION_2) Chris@16: # else Chris@16: # define I BOOST_PP_ITERATION_1 Chris@16: # endif Chris@16: Chris@16: # if I < count Chris@16: Chris@16: # // Done for this arity? Increment N Chris@16: # if (I+2 >> N+1) Chris@16: # if N == 0 Chris@16: # undef N Chris@16: # define N 1 Chris@16: # elif N == 1 Chris@16: # undef N Chris@16: # define N 2 Chris@16: # elif N == 2 Chris@16: # undef N Chris@16: # define N 3 Chris@16: # elif N == 3 Chris@16: # undef N Chris@16: # define N 4 Chris@16: # elif N == 4 Chris@16: # undef N Chris@16: # define N 5 Chris@16: # elif N == 5 Chris@16: # undef N Chris@16: # define N 6 Chris@16: # elif N == 6 Chris@16: # undef N Chris@16: # define N 7 Chris@16: # elif N == 7 Chris@16: # undef N Chris@16: # define N 8 Chris@16: # elif N == 8 Chris@16: # undef N Chris@16: # define N 9 Chris@16: # elif N == 9 Chris@16: # undef N Chris@16: # define N 10 Chris@16: # elif N == 10 Chris@16: # undef N Chris@16: # define N 11 Chris@16: # elif N == 11 Chris@16: # undef N Chris@16: # define N 12 Chris@16: # elif N == 12 Chris@16: # undef N Chris@16: # define N 13 Chris@16: # elif N == 13 Chris@16: # undef N Chris@16: # define N 14 Chris@16: # elif N == 14 Chris@16: # undef N Chris@16: # define N 15 Chris@16: # elif N == 15 Chris@16: # undef N Chris@16: # define N 16 Chris@16: # endif Chris@16: Chris@16: }; Chris@16: Chris@16: template< class Self, BOOST_PP_ENUM_PARAMS(N,typename T) > Chris@16: struct forward_adapter_result::apply< Self(BOOST_PP_ENUM_PARAMS(N,T)) > Chris@16: : boost::result_of< Chris@16: BOOST_DEDUCED_TYPENAME c::t(BOOST_PP_ENUM_BINARY_PARAMS(N, Chris@16: typename q::t& BOOST_PP_INTERCEPT)) > Chris@16: { }; Chris@16: Chris@16: template< class MD, class F, class FC > Chris@16: struct forward_adapter_impl Chris@16: { Chris@16: template< BOOST_PP_ENUM_PARAMS(N,typename T) > Chris@16: inline typename boost::result_of< F( Chris@16: BOOST_PP_ENUM_BINARY_PARAMS(N,T,& BOOST_PP_INTERCEPT)) >::type Chris@16: operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,T,& BOOST_PP_INTERCEPT)); Chris@16: }; Chris@16: Chris@16: template< class MD, class F, class FC, int MinArity > Chris@16: struct forward_adapter_impl Chris@16: : forward_adapter_impl Chris@16: { Chris@16: using forward_adapter_impl::operator(); Chris@16: Chris@16: # endif Chris@16: Chris@16: # // Zero based count for each arity would be I-(1< Chris@16: inline typename boost::result_of< FC(BOOST_PP_ENUM_PARAMS(N,PT)) Chris@16: >::type Chris@16: operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,PT,a)) const Chris@16: { Chris@16: return static_cast(this) Chris@16: ->target_function()(BOOST_PP_ENUM_PARAMS(N,a)); Chris@16: } Chris@16: template< BOOST_PP_ENUM_PARAMS(N,typename T) > Chris@16: inline typename boost::result_of< F(BOOST_PP_ENUM_PARAMS(N,PT)) Chris@16: >::type Chris@16: operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,PT,a)) Chris@16: { Chris@16: return static_cast(this) Chris@16: ->target_function()(BOOST_PP_ENUM_PARAMS(N,a)); Chris@16: } Chris@16: # else Chris@16: BOOST_TMP_MACRO(BOOST_PP_ENUM_PARAMS(N,typename T), Chris@16: BOOST_PP_ENUM_PARAMS(N,PT), BOOST_PP_ENUM_BINARY_PARAMS(N,PT,a), Chris@16: BOOST_PP_ENUM_PARAMS(N,a) ) Chris@16: // ...generates uglier code but is faster - it caches ENUM_* Chris@16: # endif Chris@16: Chris@16: # undef PT0 Chris@16: # undef PT1 Chris@16: # undef PT2 Chris@16: # undef PT3 Chris@16: # undef PT4 Chris@16: # undef PT5 Chris@16: # undef PT6 Chris@16: # undef PT7 Chris@16: # undef PT8 Chris@16: # undef PT9 Chris@16: # undef PT10 Chris@16: # undef PT11 Chris@16: # undef PT12 Chris@16: # undef PT13 Chris@16: # undef PT14 Chris@16: # undef PT15 Chris@16: Chris@16: # endif // I < count Chris@16: Chris@16: # undef I Chris@16: # endif // defined(BOOST_PP_IS_ITERATING) Chris@16: Chris@16: #endif // include guard Chris@16: