Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 09:44:49

0001 // Boost Lambda Library -- member_ptr.hpp ---------------------
0002 
0003 // Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
0004 // Copyright (C) 2000 Gary Powell (gary.powell@sierra.com)
0005 //
0006 // Distributed under the Boost Software License, Version 1.0. (See
0007 // accompanying file LICENSE_1_0.txt or copy at
0008 // http://www.boost.org/LICENSE_1_0.txt)
0009 //
0010 // For more information, see www.boost.org
0011 
0012 // --------------------------------------------------------------------------
0013 
0014 #if !defined(BOOST_LAMBDA_MEMBER_PTR_HPP)
0015 #define BOOST_LAMBDA_MEMBER_PTR_HPP
0016 
0017 namespace boost { 
0018 namespace lambda {
0019 
0020 
0021 class member_pointer_action {};
0022 
0023 
0024 namespace detail {
0025 
0026 // the boost type_traits member_pointer traits are not enough, 
0027 // need to know more details.
0028 template<class T>
0029 struct member_pointer {
0030   typedef typename boost::add_reference<T>::type type;
0031   typedef detail::unspecified class_type;
0032   typedef detail::unspecified qualified_class_type;
0033   BOOST_STATIC_CONSTANT(bool, is_data_member = false);
0034   BOOST_STATIC_CONSTANT(bool, is_function_member = false);
0035 };
0036 
0037 template<class T, class U>
0038 struct member_pointer<T U::*> {
0039   typedef typename boost::add_reference<T>::type type;
0040   typedef U class_type;
0041   typedef U qualified_class_type;
0042   BOOST_STATIC_CONSTANT(bool, is_data_member = true);
0043   BOOST_STATIC_CONSTANT(bool, is_function_member = false);
0044 };
0045 
0046 template<class T, class U>
0047 struct member_pointer<const T U::*> {
0048   typedef typename boost::add_reference<const T>::type type;
0049   typedef U class_type;
0050   typedef const U qualified_class_type;
0051   BOOST_STATIC_CONSTANT(bool, is_data_member = true);
0052   BOOST_STATIC_CONSTANT(bool, is_function_member = false);
0053 };
0054 
0055 template<class T, class U>
0056 struct member_pointer<volatile T U::*> {
0057   typedef typename boost::add_reference<volatile T>::type type;
0058   typedef U class_type;
0059   typedef volatile U qualified_class_type;
0060   BOOST_STATIC_CONSTANT(bool, is_data_member = true);
0061   BOOST_STATIC_CONSTANT(bool, is_function_member = false);
0062 };
0063 
0064 template<class T, class U>
0065 struct member_pointer<const volatile T U::*> {
0066   typedef typename boost::add_reference<const volatile T>::type type;
0067   typedef U class_type;
0068   typedef const volatile U qualified_class_type;
0069   BOOST_STATIC_CONSTANT(bool, is_data_member = true);
0070   BOOST_STATIC_CONSTANT(bool, is_function_member = false);
0071 };
0072 
0073 // -- nonconst member functions --
0074 template<class T, class U>
0075 struct member_pointer<T (U::*)()> {
0076   typedef T type;
0077   typedef U class_type;
0078   typedef U qualified_class_type;
0079   BOOST_STATIC_CONSTANT(bool, is_data_member = false);
0080   BOOST_STATIC_CONSTANT(bool, is_function_member = true);
0081 };
0082 template<class T, class U, class A1>
0083 struct member_pointer<T (U::*)(A1)> {
0084   typedef T type;
0085   typedef U class_type;
0086   typedef U qualified_class_type;
0087   BOOST_STATIC_CONSTANT(bool, is_data_member = false);
0088   BOOST_STATIC_CONSTANT(bool, is_function_member = true);
0089 };
0090 template<class T, class U, class A1, class A2>
0091 struct member_pointer<T (U::*)(A1, A2)> {
0092   typedef T type;
0093   typedef U class_type;
0094   typedef U qualified_class_type;
0095   BOOST_STATIC_CONSTANT(bool, is_data_member = false);
0096   BOOST_STATIC_CONSTANT(bool, is_function_member = true);
0097 };
0098 template<class T, class U, class A1, class A2, class A3>
0099 struct member_pointer<T (U::*)(A1, A2, A3)> {
0100   typedef T type;
0101   typedef U class_type;
0102   typedef U qualified_class_type;
0103   BOOST_STATIC_CONSTANT(bool, is_data_member = false);
0104   BOOST_STATIC_CONSTANT(bool, is_function_member = true);
0105 };
0106 template<class T, class U, class A1, class A2, class A3, class A4>
0107 struct member_pointer<T (U::*)(A1, A2, A3, A4)> {
0108   typedef T type;
0109   typedef U class_type;
0110   typedef U qualified_class_type;
0111   BOOST_STATIC_CONSTANT(bool, is_data_member = false);
0112   BOOST_STATIC_CONSTANT(bool, is_function_member = true);
0113 };
0114 template<class T, class U, class A1, class A2, class A3, class A4, class A5>
0115 struct member_pointer<T (U::*)(A1, A2, A3, A4, A5)> {
0116   typedef T type;
0117   typedef U class_type;
0118   typedef U qualified_class_type;
0119   BOOST_STATIC_CONSTANT(bool, is_data_member = false);
0120   BOOST_STATIC_CONSTANT(bool, is_function_member = true);
0121 };
0122 template<class T, class U, class A1, class A2, class A3, class A4, class A5,
0123          class A6>
0124 struct member_pointer<T (U::*)(A1, A2, A3, A4, A5, A6)> {
0125   typedef T type;
0126   typedef U class_type;
0127   typedef U qualified_class_type;
0128   BOOST_STATIC_CONSTANT(bool, is_data_member = false);
0129   BOOST_STATIC_CONSTANT(bool, is_function_member = true);
0130 };
0131 template<class T, class U, class A1, class A2, class A3, class A4, class A5,
0132          class A6, class A7>
0133 struct member_pointer<T (U::*)(A1, A2, A3, A4, A5, A6, A7)> {
0134   typedef T type;
0135   typedef U class_type;
0136   typedef U qualified_class_type;
0137   BOOST_STATIC_CONSTANT(bool, is_data_member = false);
0138   BOOST_STATIC_CONSTANT(bool, is_function_member = true);
0139 };
0140 template<class T, class U, class A1, class A2, class A3, class A4, class A5,
0141          class A6, class A7, class A8>
0142 struct member_pointer<T (U::*)(A1, A2, A3, A4, A5, A6, A7, A8)> {
0143   typedef T type;
0144   typedef U class_type;
0145   typedef U qualified_class_type;
0146   BOOST_STATIC_CONSTANT(bool, is_data_member = false);
0147   BOOST_STATIC_CONSTANT(bool, is_function_member = true);
0148 };
0149 template<class T, class U, class A1, class A2, class A3, class A4, class A5,
0150          class A6, class A7, class A8, class A9>
0151 struct member_pointer<T (U::*)(A1, A2, A3, A4, A5, A6, A7, A8, A9)> {
0152   typedef T type;
0153   typedef U class_type;
0154   typedef U qualified_class_type;
0155   BOOST_STATIC_CONSTANT(bool, is_data_member = false);
0156   BOOST_STATIC_CONSTANT(bool, is_function_member = true);
0157 };
0158 // -- const member functions --
0159 template<class T, class U>
0160 struct member_pointer<T (U::*)() const> {
0161   typedef T type;
0162   typedef U class_type;
0163   typedef const U qualified_class_type;
0164   BOOST_STATIC_CONSTANT(bool, is_data_member = false);
0165   BOOST_STATIC_CONSTANT(bool, is_function_member = true);
0166 };
0167 template<class T, class U, class A1>
0168 struct member_pointer<T (U::*)(A1) const> {
0169   typedef T type;
0170   typedef U class_type;
0171   typedef const U qualified_class_type;
0172   BOOST_STATIC_CONSTANT(bool, is_data_member = false);
0173   BOOST_STATIC_CONSTANT(bool, is_function_member = true);
0174 };
0175 template<class T, class U, class A1, class A2>
0176 struct member_pointer<T (U::*)(A1, A2) const> {
0177   typedef T type;
0178   typedef U class_type;
0179   typedef const U qualified_class_type;
0180   BOOST_STATIC_CONSTANT(bool, is_data_member = false);
0181   BOOST_STATIC_CONSTANT(bool, is_function_member = true);
0182 };
0183 template<class T, class U, class A1, class A2, class A3>
0184 struct member_pointer<T (U::*)(A1, A2, A3) const> {
0185   typedef T type;
0186   typedef U class_type;
0187   typedef const U qualified_class_type;
0188   BOOST_STATIC_CONSTANT(bool, is_data_member = false);
0189   BOOST_STATIC_CONSTANT(bool, is_function_member = true);
0190 };
0191 template<class T, class U, class A1, class A2, class A3, class A4>
0192 struct member_pointer<T (U::*)(A1, A2, A3, A4) const> {
0193   typedef T type;
0194   typedef U class_type;
0195   typedef const U qualified_class_type;
0196   BOOST_STATIC_CONSTANT(bool, is_data_member = false);
0197   BOOST_STATIC_CONSTANT(bool, is_function_member = true);
0198 };
0199 template<class T, class U, class A1, class A2, class A3, class A4, class A5>
0200 struct member_pointer<T (U::*)(A1, A2, A3, A4, A5) const> {
0201   typedef T type;
0202   typedef U class_type;
0203   typedef const U qualified_class_type;
0204   BOOST_STATIC_CONSTANT(bool, is_data_member = false);
0205   BOOST_STATIC_CONSTANT(bool, is_function_member = true);
0206 };
0207 template<class T, class U, class A1, class A2, class A3, class A4, class A5,
0208          class A6>
0209 struct member_pointer<T (U::*)(A1, A2, A3, A4, A5, A6) const> {
0210   typedef T type;
0211   typedef U class_type;
0212   typedef const U qualified_class_type;
0213   BOOST_STATIC_CONSTANT(bool, is_data_member = false);
0214   BOOST_STATIC_CONSTANT(bool, is_function_member = true);
0215 };
0216 template<class T, class U, class A1, class A2, class A3, class A4, class A5,
0217          class A6, class A7>
0218 struct member_pointer<T (U::*)(A1, A2, A3, A4, A5, A6, A7) const> {
0219   typedef T type;
0220   typedef U class_type;
0221   typedef const U qualified_class_type;
0222   BOOST_STATIC_CONSTANT(bool, is_data_member = false);
0223   BOOST_STATIC_CONSTANT(bool, is_function_member = true);
0224 };
0225 template<class T, class U, class A1, class A2, class A3, class A4, class A5,
0226          class A6, class A7, class A8>
0227 struct member_pointer<T (U::*)(A1, A2, A3, A4, A5, A6, A7, A8) const> {
0228   typedef T type;
0229   typedef U class_type;
0230   typedef const U qualified_class_type;
0231   BOOST_STATIC_CONSTANT(bool, is_data_member = false);
0232   BOOST_STATIC_CONSTANT(bool, is_function_member = true);
0233 };
0234 template<class T, class U, class A1, class A2, class A3, class A4, class A5,
0235          class A6, class A7, class A8, class A9>
0236 struct member_pointer<T (U::*)(A1, A2, A3, A4, A5, A6, A7, A8, A9) const> {
0237   typedef T type;
0238   typedef U class_type;
0239   typedef const U qualified_class_type;
0240   BOOST_STATIC_CONSTANT(bool, is_data_member = false);
0241   BOOST_STATIC_CONSTANT(bool, is_function_member = true);
0242 };
0243   // -- volatile --
0244 template<class T, class U>
0245 struct member_pointer<T (U::*)() volatile> {
0246   typedef T type;
0247   typedef U class_type;
0248   typedef volatile U qualified_class_type;
0249   BOOST_STATIC_CONSTANT(bool, is_data_member = false);
0250   BOOST_STATIC_CONSTANT(bool, is_function_member = true);
0251 };
0252 template<class T, class U, class A1>
0253 struct member_pointer<T (U::*)(A1) volatile> {
0254   typedef T type;
0255   typedef U class_type;
0256   typedef volatile U qualified_class_type;
0257   BOOST_STATIC_CONSTANT(bool, is_data_member = false);
0258   BOOST_STATIC_CONSTANT(bool, is_function_member = true);
0259 };
0260 template<class T, class U, class A1, class A2>
0261 struct member_pointer<T (U::*)(A1, A2) volatile> {
0262   typedef T type;
0263   typedef U class_type;
0264   typedef volatile U qualified_class_type;
0265   BOOST_STATIC_CONSTANT(bool, is_data_member = false);
0266   BOOST_STATIC_CONSTANT(bool, is_function_member = true);
0267 };
0268 template<class T, class U, class A1, class A2, class A3>
0269 struct member_pointer<T (U::*)(A1, A2, A3) volatile> {
0270   typedef T type;
0271   typedef U class_type;
0272   typedef volatile U qualified_class_type;
0273   BOOST_STATIC_CONSTANT(bool, is_data_member = false);
0274   BOOST_STATIC_CONSTANT(bool, is_function_member = true);
0275 };
0276 template<class T, class U, class A1, class A2, class A3, class A4>
0277 struct member_pointer<T (U::*)(A1, A2, A3, A4) volatile> {
0278   typedef T type;
0279   typedef U class_type;
0280   typedef volatile U qualified_class_type;
0281   BOOST_STATIC_CONSTANT(bool, is_data_member = false);
0282   BOOST_STATIC_CONSTANT(bool, is_function_member = true);
0283 };
0284 template<class T, class U, class A1, class A2, class A3, class A4, class A5>
0285 struct member_pointer<T (U::*)(A1, A2, A3, A4, A5) volatile> {
0286   typedef T type;
0287   typedef U class_type;
0288   typedef volatile U qualified_class_type;
0289   BOOST_STATIC_CONSTANT(bool, is_data_member = false);
0290   BOOST_STATIC_CONSTANT(bool, is_function_member = true);
0291 };
0292 template<class T, class U, class A1, class A2, class A3, class A4, class A5,
0293          class A6>
0294 struct member_pointer<T (U::*)(A1, A2, A3, A4, A5, A6) volatile> {
0295   typedef T type;
0296   typedef U class_type;
0297   typedef volatile U qualified_class_type;
0298   BOOST_STATIC_CONSTANT(bool, is_data_member = false);
0299   BOOST_STATIC_CONSTANT(bool, is_function_member = true);
0300 };
0301 template<class T, class U, class A1, class A2, class A3, class A4, class A5,
0302          class A6, class A7>
0303 struct member_pointer<T (U::*)(A1, A2, A3, A4, A5, A6, A7) volatile> {
0304   typedef T type;
0305   typedef U class_type;
0306   typedef volatile U qualified_class_type;
0307   BOOST_STATIC_CONSTANT(bool, is_data_member = false);
0308   BOOST_STATIC_CONSTANT(bool, is_function_member = true);
0309 };
0310 template<class T, class U, class A1, class A2, class A3, class A4, class A5,
0311          class A6, class A7, class A8>
0312 struct member_pointer<T (U::*)(A1, A2, A3, A4, A5, A6, A7, A8) volatile> {
0313   typedef T type;
0314   typedef U class_type;
0315   typedef volatile U qualified_class_type;
0316   BOOST_STATIC_CONSTANT(bool, is_data_member = false);
0317   BOOST_STATIC_CONSTANT(bool, is_function_member = true);
0318 };
0319 template<class T, class U, class A1, class A2, class A3, class A4, class A5,
0320          class A6, class A7, class A8, class A9>
0321 struct member_pointer<T (U::*)(A1, A2, A3, A4, A5, A6, A7, A8, A9) volatile> {
0322   typedef T type;
0323   typedef U class_type;
0324   typedef volatile U qualified_class_type;
0325   BOOST_STATIC_CONSTANT(bool, is_data_member = false);
0326   BOOST_STATIC_CONSTANT(bool, is_function_member = true);
0327 };
0328   // -- const volatile
0329 template<class T, class U>
0330 struct member_pointer<T (U::*)() const volatile> {
0331   typedef T type;
0332   typedef U class_type;
0333   typedef const volatile U qualified_class_type;
0334   BOOST_STATIC_CONSTANT(bool, is_data_member = false);
0335   BOOST_STATIC_CONSTANT(bool, is_function_member = true);
0336 };
0337 template<class T, class U, class A1>
0338 struct member_pointer<T (U::*)(A1) const volatile> {
0339   typedef T type;
0340   typedef U class_type;
0341   typedef const volatile U qualified_class_type;
0342   BOOST_STATIC_CONSTANT(bool, is_data_member = false);
0343   BOOST_STATIC_CONSTANT(bool, is_function_member = true);
0344 };
0345 template<class T, class U, class A1, class A2>
0346 struct member_pointer<T (U::*)(A1, A2) const volatile> {
0347   typedef T type;
0348   typedef U class_type;
0349   typedef const volatile U qualified_class_type;
0350   BOOST_STATIC_CONSTANT(bool, is_data_member = false);
0351   BOOST_STATIC_CONSTANT(bool, is_function_member = true);
0352 };
0353 template<class T, class U, class A1, class A2, class A3>
0354 struct member_pointer<T (U::*)(A1, A2, A3) const volatile> {
0355   typedef T type;
0356   typedef U class_type;
0357   typedef const volatile U qualified_class_type;
0358   BOOST_STATIC_CONSTANT(bool, is_data_member = false);
0359   BOOST_STATIC_CONSTANT(bool, is_function_member = true);
0360 };
0361 template<class T, class U, class A1, class A2, class A3, class A4>
0362 struct member_pointer<T (U::*)(A1, A2, A3, A4) const volatile> {
0363   typedef T type;
0364   typedef U class_type;
0365   typedef const volatile U qualified_class_type;
0366 };
0367 template<class T, class U, class A1, class A2, class A3, class A4, class A5>
0368 struct member_pointer<T (U::*)(A1, A2, A3, A4, A5) const volatile> {
0369   typedef T type;
0370   typedef U class_type;
0371   typedef const volatile U qualified_class_type;
0372   BOOST_STATIC_CONSTANT(bool, is_data_member = false);
0373   BOOST_STATIC_CONSTANT(bool, is_function_member = true);
0374 };
0375 template<class T, class U, class A1, class A2, class A3, class A4, class A5,
0376          class A6>
0377 struct member_pointer<T (U::*)(A1, A2, A3, A4, A5, A6) const volatile> {
0378   typedef T type;
0379   typedef U class_type;
0380   typedef const volatile U qualified_class_type;
0381   BOOST_STATIC_CONSTANT(bool, is_data_member = false);
0382   BOOST_STATIC_CONSTANT(bool, is_function_member = true);
0383 };
0384 template<class T, class U, class A1, class A2, class A3, class A4, class A5,
0385          class A6, class A7>
0386 struct member_pointer<T (U::*)(A1, A2, A3, A4, A5, A6, A7) const volatile> {
0387   typedef T type;
0388   typedef U class_type;
0389   typedef const volatile U qualified_class_type;
0390   BOOST_STATIC_CONSTANT(bool, is_data_member = false);
0391   BOOST_STATIC_CONSTANT(bool, is_function_member = true);
0392 };
0393 template<class T, class U, class A1, class A2, class A3, class A4, class A5,
0394          class A6, class A7, class A8>
0395 struct member_pointer<T (U::*)(A1, A2, A3, A4, A5, A6, A7, A8) const volatile> {
0396   typedef T type;
0397   typedef U class_type;
0398   typedef const volatile U qualified_class_type;
0399   BOOST_STATIC_CONSTANT(bool, is_data_member = false);
0400   BOOST_STATIC_CONSTANT(bool, is_function_member = true);
0401 };
0402 template<class T, class U, class A1, class A2, class A3, class A4, class A5,
0403          class A6, class A7, class A8, class A9>
0404 struct member_pointer<T (U::*)(A1, A2, A3, A4, A5, A6, A7, A8, A9) const volatile> {
0405   typedef T type;
0406   typedef U class_type;
0407   typedef const volatile U qualified_class_type;
0408   BOOST_STATIC_CONSTANT(bool, is_data_member = false);
0409   BOOST_STATIC_CONSTANT(bool, is_function_member = true);
0410 };
0411 
0412 } // detail
0413 
0414 namespace detail {
0415 
0416   // this class holds a pointer to a member function and the object.
0417   // when called, it just calls the member function with the parameters 
0418   // provided
0419 
0420   // It would have been possible to use existing lambda_functors to represent
0421   // a bound member function like this, but to have a separate template is 
0422   // safer, since now this functor doesn't mix and match with lambda_functors
0423   // only thing you can do with this is to call it
0424 
0425   // note that previously instantiated classes 
0426   // (other_action<member_pointer_action> and member_pointer_action_helper
0427   // guarantee, that A and B are 
0428   // such types, that for objects a and b of corresponding types, a->*b leads 
0429   // to the builtin ->* to be called. So types that would end in a  call to 
0430   // a user defined ->* do not create a member_pointer_caller object.
0431 
0432 template<class RET, class A, class B>
0433 class member_pointer_caller {
0434   A a; B b;
0435 
0436 public:
0437   member_pointer_caller(const A& aa, const B& bb) : a(aa), b(bb) {}
0438 
0439   RET operator()() const { return (a->*b)(); } 
0440 
0441   template<class A1>
0442   RET operator()(const A1& a1) const { return (a->*b)(a1); } 
0443 
0444   template<class A1, class A2>
0445   RET operator()(const A1& a1, const A2& a2) const { return (a->*b)(a1, a2); } 
0446 
0447   template<class A1, class A2, class A3>
0448   RET operator()(const A1& a1, const A2& a2, const A3& a3) const { 
0449     return (a->*b)(a1, a2, a3); 
0450   } 
0451 
0452   template<class A1, class A2, class A3, class A4>
0453   RET operator()(const A1& a1, const A2& a2, const A3& a3, 
0454                  const A4& a4) const { 
0455     return (a->*b)(a1, a2, a3, a4); 
0456   } 
0457 
0458   template<class A1, class A2, class A3, class A4, class A5>
0459   RET operator()(const A1& a1, const A2& a2, const A3& a3, const A4& a4, 
0460                  const A5& a5) const { 
0461     return (a->*b)(a1, a2, a3, a4, a5); 
0462   } 
0463 
0464   template<class A1, class A2, class A3, class A4, class A5, class A6>
0465   RET operator()(const A1& a1, const A2& a2, const A3& a3, const A4& a4, 
0466                  const A5& a5, const A6& a6) const { 
0467     return (a->*b)(a1, a2, a3, a4, a5, a6); 
0468   } 
0469 
0470   template<class A1, class A2, class A3, class A4, class A5, class A6, 
0471            class A7>
0472   RET operator()(const A1& a1, const A2& a2, const A3& a3, const A4& a4, 
0473                  const A5& a5, const A6& a6, const A7& a7) const { 
0474     return (a->*b)(a1, a2, a3, a4, a5, a6, a7); 
0475   } 
0476 
0477   template<class A1, class A2, class A3, class A4, class A5, class A6, 
0478            class A7, class A8>
0479   RET operator()(const A1& a1, const A2& a2, const A3& a3, const A4& a4, 
0480                  const A5& a5, const A6& a6, const A7& a7,
0481                  const A8& a8) const { 
0482     return (a->*b)(a1, a2, a3, a4, a5, a6, a7, a8); 
0483   } 
0484 
0485   template<class A1, class A2, class A3, class A4, class A5, class A6, 
0486            class A7, class A8, class A9>
0487   RET operator()(const A1& a1, const A2& a2, const A3& a3, const A4& a4, 
0488                  const A5& a5, const A6& a6, const A7& a7,
0489                  const A8& a8, const A9& a9) const { 
0490     return (a->*b)(a1, a2, a3, a4, a5, a6, a7, a8, a9); 
0491   } 
0492 
0493 };
0494 
0495 // helper templates for return type deduction and action classes
0496 // different cases for data member, function member, neither
0497 
0498 // true-true case
0499 template <bool Is_data_member, bool Is_function_member>
0500 struct member_pointer_action_helper;
0501   // cannot be both, no body provided
0502 
0503   // data member case
0504   // this means, that B is a data member and A is a pointer type,
0505   // so either built-in ->* should be called, or there is an error
0506 template <>
0507 struct member_pointer_action_helper<true, false> {
0508 public:
0509 
0510   template<class RET, class A, class B>
0511   static RET apply(A& a, B& b) { 
0512     return a->*b; 
0513   }
0514 
0515   template<class A, class B>
0516   struct return_type {
0517   private:
0518     typedef typename detail::remove_reference_and_cv<B>::type plainB;
0519 
0520     typedef typename detail::member_pointer<plainB>::type type0;
0521     // we remove the reference now, as we may have to add cv:s 
0522     typedef typename boost::remove_reference<type0>::type type1;
0523 
0524     // A is a reference to pointer
0525     // remove the top level cv qualifiers and reference
0526     typedef typename 
0527       detail::remove_reference_and_cv<A>::type non_ref_A;
0528 
0529     // A is a pointer type, so take the type pointed to
0530     typedef typename ::boost::remove_pointer<non_ref_A>::type non_pointer_A; 
0531 
0532   public:
0533     // For non-reference types, we must add const and/or volatile if
0534     // the pointer type has these qualifiers
0535     // If the member is a reference, these do not have any effect
0536     //   (cv T == T if T is a reference type)
0537     typedef typename detail::IF<
0538       ::boost::is_const<non_pointer_A>::value, 
0539       typename ::boost::add_const<type1>::type,
0540       type1
0541     >::RET type2;
0542     typedef typename detail::IF<
0543       ::boost::is_volatile<non_pointer_A>::value, 
0544       typename ::boost::add_volatile<type2>::type,
0545       type2
0546     >::RET type3;
0547     // add reference back
0548     typedef typename ::boost::add_reference<type3>::type type;
0549   };
0550 };
0551 
0552   // neither case
0553 template <>
0554 struct member_pointer_action_helper<false, false> {
0555 public:
0556   template<class RET, class A, class B>
0557   static RET apply(A& a, B& b) { 
0558 // not a built in member pointer operator, just call ->*
0559     return a->*b; 
0560   }
0561   // an overloaded member pointer operators, user should have specified
0562   // the return type
0563   // At this point we know that there is no matching specialization for
0564   // return_type_2, so try return_type_2_plain
0565   template<class A, class B>
0566   struct return_type {
0567 
0568     typedef typename plain_return_type_2<
0569       other_action<member_pointer_action>, A, B
0570     >::type type;
0571   };
0572   
0573 };
0574 
0575 
0576 // member pointer function case
0577 // This is a built in ->* call for a member function, 
0578 // the only thing that you can do with that, is to give it some arguments
0579 // note, it is guaranteed that A is a pointer type, and thus it cannot
0580 // be a call to overloaded ->*
0581 template <>
0582 struct member_pointer_action_helper<false, true> {
0583   public:
0584 
0585   template<class RET, class A, class B>
0586   static RET apply(A& a, B& b) { 
0587     typedef typename ::boost::remove_cv<B>::type plainB;
0588     typedef typename detail::member_pointer<plainB>::type ret_t; 
0589     typedef typename ::boost::remove_cv<A>::type plainA;
0590 
0591     // we always strip cv:s to 
0592     // make the two routes (calling and type deduction)
0593     // to give the same results (and the const does not make any functional
0594     // difference)
0595     return detail::member_pointer_caller<ret_t, plainA, plainB>(a, b); 
0596   }
0597 
0598   template<class A, class B>
0599   struct return_type {
0600     typedef typename detail::remove_reference_and_cv<B>::type plainB;
0601     typedef typename detail::member_pointer<plainB>::type ret_t; 
0602     typedef typename detail::remove_reference_and_cv<A>::type plainA; 
0603 
0604     typedef detail::member_pointer_caller<ret_t, plainA, plainB> type; 
0605   };
0606 };
0607 
0608 } // detail
0609 
0610 template<> class other_action<member_pointer_action>  {
0611 public:
0612   template<class RET, class A, class B>
0613   static RET apply(A& a, B& b) {
0614     typedef typename 
0615       ::boost::remove_cv<B>::type plainB;
0616 
0617     return detail::member_pointer_action_helper<
0618         boost::is_pointer<A>::value && 
0619           detail::member_pointer<plainB>::is_data_member,
0620         boost::is_pointer<A>::value && 
0621           detail::member_pointer<plainB>::is_function_member
0622       >::template apply<RET>(a, b); 
0623     }
0624 };
0625 
0626   // return type deduction --
0627 
0628   // If the right argument is a pointer to data member, 
0629   // and the left argument is of compatible pointer to class type
0630   // return type is a reference to the data member type
0631 
0632   // if right argument is a pointer to a member function, and the left 
0633   // argument is of a compatible type, the return type is a 
0634   // member_pointer_caller (see above)
0635 
0636   // Otherwise, return type deduction fails. There is either an error, 
0637   // or the user is trying to call an overloaded ->*
0638   // In such a case either ret<> must be used, or a return_type_2 user 
0639   // defined specialization must be provided
0640 
0641 
0642 template<class A, class B>
0643 struct return_type_2<other_action<member_pointer_action>, A, B> {
0644 private:
0645   typedef typename 
0646     detail::remove_reference_and_cv<B>::type plainB;
0647 public:
0648   typedef typename 
0649     detail::member_pointer_action_helper<
0650       detail::member_pointer<plainB>::is_data_member,
0651       detail::member_pointer<plainB>::is_function_member
0652     >::template return_type<A, B>::type type; 
0653 };
0654 
0655   // this is the way the generic lambda_functor_base functions instantiate
0656   // return type deduction. We turn it into return_type_2, so that the 
0657   // user can provide specializations on that level.
0658 template<class Args>
0659 struct return_type_N<other_action<member_pointer_action>, Args> {
0660   typedef typename boost::tuples::element<0, Args>::type A;
0661   typedef typename boost::tuples::element<1, Args>::type B;
0662   typedef typename 
0663     return_type_2<other_action<member_pointer_action>, 
0664                   typename boost::remove_reference<A>::type, 
0665                   typename boost::remove_reference<B>::type
0666                  >::type type;
0667 };
0668 
0669 
0670 template<class Arg1, class Arg2>
0671 inline const
0672 lambda_functor<
0673   lambda_functor_base<
0674     action<2, other_action<member_pointer_action> >,
0675     tuple<lambda_functor<Arg1>, typename const_copy_argument<Arg2>::type>
0676   >
0677 >
0678 operator->*(const lambda_functor<Arg1>& a1, const Arg2& a2)
0679 {
0680   return 
0681       lambda_functor_base<
0682         action<2, other_action<member_pointer_action> >,
0683         tuple<lambda_functor<Arg1>, typename const_copy_argument<Arg2>::type>
0684       >
0685       (tuple<lambda_functor<Arg1>, 
0686              typename const_copy_argument<Arg2>::type>(a1, a2));
0687 }
0688 
0689 template<class Arg1, class Arg2>
0690 inline const
0691 lambda_functor<
0692   lambda_functor_base<
0693     action<2, other_action<member_pointer_action> >,
0694     tuple<lambda_functor<Arg1>, lambda_functor<Arg2> >
0695   >
0696 >
0697 operator->*(const lambda_functor<Arg1>& a1, const lambda_functor<Arg2>& a2)
0698 {
0699   return 
0700       lambda_functor_base<
0701         action<2, other_action<member_pointer_action> >,
0702         tuple<lambda_functor<Arg1>, lambda_functor<Arg2> >
0703       >
0704     (tuple<lambda_functor<Arg1>, lambda_functor<Arg2> >(a1, a2));
0705 }
0706 
0707 template<class Arg1, class Arg2>
0708 inline const
0709 lambda_functor<
0710   lambda_functor_base<
0711     action<2, other_action<member_pointer_action> >,
0712     tuple<typename const_copy_argument<Arg1>::type, lambda_functor<Arg2> >
0713   >
0714 >
0715 operator->*(const Arg1& a1, const lambda_functor<Arg2>& a2)
0716 {
0717   return 
0718       lambda_functor_base<
0719         action<2, other_action<member_pointer_action> >,
0720         tuple<typename const_copy_argument<Arg1>::type, lambda_functor<Arg2> >
0721       >
0722       (tuple<typename const_copy_argument<Arg1>::type, 
0723              lambda_functor<Arg2> >(a1, a2));
0724 }
0725 
0726 
0727 } // namespace lambda 
0728 } // namespace boost
0729 
0730 
0731 #endif
0732 
0733 
0734 
0735 
0736 
0737