Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:31:06

0001 /*=============================================================================
0002     Copyright (c) 2007-2008 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_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/iteration/iterate.hpp>
0016 #   include <boost/preprocessor/repetition/enum_params.hpp>
0017 #   include <boost/preprocessor/repetition/enum_binary_params.hpp>
0018 #   include <boost/preprocessor/facilities/intercept.hpp>
0019 #   include <boost/preprocessor/arithmetic/dec.hpp>
0020 
0021 #   include <boost/utility/result_of.hpp>
0022 
0023 #   ifndef BOOST_FUNCTIONAL_FORWARD_ADAPTER_MAX_ARITY
0024 #     define BOOST_FUNCTIONAL_FORWARD_ADAPTER_MAX_ARITY 6
0025 #   elif BOOST_FUNCTIONAL_FORWARD_ADAPTER_MAX_ARITY < 3
0026 #     undef  BOOST_FUNCTIONAL_FORWARD_ADAPTER_MAX_ARITY
0027 #     define BOOST_FUNCTIONAL_FORWARD_ADAPTER_MAX_ARITY 3
0028 #   endif
0029 
0030 
0031 namespace boost 
0032 {
0033     template< typename Function, int Arity_Or_MinArity = -1, int MaxArity = -1 >
0034     class forward_adapter;
0035 
0036     //----- ---- --- -- - -  -   -
0037 
0038     namespace detail
0039     {
0040         template< class MostDerived, typename Function, typename FunctionConst, 
0041             int Arity, int MinArity >
0042         struct forward_adapter_impl;
0043 
0044         struct forward_adapter_result
0045         {
0046             template< typename Sig > struct apply;
0047 
0048             // Utility metafunction for qualification adjustment on arguments
0049             template< typename T > struct q          { typedef T const t; };
0050             template< typename T > struct q<T const> { typedef T const t; };
0051             template< typename T > struct q<T &>     { typedef T       t; };
0052 
0053             // Utility metafunction to choose target function qualification
0054             template< typename T > struct c
0055             { typedef typename T::target_function_t t; };
0056             template< typename T > struct c<T&      >
0057             { typedef typename T::target_function_t t; };
0058             template< typename T > struct c<T const >
0059             { typedef typename T::target_function_const_t t; };
0060             template< typename T > struct c<T const&>
0061             { typedef typename T::target_function_const_t t; };
0062         };
0063     }
0064 
0065 #   define BOOST_TMP_MACRO(f,fn,fc) \
0066         boost::detail::forward_adapter_impl< \
0067             forward_adapter<f,Arity_Or_MinArity,MaxArity>, fn, fc, \
0068             (MaxArity!=-1? MaxArity :Arity_Or_MinArity!=-1? Arity_Or_MinArity \
0069                 :BOOST_FUNCTIONAL_FORWARD_ADAPTER_MAX_ARITY), \
0070             (Arity_Or_MinArity!=-1? Arity_Or_MinArity : 0) >
0071 
0072     template< typename Function, int Arity_Or_MinArity, int MaxArity >
0073     class forward_adapter
0074         : public BOOST_TMP_MACRO(Function,Function,Function const)
0075         , private Function
0076     {
0077       public:
0078         forward_adapter(Function const& f = Function()) 
0079           : Function(f) 
0080         { }
0081 
0082         typedef Function        target_function_t;
0083         typedef Function const  target_function_const_t;
0084 
0085         Function       & target_function()       { return *this; }
0086         Function const & target_function() const { return *this; }
0087 
0088         template< typename Sig > struct result
0089             : detail::forward_adapter_result::template apply<Sig>
0090         { };
0091 
0092         using BOOST_TMP_MACRO(Function,Function, Function const)::operator();
0093     };
0094     template< typename Function, int Arity_Or_MinArity, int MaxArity >
0095     class forward_adapter< Function const, Arity_Or_MinArity, MaxArity >
0096         : public BOOST_TMP_MACRO(Function const, Function const, Function const)
0097         , private Function
0098     {
0099       public:
0100         forward_adapter(Function const& f = Function())
0101           : Function(f) 
0102         { }
0103 
0104         typedef Function const target_function_t;
0105         typedef Function const target_function_const_t;
0106 
0107         Function const & target_function() const { return *this; }
0108 
0109         template< typename Sig > struct result
0110             : detail::forward_adapter_result::template apply<Sig>
0111         { };
0112 
0113         using BOOST_TMP_MACRO(Function const,Function const, Function const)
0114             ::operator();
0115     };
0116     template< typename Function, int Arity_Or_MinArity, int MaxArity >
0117     class forward_adapter< Function &, Arity_Or_MinArity, MaxArity >
0118         : public BOOST_TMP_MACRO(Function&, Function, Function)
0119     {
0120         Function& ref_function;
0121       public:
0122         forward_adapter(Function& f)
0123           : ref_function(f) 
0124         { }
0125 
0126         typedef Function target_function_t;
0127         typedef Function target_function_const_t;
0128 
0129         Function & target_function() const { return this->ref_function; }
0130 
0131         template< typename Sig > struct result
0132             : detail::forward_adapter_result::template apply<Sig>
0133         { };
0134 
0135         using BOOST_TMP_MACRO(Function&, Function, Function)::operator();
0136     }; 
0137 
0138     #undef BOOST_TMP_MACRO
0139 
0140     namespace detail
0141     {
0142         template< class Self >
0143         struct forward_adapter_result::apply< Self() >
0144             : boost::result_of< BOOST_DEDUCED_TYPENAME c<Self>::t() >
0145         { };
0146 
0147         // WHen operator()() doesn't have any parameters, it can't
0148         // be templatized and can't use SFINAE, so intead use class
0149         // template parameter SFINAE to decide whether to instantiate it.
0150 
0151         template <typename T, typename R = void>
0152         struct forward_adapter_sfinae
0153         {
0154             typedef T type;
0155         };
0156 
0157         // This is the fallback for when there isn't an operator()(),
0158         // need to create an operator() that will never instantiate
0159         // so that using parent::operator() will work okay.
0160         template< class MD, class F, class FC, class Enable = void>
0161         struct forward_adapter_impl_zero
0162         {
0163             template <typename T> struct never_instantiate {};
0164             template <typename T>
0165             typename never_instantiate<T>::type operator()(T) const {}
0166         };
0167 
0168         template< class MD, class F, class FC>
0169         struct forward_adapter_impl_zero<MD, F, FC,
0170             typename forward_adapter_sfinae<typename boost::result_of< FC() >::type>::type>
0171         {
0172             inline typename boost::result_of< FC() >::type
0173             operator()() const
0174             {
0175                 return static_cast<MD const*>(this)->target_function()();
0176             }
0177 
0178             inline typename boost::result_of< F() >::type
0179             operator()()
0180             {
0181                 return static_cast<MD*>(this)->target_function()();
0182             }
0183         };
0184 
0185         template< class MD, class F, class FC >
0186         struct forward_adapter_impl<MD,F,FC,0,0>
0187             : forward_adapter_impl_zero<MD,F,FC>
0188         {
0189             using forward_adapter_impl_zero<MD,F,FC>::operator();
0190 
0191         // closing brace gets generated by preprocessing code, below
0192 
0193 #       define BOOST_TMP_MACRO(tpl_params,arg_types,params,args)              \
0194             template< tpl_params >                                             \
0195             inline typename boost::result_of< FC(arg_types) >::type            \
0196             operator()(params) const                                           \
0197             {                                                                  \
0198                 return static_cast<MD const*>(this)->target_function()(args);  \
0199             }                                                                  \
0200             template< tpl_params >                                             \
0201             inline typename boost::result_of< F(arg_types)>::type              \
0202             operator()(params)                                                 \
0203             {                                                                  \
0204                 return static_cast<MD*>(this)->target_function()(args);        \
0205             }
0206 
0207 #       // This is the total number of iterations we need
0208 #       define count ((1 << BOOST_FUNCTIONAL_FORWARD_ADAPTER_MAX_ARITY+1)-2)
0209 
0210 #       // Chain file iteration to virtually one loop
0211 #       if BOOST_FUNCTIONAL_FORWARD_ADAPTER_MAX_ARITY <= 7
0212 #         define limit1 count
0213 #         define limit2 0
0214 #         define limit3 0
0215 #       else
0216 #         if BOOST_FUNCTIONAL_FORWARD_ADAPTER_MAX_ARITY <= 15
0217 #           define limit1 (count >> 8)
0218 #           define limit2 255
0219 #           define limit3 0
0220 #         else
0221 #           define limit1 (count >> 16)
0222 #           define limit2 255
0223 #           define limit3 255
0224 #         endif
0225 #       endif
0226 
0227 #       define N 0
0228 
0229 #       define  BOOST_PP_FILENAME_1 <boost/functional/forward_adapter.hpp>
0230 #       define  BOOST_PP_ITERATION_LIMITS (0,limit1)
0231 #       include BOOST_PP_ITERATE()
0232 
0233 #       undef N
0234 #       undef limit3
0235 #       undef limit2
0236 #       undef limit1
0237 #       undef count
0238 #       undef BOOST_TMP_MACRO
0239 
0240         };
0241 
0242     } // namespace detail
0243 
0244     template<class F, int A0, int A1>
0245     struct result_of<boost::forward_adapter<F,A0,A1> const ()>
0246         : boost::detail::forward_adapter_result::template apply<
0247             boost::forward_adapter<F,A0,A1> const () >
0248     { };
0249     template<class F, int A0, int A1>
0250     struct result_of<boost::forward_adapter<F,A0,A1>()>
0251         : boost::detail::forward_adapter_result::template apply<
0252             boost::forward_adapter<F,A0,A1>() >
0253     { };
0254     template<class F, int A0, int A1>
0255     struct result_of<boost::forward_adapter<F,A0,A1> const& ()>
0256         : boost::detail::forward_adapter_result::template apply<
0257             boost::forward_adapter<F,A0,A1> const () >
0258     { };
0259     template<class F, int A0, int A1>
0260     struct result_of<boost::forward_adapter<F,A0,A1>& ()>
0261         : boost::detail::forward_adapter_result::template apply<
0262             boost::forward_adapter<F,A0,A1>() >
0263     { };
0264 }
0265 
0266 #       define BOOST_FUNCTIONAL_FORWARD_ADAPTER_HPP_INCLUDED
0267 
0268 #   elif BOOST_PP_ITERATION_DEPTH() == 1 && limit2
0269 #     define  BOOST_PP_FILENAME_2 <boost/functional/forward_adapter.hpp>
0270 #     define  BOOST_PP_ITERATION_LIMITS (0,limit2)
0271 #     include BOOST_PP_ITERATE()
0272 #   elif BOOST_PP_ITERATION_DEPTH() == 2 && limit3
0273 #     define  BOOST_PP_FILENAME_3 <boost/functional/forward_adapter.hpp>
0274 #     define  BOOST_PP_ITERATION_LIMITS (0,limit3)
0275 #     include BOOST_PP_ITERATE()
0276 
0277 #   else
0278 
0279 #     // I is the loop counter
0280 #     if limit2 && limit3
0281 #       define I (BOOST_PP_ITERATION_1 << 16 | BOOST_PP_ITERATION_2 << 8 | \
0282             BOOST_PP_ITERATION_3)
0283 #     elif limit2
0284 #       define I (BOOST_PP_ITERATION_1 << 8 | BOOST_PP_ITERATION_2)
0285 #     else
0286 #       define I BOOST_PP_ITERATION_1
0287 #     endif
0288 
0289 #     if I < count
0290 
0291 #       // Done for this arity? Increment N
0292 #       if (I+2 >> N+1) 
0293 #         if N == 0
0294 #           undef N
0295 #           define N 1
0296 #         elif N == 1
0297 #           undef N
0298 #           define N 2
0299 #         elif N == 2
0300 #           undef N
0301 #           define N 3
0302 #         elif N == 3
0303 #           undef N
0304 #           define N 4
0305 #         elif N == 4
0306 #           undef N
0307 #           define N 5
0308 #         elif N == 5
0309 #           undef N
0310 #           define N 6
0311 #         elif N == 6
0312 #           undef N
0313 #           define N 7
0314 #         elif N == 7
0315 #           undef N
0316 #           define N 8
0317 #         elif N == 8
0318 #           undef N
0319 #           define N 9
0320 #         elif N == 9
0321 #           undef N
0322 #           define N 10
0323 #         elif N == 10
0324 #           undef N
0325 #           define N 11
0326 #         elif N == 11
0327 #           undef N
0328 #           define N 12
0329 #         elif N == 12
0330 #           undef N
0331 #           define N 13
0332 #         elif N == 13
0333 #           undef N
0334 #           define N 14
0335 #         elif N == 14
0336 #           undef N
0337 #           define N 15
0338 #         elif N == 15
0339 #           undef N
0340 #           define N 16
0341 #         endif
0342 
0343         };
0344 
0345         template< class Self, BOOST_PP_ENUM_PARAMS(N,typename T) >
0346         struct forward_adapter_result::apply< Self(BOOST_PP_ENUM_PARAMS(N,T)) >
0347             : boost::result_of< 
0348                 BOOST_DEDUCED_TYPENAME c<Self>::t(BOOST_PP_ENUM_BINARY_PARAMS(N, 
0349                       typename q<T,>::t& BOOST_PP_INTERCEPT)) >
0350         { };
0351 
0352         template< class MD, class F, class FC >
0353         struct forward_adapter_impl<MD,F,FC,BOOST_PP_DEC(N),N>
0354         {
0355             template< BOOST_PP_ENUM_PARAMS(N,typename T) >
0356             inline typename boost::result_of< F(
0357                 BOOST_PP_ENUM_BINARY_PARAMS(N,T,& BOOST_PP_INTERCEPT)) >::type
0358             operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,T,& BOOST_PP_INTERCEPT));
0359         };
0360 
0361         template< class MD, class F, class FC, int MinArity >
0362         struct forward_adapter_impl<MD,F,FC,N,MinArity>
0363             : forward_adapter_impl<MD,F,FC,BOOST_PP_DEC(N),MinArity>
0364         {
0365             using forward_adapter_impl<MD,F,FC,BOOST_PP_DEC(N),MinArity>::operator();
0366 
0367 #       endif
0368 
0369 #       // Zero based count for each arity would be I-(1<<N)+2, but we don't
0370 #       // need it, unless we need a nicer order.
0371 
0372 #       // Macros for the parameter's type modifiers.
0373 #       if I & 0x000001
0374 #         define PT0 T0 &
0375 #       else
0376 #         define PT0 T0 const &
0377 #       endif
0378 #       if I & 0x000002
0379 #         define PT1 T1 &
0380 #       else
0381 #         define PT1 T1 const &
0382 #       endif
0383 #       if I & 0x000004
0384 #         define PT2 T2 &
0385 #       else
0386 #         define PT2 T2 const &
0387 #       endif
0388 #       if I & 0x000008
0389 #         define PT3 T3 &
0390 #       else
0391 #         define PT3 T3 const &
0392 #       endif
0393 #       if I & 0x000010
0394 #         define PT4 T4 &
0395 #       else
0396 #         define PT4 T4 const &
0397 #       endif
0398 #       if I & 0x000020
0399 #         define PT5 T5 &
0400 #       else
0401 #         define PT5 T5 const &
0402 #       endif
0403 #       if I & 0x000040
0404 #         define PT6 T6 &
0405 #       else
0406 #         define PT6 T6 const &
0407 #       endif
0408 #       if I & 0x000080
0409 #         define PT7 T7 &
0410 #       else
0411 #         define PT7 T7 const &
0412 #       endif
0413 #       if I & 0x000100
0414 #         define PT8 T8 &
0415 #       else
0416 #         define PT8 T8 const &
0417 #       endif
0418 #       if I & 0x000200
0419 #         define PT9 T9 &
0420 #       else
0421 #         define PT9 T9 const &
0422 #       endif
0423 #       if I & 0x000400
0424 #         define PT10 T10 &
0425 #       else
0426 #         define PT10 T10 const &
0427 #       endif
0428 #       if I & 0x000800
0429 #         define PT11 T11 &
0430 #       else
0431 #         define PT11 T11 const &
0432 #       endif
0433 #       if I & 0x001000
0434 #         define PT12 T12 &
0435 #       else
0436 #         define PT12 T12 const &
0437 #       endif
0438 #       if I & 0x002000
0439 #         define PT13 T13 &
0440 #       else
0441 #         define PT13 T13 const &
0442 #       endif
0443 #       if I & 0x004000
0444 #         define PT14 T14 &
0445 #       else
0446 #         define PT14 T14 const &
0447 #       endif
0448 #       if I & 0x008000
0449 #         define PT15 T15 &
0450 #       else
0451 #         define PT15 T15 const &
0452 #       endif
0453 
0454 #       if BOOST_WORKAROUND(BOOST_MSVC,BOOST_TESTED_AT(1400)) 
0455             template< BOOST_PP_ENUM_PARAMS(N,typename T) >
0456             inline typename boost::result_of<  FC(BOOST_PP_ENUM_PARAMS(N,PT)) 
0457                 >::type
0458             operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,PT,a)) const
0459             {
0460                 return static_cast<MD const* const>(this)
0461                     ->target_function()(BOOST_PP_ENUM_PARAMS(N,a));
0462             }
0463             template< BOOST_PP_ENUM_PARAMS(N,typename T) >
0464             inline typename boost::result_of<  F(BOOST_PP_ENUM_PARAMS(N,PT))
0465                 >::type
0466             operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,PT,a))
0467             {
0468                 return static_cast<MD* const>(this)
0469                     ->target_function()(BOOST_PP_ENUM_PARAMS(N,a));
0470             }
0471 #       else
0472         BOOST_TMP_MACRO(BOOST_PP_ENUM_PARAMS(N,typename T),
0473             BOOST_PP_ENUM_PARAMS(N,PT), BOOST_PP_ENUM_BINARY_PARAMS(N,PT,a),
0474             BOOST_PP_ENUM_PARAMS(N,a) )
0475         // ...generates uglier code but is faster - it caches ENUM_*
0476 #       endif
0477 
0478 #       undef PT0
0479 #       undef PT1
0480 #       undef PT2
0481 #       undef PT3
0482 #       undef PT4
0483 #       undef PT5
0484 #       undef PT6
0485 #       undef PT7
0486 #       undef PT8
0487 #       undef PT9
0488 #       undef PT10
0489 #       undef PT11
0490 #       undef PT12
0491 #       undef PT13
0492 #       undef PT14
0493 #       undef PT15
0494 
0495 #     endif // I < count
0496 
0497 #     undef I
0498 #   endif // defined(BOOST_PP_IS_ITERATING)
0499 
0500 #endif // include guard
0501