Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 09:35:55

0001 /*=============================================================================
0002     Copyright (c) 2007 Tobias Schwinger
0003   
0004     Use modification and distribution are subject to the Boost Software 
0005     License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
0006     http://www.boost.org/LICENSE_1_0.txt).
0007 ==============================================================================*/
0008 
0009 #ifndef BOOST_FUNCTIONAL_LIGHTWEIGHT_FORWARD_ADAPTER_HPP_INCLUDED
0010 #   ifndef BOOST_PP_IS_ITERATING
0011 
0012 #   include <boost/config.hpp>
0013 #   include <boost/config/workaround.hpp>
0014 
0015 #   include <boost/preprocessor/cat.hpp>
0016 #   include <boost/preprocessor/iteration/iterate.hpp>
0017 #   include <boost/preprocessor/repetition/enum.hpp>
0018 #   include <boost/preprocessor/repetition/enum_params.hpp>
0019 #   include <boost/preprocessor/repetition/enum_binary_params.hpp>
0020 #   include <boost/preprocessor/facilities/intercept.hpp>
0021 
0022 #   include <boost/utility/result_of.hpp>
0023 #   include <boost/ref.hpp>
0024 
0025 #   ifndef BOOST_FUNCTIONAL_LIGHTWEIGHT_FORWARD_ADAPTER_MAX_ARITY
0026 #     define BOOST_FUNCTIONAL_LIGHTWEIGHT_FORWARD_ADAPTER_MAX_ARITY 10
0027 #   elif BOOST_FUNCTIONAL_FORDWARD_ADAPTER_MAX_ARITY < 3
0028 #     undef  BOOST_FUNCTIONAL_LIGHTWEIGHT_FORWARD_ADAPTER_MAX_ARITY
0029 #     define BOOST_FUNCTIONAL_LIGHTWEIGHT_FORWARD_ADAPTER_MAX_ARITY 3
0030 #   endif
0031 
0032 namespace boost 
0033 {
0034     template< typename Function, int Arity_Or_MinArity = -1, int MaxArity = -1 >
0035     class lightweight_forward_adapter;
0036 
0037     //----- ---- --- -- - -  -   -
0038 
0039     namespace detail
0040     {
0041         template< class MostDerived, typename Function, typename FunctionConst, 
0042             int Arity, int MinArity >
0043         struct lightweight_forward_adapter_impl;
0044 
0045         struct lightweight_forward_adapter_result
0046         {
0047             template< typename Sig > struct apply;
0048 
0049             // Utility metafunction for argument transform
0050             template< typename T > struct x  { typedef T const& t; };
0051             template< typename T > struct x< boost::reference_wrapper<T> >
0052             { typedef T& t; };
0053             template< typename T > struct x<T&>       : x<T> { };
0054             template< typename T > struct x<T const&> : x<T> { };
0055             template< typename T > struct x<T const>  : x<T> { };
0056 
0057             // Utility metafunction to choose target function qualification
0058             template< typename T > struct c
0059             { typedef typename T::target_function_t t; };
0060             template< typename T > struct c<T&      >
0061             { typedef typename T::target_function_t t; };
0062             template< typename T > struct c<T const >
0063             { typedef typename T::target_function_const_t t; };
0064             template< typename T > struct c<T const&>
0065             { typedef typename T::target_function_const_t t; };
0066         };
0067     }
0068 
0069 #   define BOOST_TMP_MACRO(f,fn,fc) \
0070         boost::detail::lightweight_forward_adapter_impl< \
0071             lightweight_forward_adapter<f,Arity_Or_MinArity,MaxArity>, fn, fc, \
0072             (MaxArity!=-1? MaxArity :Arity_Or_MinArity!=-1? Arity_Or_MinArity \
0073                 :BOOST_FUNCTIONAL_LIGHTWEIGHT_FORWARD_ADAPTER_MAX_ARITY), \
0074             (Arity_Or_MinArity!=-1? Arity_Or_MinArity : 0) >
0075 
0076     template< typename Function, int Arity_Or_MinArity, int MaxArity >
0077     class lightweight_forward_adapter
0078         : public BOOST_TMP_MACRO(Function,Function,Function const)
0079         , private Function
0080     {
0081       public:
0082         lightweight_forward_adapter(Function const& f = Function()) 
0083           : Function(f) 
0084         { }
0085 
0086         typedef Function        target_function_t;
0087         typedef Function const  target_function_const_t;
0088 
0089         Function       & target_function()       { return *this; }
0090         Function const & target_function() const { return *this; }
0091 
0092         template< typename Sig > struct result
0093             : detail::lightweight_forward_adapter_result::template apply<Sig>
0094         { };
0095 
0096         using BOOST_TMP_MACRO(Function,Function, Function const)::operator();
0097     };
0098     template< typename Function, int Arity_Or_MinArity, int MaxArity >
0099     class lightweight_forward_adapter< Function const, Arity_Or_MinArity, 
0100         MaxArity >
0101         : public BOOST_TMP_MACRO(Function const, Function const, Function const)
0102         , private Function
0103     {
0104       public:
0105         lightweight_forward_adapter(Function const& f = Function())
0106           : Function(f) 
0107         { }
0108 
0109         typedef Function const target_function_t;
0110         typedef Function const target_function_const_t;
0111 
0112         Function const & target_function() const { return *this; }
0113 
0114         template< typename Sig > struct result
0115             : detail::lightweight_forward_adapter_result::template apply<Sig>
0116         { };
0117 
0118         using BOOST_TMP_MACRO(Function const,Function const, Function const)
0119             ::operator();
0120     };
0121     template< typename Function, int Arity_Or_MinArity, int MaxArity >
0122     class lightweight_forward_adapter< Function &, Arity_Or_MinArity, MaxArity >
0123         : public BOOST_TMP_MACRO(Function&, Function, Function)
0124     {
0125         Function& ref_function;
0126       public:
0127         lightweight_forward_adapter(Function& f)
0128           : ref_function(f) 
0129         { }
0130 
0131         typedef Function target_function_t;
0132         typedef Function target_function_const_t;
0133 
0134         Function & target_function() const { return this->ref_function; }
0135 
0136         template< typename Sig > struct result
0137             : detail::lightweight_forward_adapter_result::template apply<Sig>
0138         { };
0139 
0140         using BOOST_TMP_MACRO(Function&, Function, Function)::operator();
0141     }; 
0142 
0143     #undef BOOST_TMP_MACRO
0144 
0145     namespace detail
0146     {
0147         template< class Self >
0148         struct lightweight_forward_adapter_result::apply< Self() >
0149             : boost::result_of< BOOST_DEDUCED_TYPENAME c<Self>::t() >
0150         { };
0151 
0152         // When operator() doesn't have any parameters, it can't
0153         // be templatized and can't use SFINAE, so intead use class
0154         // template parameter SFINAE to decide whether to instantiate it.
0155 
0156         template <typename T, typename R = void>
0157         struct lightweight_forward_adapter_sfinae
0158         {
0159             typedef T type;
0160         };
0161 
0162         // This is the fallback for when there isn't an operator()(),
0163         // need to create an operator() that will never instantiate
0164         // so that using parent::operator() will work okay.
0165         template< class MD, class F, class FC, class Enable = void>
0166         struct lightweight_forward_adapter_impl_zero
0167             : lightweight_forward_adapter_result
0168         {
0169             template <typename T> struct never_instantiate {};
0170             template <typename T>
0171             typename never_instantiate<T>::type operator()(T) const {}
0172         };
0173 
0174         template< class MD, class F, class FC>
0175         struct lightweight_forward_adapter_impl_zero<MD, F, FC,
0176             typename lightweight_forward_adapter_sfinae<typename boost::result_of< FC() >::type>::type>
0177             : lightweight_forward_adapter_result
0178         {
0179             inline typename boost::result_of< FC() >::type
0180             operator()() const
0181             {
0182                 return static_cast<MD const*>(this)->target_function()();
0183             }
0184 
0185             inline typename boost::result_of< F() >::type
0186             operator()()
0187             {
0188                 return static_cast<MD*>(this)->target_function()();
0189             }
0190         };
0191 
0192         template< class MD, class F, class FC >
0193         struct lightweight_forward_adapter_impl<MD,F,FC,0,0>
0194             : lightweight_forward_adapter_impl_zero<MD,F,FC>
0195         {
0196         };
0197 
0198 #       define  BOOST_PP_FILENAME_1 \
0199             <boost/functional/lightweight_forward_adapter.hpp>
0200 #       define  BOOST_PP_ITERATION_LIMITS                                     \
0201             (1,BOOST_FUNCTIONAL_LIGHTWEIGHT_FORWARD_ADAPTER_MAX_ARITY) 
0202 #       include BOOST_PP_ITERATE()
0203 
0204     } // namespace detail
0205 
0206     template<class F, int A0, int A1>
0207     struct result_of<boost::lightweight_forward_adapter<F,A0,A1> const ()>
0208         : boost::detail::lightweight_forward_adapter_result::template apply<
0209             boost::lightweight_forward_adapter<F,A0,A1> const () >
0210     { };
0211     template<class F, int A0, int A1>
0212     struct result_of<boost::lightweight_forward_adapter<F,A0,A1>()>
0213         : boost::detail::lightweight_forward_adapter_result::template apply<
0214             boost::lightweight_forward_adapter<F,A0,A1>() >
0215     { };
0216     template<class F, int A0, int A1>
0217     struct result_of<boost::lightweight_forward_adapter<F,A0,A1> const& ()>
0218         : boost::detail::lightweight_forward_adapter_result::template apply<
0219             boost::lightweight_forward_adapter<F,A0,A1> const () >
0220     { };
0221     template<class F, int A0, int A1>
0222     struct result_of<boost::lightweight_forward_adapter<F,A0,A1>& ()>
0223         : boost::detail::lightweight_forward_adapter_result::template apply<
0224             boost::lightweight_forward_adapter<F,A0,A1>() >
0225     { };
0226 }
0227 
0228 #     define BOOST_FUNCTIONAL_LIGHTWEIGHT_FORWARD_ADAPTER_HPP_INCLUDED
0229 
0230 #   else // defined(BOOST_PP_IS_ITERATING)
0231 #     define N BOOST_PP_ITERATION() 
0232 
0233         template< class Self, BOOST_PP_ENUM_PARAMS(N,typename T) >
0234         struct lightweight_forward_adapter_result::apply<
0235             Self (BOOST_PP_ENUM_PARAMS(N,T)) >
0236             : boost::result_of<
0237                 BOOST_DEDUCED_TYPENAME c<Self>::t (BOOST_PP_ENUM_BINARY_PARAMS(N,
0238                     typename x<T,>::t BOOST_PP_INTERCEPT)) >
0239         { };
0240 
0241         template< class MD, class F, class FC >
0242         struct lightweight_forward_adapter_impl<MD,F,FC,BOOST_PP_DEC(N),N>
0243             : lightweight_forward_adapter_result
0244         {
0245             template< BOOST_PP_ENUM_PARAMS(N,typename T) >
0246             inline typename boost::result_of< F(BOOST_PP_ENUM_BINARY_PARAMS(N,
0247                 T,const& BOOST_PP_INTERCEPT)) >::type
0248             operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,T,& BOOST_PP_INTERCEPT));
0249         };
0250 
0251         template< class MD, class F, class FC, int MinArity >
0252         struct lightweight_forward_adapter_impl<MD,F,FC,N,MinArity>
0253             : lightweight_forward_adapter_impl<MD,F,FC,BOOST_PP_DEC(N),MinArity>
0254         {
0255             using lightweight_forward_adapter_impl<MD,F,FC,BOOST_PP_DEC(N),
0256                 MinArity>::operator();
0257 
0258 #     define M(z,i,d) \
0259           static_cast<typename d::template x<T##i>::t>(a##i)
0260 
0261             template< BOOST_PP_ENUM_PARAMS(N,typename T) >
0262             inline typename lightweight_forward_adapter_result::template apply<
0263                 MD const (BOOST_PP_ENUM_BINARY_PARAMS(N,
0264                     T,const& BOOST_PP_INTERCEPT)) >::type
0265             operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,T,const& a)) const
0266             {
0267                 typedef lightweight_forward_adapter_result _;
0268                 return static_cast<MD const*>(this)->target_function()(
0269                     BOOST_PP_ENUM(N,M,_));
0270             }
0271             template< BOOST_PP_ENUM_PARAMS(N,typename T) >
0272             inline typename lightweight_forward_adapter_result::template apply<
0273                 MD (BOOST_PP_ENUM_BINARY_PARAMS(N,
0274                     T,const& BOOST_PP_INTERCEPT)) >::type
0275             operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,T,const& a))
0276             {
0277                 typedef lightweight_forward_adapter_result _;
0278                 return static_cast<MD*>(this)->target_function()(
0279                     BOOST_PP_ENUM(N,M,_));
0280             }
0281 #     undef M
0282       };
0283 
0284 #     undef N
0285 #   endif // defined(BOOST_PP_IS_ITERATING)
0286 
0287 #endif // include guard
0288