File indexing completed on 2025-01-18 09:31:06
0001
0002
0003
0004
0005
0006
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
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
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
0148
0149
0150
0151 template <typename T, typename R = void>
0152 struct forward_adapter_sfinae
0153 {
0154 typedef T type;
0155 };
0156
0157
0158
0159
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
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 #
0208 # define count ((1 << BOOST_FUNCTIONAL_FORWARD_ADAPTER_MAX_ARITY+1)-2)
0209
0210 #
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 }
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 #
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 #
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 #
0370 #
0371
0372 #
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
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
0496
0497 # undef I
0498 # endif
0499
0500 #endif
0501