260 lines
10 KiB
C++
260 lines
10 KiB
C++
/*=============================================================================
|
|
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
|
|
|