diff options
Diffstat (limited to 'boost/functional/lightweight_forward_adapter.hpp')
-rw-r--r-- | boost/functional/lightweight_forward_adapter.hpp | 259 |
1 files changed, 259 insertions, 0 deletions
diff --git a/boost/functional/lightweight_forward_adapter.hpp b/boost/functional/lightweight_forward_adapter.hpp new file mode 100644 index 0000000000..637aa9e19c --- /dev/null +++ b/boost/functional/lightweight_forward_adapter.hpp @@ -0,0 +1,259 @@ +/*============================================================================= + Copyright (c) 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). +==============================================================================*/ + +#ifndef BOOST_FUNCTIONAL_LIGHTWEIGHT_FORWARD_ADAPTER_HPP_INCLUDED +# ifndef BOOST_PP_IS_ITERATING + +# include <boost/config.hpp> +# include <boost/detail/workaround.hpp> + +# include <boost/preprocessor/cat.hpp> +# include <boost/preprocessor/iteration/iterate.hpp> +# include <boost/preprocessor/repetition/enum.hpp> +# include <boost/preprocessor/repetition/enum_params.hpp> +# include <boost/preprocessor/repetition/enum_binary_params.hpp> +# include <boost/preprocessor/facilities/intercept.hpp> + +# include <boost/utility/result_of.hpp> +# include <boost/ref.hpp> + +# ifndef BOOST_FUNCTIONAL_LIGHTWEIGHT_FORWARD_ADAPTER_MAX_ARITY +# define BOOST_FUNCTIONAL_LIGHTWEIGHT_FORWARD_ADAPTER_MAX_ARITY 10 +# elif BOOST_FUNCTIONAL_FORDWARD_ADAPTER_MAX_ARITY < 3 +# undef BOOST_FUNCTIONAL_LIGHTWEIGHT_FORWARD_ADAPTER_MAX_ARITY +# define BOOST_FUNCTIONAL_LIGHTWEIGHT_FORWARD_ADAPTER_MAX_ARITY 3 +# endif + +namespace boost +{ + template< typename Function, int Arity_Or_MinArity = -1, int MaxArity = -1 > + class lightweight_forward_adapter; + + //----- ---- --- -- - - - - + + namespace detail + { + template< class MostDerived, typename Function, typename FunctionConst, + int Arity, int MinArity > + struct lightweight_forward_adapter_impl; + + struct lightweight_forward_adapter_result + { + template< typename Sig > struct apply; + + // Utility metafunction for argument transform + template< typename T > struct x { typedef T const& t; }; + template< typename T > struct x< boost::reference_wrapper<T> > + { typedef T& t; }; + template< typename T > struct x<T&> : x<T> { }; + template< typename T > struct x<T const&> : x<T> { }; + template< typename T > struct x<T const> : x<T> { }; + + // Utility metafunction to choose target function qualification + template< typename T > struct c + { typedef typename T::target_function_t t; }; + template< typename T > struct c<T& > + { typedef typename T::target_function_t t; }; + template< typename T > struct c<T const > + { typedef typename T::target_function_const_t t; }; + template< typename T > struct c<T const&> + { typedef typename T::target_function_const_t t; }; + }; + } + +# define BOOST_TMP_MACRO(f,fn,fc) \ + boost::detail::lightweight_forward_adapter_impl< \ + lightweight_forward_adapter<f,Arity_Or_MinArity,MaxArity>, fn, fc, \ + (MaxArity!=-1? MaxArity :Arity_Or_MinArity!=-1? Arity_Or_MinArity \ + :BOOST_FUNCTIONAL_LIGHTWEIGHT_FORWARD_ADAPTER_MAX_ARITY), \ + (Arity_Or_MinArity!=-1? Arity_Or_MinArity : 0) > + + template< typename Function, int Arity_Or_MinArity, int MaxArity > + class lightweight_forward_adapter + : public BOOST_TMP_MACRO(Function,Function,Function const) + , private Function + { + public: + lightweight_forward_adapter(Function const& f = Function()) + : Function(f) + { } + + typedef Function target_function_t; + typedef Function const target_function_const_t; + + Function & target_function() { return *this; } + Function const & target_function() const { return *this; } + + template< typename Sig > struct result + : detail::lightweight_forward_adapter_result::template apply<Sig> + { }; + + using BOOST_TMP_MACRO(Function,Function, Function const)::operator(); + }; + template< typename Function, int Arity_Or_MinArity, int MaxArity > + class lightweight_forward_adapter< Function const, Arity_Or_MinArity, + MaxArity > + : public BOOST_TMP_MACRO(Function const, Function const, Function const) + , private Function + { + public: + lightweight_forward_adapter(Function const& f = Function()) + : Function(f) + { } + + typedef Function const target_function_t; + typedef Function const target_function_const_t; + + Function const & target_function() const { return *this; } + + template< typename Sig > struct result + : detail::lightweight_forward_adapter_result::template apply<Sig> + { }; + + using BOOST_TMP_MACRO(Function const,Function const, Function const) + ::operator(); + }; + template< typename Function, int Arity_Or_MinArity, int MaxArity > + class lightweight_forward_adapter< Function &, Arity_Or_MinArity, MaxArity > + : public BOOST_TMP_MACRO(Function&, Function, Function) + { + Function& ref_function; + public: + lightweight_forward_adapter(Function& f) + : ref_function(f) + { } + + typedef Function target_function_t; + typedef Function target_function_const_t; + + Function & target_function() const { return this->ref_function; } + + template< typename Sig > struct result + : detail::lightweight_forward_adapter_result::template apply<Sig> + { }; + + using BOOST_TMP_MACRO(Function&, Function, Function)::operator(); + }; + + #undef BOOST_TMP_MACRO + + namespace detail + { + template< class Self > + struct lightweight_forward_adapter_result::apply< Self() > + : boost::result_of< BOOST_DEDUCED_TYPENAME c<Self>::t() > + { }; + + template< class MD, class F, class FC > + struct lightweight_forward_adapter_impl<MD,F,FC,0,0> + : lightweight_forward_adapter_result + { + inline typename boost::result_of< FC() >::type + operator()() const + { + return static_cast<MD const*>(this)->target_function()(); + } + + inline typename boost::result_of< F() >::type + operator()() + { + return static_cast<MD*>(this)->target_function()(); + } + }; + +# define BOOST_PP_FILENAME_1 \ + <boost/functional/lightweight_forward_adapter.hpp> +# define BOOST_PP_ITERATION_LIMITS \ + (1,BOOST_FUNCTIONAL_LIGHTWEIGHT_FORWARD_ADAPTER_MAX_ARITY) +# include BOOST_PP_ITERATE() + + } // namespace detail + + template<class F, int A0, int A1> + struct result_of<boost::lightweight_forward_adapter<F,A0,A1> const ()> + : boost::detail::lightweight_forward_adapter_result::template apply< + boost::lightweight_forward_adapter<F,A0,A1> const () > + { }; + template<class F, int A0, int A1> + struct result_of<boost::lightweight_forward_adapter<F,A0,A1>()> + : boost::detail::lightweight_forward_adapter_result::template apply< + boost::lightweight_forward_adapter<F,A0,A1>() > + { }; + template<class F, int A0, int A1> + struct result_of<boost::lightweight_forward_adapter<F,A0,A1> const& ()> + : boost::detail::lightweight_forward_adapter_result::template apply< + boost::lightweight_forward_adapter<F,A0,A1> const () > + { }; + template<class F, int A0, int A1> + struct result_of<boost::lightweight_forward_adapter<F,A0,A1>& ()> + : boost::detail::lightweight_forward_adapter_result::template apply< + boost::lightweight_forward_adapter<F,A0,A1>() > + { }; +} + +# define BOOST_FUNCTIONAL_LIGHTWEIGHT_FORWARD_ADAPTER_HPP_INCLUDED + +# else // defined(BOOST_PP_IS_ITERATING) +# define N BOOST_PP_ITERATION() + + template< class Self, BOOST_PP_ENUM_PARAMS(N,typename T) > + struct lightweight_forward_adapter_result::apply< + Self (BOOST_PP_ENUM_PARAMS(N,T)) > + : boost::result_of< + BOOST_DEDUCED_TYPENAME c<Self>::t (BOOST_PP_ENUM_BINARY_PARAMS(N, + typename x<T,>::t BOOST_PP_INTERCEPT)) > + { }; + + template< class MD, class F, class FC > + struct lightweight_forward_adapter_impl<MD,F,FC,BOOST_PP_DEC(N),N> + : lightweight_forward_adapter_result + { + template< BOOST_PP_ENUM_PARAMS(N,typename T) > + inline typename boost::result_of< F(BOOST_PP_ENUM_BINARY_PARAMS(N, + T,const& BOOST_PP_INTERCEPT)) >::type + operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,T,& BOOST_PP_INTERCEPT)); + }; + + template< class MD, class F, class FC, int MinArity > + struct lightweight_forward_adapter_impl<MD,F,FC,N,MinArity> + : lightweight_forward_adapter_impl<MD,F,FC,BOOST_PP_DEC(N),MinArity> + { + using lightweight_forward_adapter_impl<MD,F,FC,BOOST_PP_DEC(N), + MinArity>::operator(); + +# define M(z,i,d) \ + static_cast<typename d::template x<T##i>::t>(a##i) + + template< BOOST_PP_ENUM_PARAMS(N,typename T) > + inline typename lightweight_forward_adapter_result::template apply< + MD const (BOOST_PP_ENUM_BINARY_PARAMS(N, + T,const& BOOST_PP_INTERCEPT)) >::type + operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,T,const& a)) const + { + typedef lightweight_forward_adapter_result _; + return static_cast<MD const*>(this)->target_function()( + BOOST_PP_ENUM(N,M,_)); + } + template< BOOST_PP_ENUM_PARAMS(N,typename T) > + inline typename lightweight_forward_adapter_result::template apply< + MD (BOOST_PP_ENUM_BINARY_PARAMS(N, + T,const& BOOST_PP_INTERCEPT)) >::type + operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,T,const& a)) + { + typedef lightweight_forward_adapter_result _; + return static_cast<MD*>(this)->target_function()( + BOOST_PP_ENUM(N,M,_)); + } +# undef M + }; + +# undef N +# endif // defined(BOOST_PP_IS_ITERATING) + +#endif // include guard + |