epoc32/include/stdapis/boost/lambda/detail/member_ptr.hpp
author William Roberts <williamr@symbian.org>
Wed, 31 Mar 2010 12:27:01 +0100
branchSymbian2
changeset 3 e1b950c65cb4
permissions -rw-r--r--
Attempt to represent the S^2->S^3 header reorganisation as a series of "hg rename" operations
     1 // Boost Lambda Library -- member_ptr.hpp ---------------------
     2 
     3 // Copyright (C) 1999, 2000 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
     4 // Copyright (C) 2000 Gary Powell (gary.powell@sierra.com)
     5 //
     6 // Distributed under the Boost Software License, Version 1.0. (See
     7 // accompanying file LICENSE_1_0.txt or copy at
     8 // http://www.boost.org/LICENSE_1_0.txt)
     9 //
    10 // For more information, see www.boost.org
    11 
    12 // --------------------------------------------------------------------------
    13 
    14 #if !defined(BOOST_LAMBDA_MEMBER_PTR_HPP)
    15 #define BOOST_LAMBDA_MEMBER_PTR_HPP
    16 
    17 namespace boost { 
    18 namespace lambda {
    19 
    20 
    21 class member_pointer_action {};
    22 
    23 
    24 namespace detail {
    25 
    26 // the boost type_traits member_pointer traits are not enough, 
    27 // need to know more details.
    28 template<class T>
    29 struct member_pointer {
    30   typedef typename boost::add_reference<T>::type type;
    31   typedef detail::unspecified class_type;
    32   typedef detail::unspecified qualified_class_type;
    33   BOOST_STATIC_CONSTANT(bool, is_data_member = false);
    34   BOOST_STATIC_CONSTANT(bool, is_function_member = false);
    35 };
    36 
    37 template<class T, class U>
    38 struct member_pointer<T U::*> {
    39   typedef typename boost::add_reference<T>::type type;
    40   typedef U class_type;
    41   typedef U qualified_class_type;
    42   BOOST_STATIC_CONSTANT(bool, is_data_member = true);
    43   BOOST_STATIC_CONSTANT(bool, is_function_member = false);
    44 };
    45 
    46 template<class T, class U>
    47 struct member_pointer<const T U::*> {
    48   typedef typename boost::add_reference<const T>::type type;
    49   typedef U class_type;
    50   typedef const U qualified_class_type;
    51   BOOST_STATIC_CONSTANT(bool, is_data_member = true);
    52   BOOST_STATIC_CONSTANT(bool, is_function_member = false);
    53 };
    54 
    55 template<class T, class U>
    56 struct member_pointer<volatile T U::*> {
    57   typedef typename boost::add_reference<volatile T>::type type;
    58   typedef U class_type;
    59   typedef volatile U qualified_class_type;
    60   BOOST_STATIC_CONSTANT(bool, is_data_member = true);
    61   BOOST_STATIC_CONSTANT(bool, is_function_member = false);
    62 };
    63 
    64 template<class T, class U>
    65 struct member_pointer<const volatile T U::*> {
    66   typedef typename boost::add_reference<const volatile T>::type type;
    67   typedef U class_type;
    68   typedef const volatile U qualified_class_type;
    69   BOOST_STATIC_CONSTANT(bool, is_data_member = true);
    70   BOOST_STATIC_CONSTANT(bool, is_function_member = false);
    71 };
    72 
    73 // -- nonconst member functions --
    74 template<class T, class U>
    75 struct member_pointer<T (U::*)()> {
    76   typedef T type;
    77   typedef U class_type;
    78   typedef U qualified_class_type;
    79   BOOST_STATIC_CONSTANT(bool, is_data_member = false);
    80   BOOST_STATIC_CONSTANT(bool, is_function_member = true);
    81 };
    82 template<class T, class U, class A1>
    83 struct member_pointer<T (U::*)(A1)> {
    84   typedef T type;
    85   typedef U class_type;
    86   typedef U qualified_class_type;
    87   BOOST_STATIC_CONSTANT(bool, is_data_member = false);
    88   BOOST_STATIC_CONSTANT(bool, is_function_member = true);
    89 };
    90 template<class T, class U, class A1, class A2>
    91 struct member_pointer<T (U::*)(A1, A2)> {
    92   typedef T type;
    93   typedef U class_type;
    94   typedef U qualified_class_type;
    95   BOOST_STATIC_CONSTANT(bool, is_data_member = false);
    96   BOOST_STATIC_CONSTANT(bool, is_function_member = true);
    97 };
    98 template<class T, class U, class A1, class A2, class A3>
    99 struct member_pointer<T (U::*)(A1, A2, A3)> {
   100   typedef T type;
   101   typedef U class_type;
   102   typedef U qualified_class_type;
   103   BOOST_STATIC_CONSTANT(bool, is_data_member = false);
   104   BOOST_STATIC_CONSTANT(bool, is_function_member = true);
   105 };
   106 template<class T, class U, class A1, class A2, class A3, class A4>
   107 struct member_pointer<T (U::*)(A1, A2, A3, A4)> {
   108   typedef T type;
   109   typedef U class_type;
   110   typedef U qualified_class_type;
   111   BOOST_STATIC_CONSTANT(bool, is_data_member = false);
   112   BOOST_STATIC_CONSTANT(bool, is_function_member = true);
   113 };
   114 template<class T, class U, class A1, class A2, class A3, class A4, class A5>
   115 struct member_pointer<T (U::*)(A1, A2, A3, A4, A5)> {
   116   typedef T type;
   117   typedef U class_type;
   118   typedef U qualified_class_type;
   119   BOOST_STATIC_CONSTANT(bool, is_data_member = false);
   120   BOOST_STATIC_CONSTANT(bool, is_function_member = true);
   121 };
   122 template<class T, class U, class A1, class A2, class A3, class A4, class A5,
   123          class A6>
   124 struct member_pointer<T (U::*)(A1, A2, A3, A4, A5, A6)> {
   125   typedef T type;
   126   typedef U class_type;
   127   typedef U qualified_class_type;
   128   BOOST_STATIC_CONSTANT(bool, is_data_member = false);
   129   BOOST_STATIC_CONSTANT(bool, is_function_member = true);
   130 };
   131 template<class T, class U, class A1, class A2, class A3, class A4, class A5,
   132          class A6, class A7>
   133 struct member_pointer<T (U::*)(A1, A2, A3, A4, A5, A6, A7)> {
   134   typedef T type;
   135   typedef U class_type;
   136   typedef U qualified_class_type;
   137   BOOST_STATIC_CONSTANT(bool, is_data_member = false);
   138   BOOST_STATIC_CONSTANT(bool, is_function_member = true);
   139 };
   140 template<class T, class U, class A1, class A2, class A3, class A4, class A5,
   141          class A6, class A7, class A8>
   142 struct member_pointer<T (U::*)(A1, A2, A3, A4, A5, A6, A7, A8)> {
   143   typedef T type;
   144   typedef U class_type;
   145   typedef U qualified_class_type;
   146   BOOST_STATIC_CONSTANT(bool, is_data_member = false);
   147   BOOST_STATIC_CONSTANT(bool, is_function_member = true);
   148 };
   149 template<class T, class U, class A1, class A2, class A3, class A4, class A5,
   150          class A6, class A7, class A8, class A9>
   151 struct member_pointer<T (U::*)(A1, A2, A3, A4, A5, A6, A7, A8, A9)> {
   152   typedef T type;
   153   typedef U class_type;
   154   typedef U qualified_class_type;
   155   BOOST_STATIC_CONSTANT(bool, is_data_member = false);
   156   BOOST_STATIC_CONSTANT(bool, is_function_member = true);
   157 };
   158 // -- const member functions --
   159 template<class T, class U>
   160 struct member_pointer<T (U::*)() const> {
   161   typedef T type;
   162   typedef U class_type;
   163   typedef const U qualified_class_type;
   164   BOOST_STATIC_CONSTANT(bool, is_data_member = false);
   165   BOOST_STATIC_CONSTANT(bool, is_function_member = true);
   166 };
   167 template<class T, class U, class A1>
   168 struct member_pointer<T (U::*)(A1) const> {
   169   typedef T type;
   170   typedef U class_type;
   171   typedef const U qualified_class_type;
   172   BOOST_STATIC_CONSTANT(bool, is_data_member = false);
   173   BOOST_STATIC_CONSTANT(bool, is_function_member = true);
   174 };
   175 template<class T, class U, class A1, class A2>
   176 struct member_pointer<T (U::*)(A1, A2) const> {
   177   typedef T type;
   178   typedef U class_type;
   179   typedef const U qualified_class_type;
   180   BOOST_STATIC_CONSTANT(bool, is_data_member = false);
   181   BOOST_STATIC_CONSTANT(bool, is_function_member = true);
   182 };
   183 template<class T, class U, class A1, class A2, class A3>
   184 struct member_pointer<T (U::*)(A1, A2, A3) const> {
   185   typedef T type;
   186   typedef U class_type;
   187   typedef const U qualified_class_type;
   188   BOOST_STATIC_CONSTANT(bool, is_data_member = false);
   189   BOOST_STATIC_CONSTANT(bool, is_function_member = true);
   190 };
   191 template<class T, class U, class A1, class A2, class A3, class A4>
   192 struct member_pointer<T (U::*)(A1, A2, A3, A4) const> {
   193   typedef T type;
   194   typedef U class_type;
   195   typedef const U qualified_class_type;
   196   BOOST_STATIC_CONSTANT(bool, is_data_member = false);
   197   BOOST_STATIC_CONSTANT(bool, is_function_member = true);
   198 };
   199 template<class T, class U, class A1, class A2, class A3, class A4, class A5>
   200 struct member_pointer<T (U::*)(A1, A2, A3, A4, A5) const> {
   201   typedef T type;
   202   typedef U class_type;
   203   typedef const U qualified_class_type;
   204   BOOST_STATIC_CONSTANT(bool, is_data_member = false);
   205   BOOST_STATIC_CONSTANT(bool, is_function_member = true);
   206 };
   207 template<class T, class U, class A1, class A2, class A3, class A4, class A5,
   208          class A6>
   209 struct member_pointer<T (U::*)(A1, A2, A3, A4, A5, A6) const> {
   210   typedef T type;
   211   typedef U class_type;
   212   typedef const U qualified_class_type;
   213   BOOST_STATIC_CONSTANT(bool, is_data_member = false);
   214   BOOST_STATIC_CONSTANT(bool, is_function_member = true);
   215 };
   216 template<class T, class U, class A1, class A2, class A3, class A4, class A5,
   217          class A6, class A7>
   218 struct member_pointer<T (U::*)(A1, A2, A3, A4, A5, A6, A7) const> {
   219   typedef T type;
   220   typedef U class_type;
   221   typedef const U qualified_class_type;
   222   BOOST_STATIC_CONSTANT(bool, is_data_member = false);
   223   BOOST_STATIC_CONSTANT(bool, is_function_member = true);
   224 };
   225 template<class T, class U, class A1, class A2, class A3, class A4, class A5,
   226          class A6, class A7, class A8>
   227 struct member_pointer<T (U::*)(A1, A2, A3, A4, A5, A6, A7, A8) const> {
   228   typedef T type;
   229   typedef U class_type;
   230   typedef const U qualified_class_type;
   231   BOOST_STATIC_CONSTANT(bool, is_data_member = false);
   232   BOOST_STATIC_CONSTANT(bool, is_function_member = true);
   233 };
   234 template<class T, class U, class A1, class A2, class A3, class A4, class A5,
   235          class A6, class A7, class A8, class A9>
   236 struct member_pointer<T (U::*)(A1, A2, A3, A4, A5, A6, A7, A8, A9) const> {
   237   typedef T type;
   238   typedef U class_type;
   239   typedef const U qualified_class_type;
   240   BOOST_STATIC_CONSTANT(bool, is_data_member = false);
   241   BOOST_STATIC_CONSTANT(bool, is_function_member = true);
   242 };
   243   // -- volatile --
   244 template<class T, class U>
   245 struct member_pointer<T (U::*)() volatile> {
   246   typedef T type;
   247   typedef U class_type;
   248   typedef volatile U qualified_class_type;
   249   BOOST_STATIC_CONSTANT(bool, is_data_member = false);
   250   BOOST_STATIC_CONSTANT(bool, is_function_member = true);
   251 };
   252 template<class T, class U, class A1>
   253 struct member_pointer<T (U::*)(A1) volatile> {
   254   typedef T type;
   255   typedef U class_type;
   256   typedef volatile U qualified_class_type;
   257   BOOST_STATIC_CONSTANT(bool, is_data_member = false);
   258   BOOST_STATIC_CONSTANT(bool, is_function_member = true);
   259 };
   260 template<class T, class U, class A1, class A2>
   261 struct member_pointer<T (U::*)(A1, A2) volatile> {
   262   typedef T type;
   263   typedef U class_type;
   264   typedef volatile U qualified_class_type;
   265   BOOST_STATIC_CONSTANT(bool, is_data_member = false);
   266   BOOST_STATIC_CONSTANT(bool, is_function_member = true);
   267 };
   268 template<class T, class U, class A1, class A2, class A3>
   269 struct member_pointer<T (U::*)(A1, A2, A3) volatile> {
   270   typedef T type;
   271   typedef U class_type;
   272   typedef volatile U qualified_class_type;
   273   BOOST_STATIC_CONSTANT(bool, is_data_member = false);
   274   BOOST_STATIC_CONSTANT(bool, is_function_member = true);
   275 };
   276 template<class T, class U, class A1, class A2, class A3, class A4>
   277 struct member_pointer<T (U::*)(A1, A2, A3, A4) volatile> {
   278   typedef T type;
   279   typedef U class_type;
   280   typedef volatile U qualified_class_type;
   281   BOOST_STATIC_CONSTANT(bool, is_data_member = false);
   282   BOOST_STATIC_CONSTANT(bool, is_function_member = true);
   283 };
   284 template<class T, class U, class A1, class A2, class A3, class A4, class A5>
   285 struct member_pointer<T (U::*)(A1, A2, A3, A4, A5) volatile> {
   286   typedef T type;
   287   typedef U class_type;
   288   typedef volatile U qualified_class_type;
   289   BOOST_STATIC_CONSTANT(bool, is_data_member = false);
   290   BOOST_STATIC_CONSTANT(bool, is_function_member = true);
   291 };
   292 template<class T, class U, class A1, class A2, class A3, class A4, class A5,
   293          class A6>
   294 struct member_pointer<T (U::*)(A1, A2, A3, A4, A5, A6) volatile> {
   295   typedef T type;
   296   typedef U class_type;
   297   typedef volatile U qualified_class_type;
   298   BOOST_STATIC_CONSTANT(bool, is_data_member = false);
   299   BOOST_STATIC_CONSTANT(bool, is_function_member = true);
   300 };
   301 template<class T, class U, class A1, class A2, class A3, class A4, class A5,
   302          class A6, class A7>
   303 struct member_pointer<T (U::*)(A1, A2, A3, A4, A5, A6, A7) volatile> {
   304   typedef T type;
   305   typedef U class_type;
   306   typedef volatile U qualified_class_type;
   307   BOOST_STATIC_CONSTANT(bool, is_data_member = false);
   308   BOOST_STATIC_CONSTANT(bool, is_function_member = true);
   309 };
   310 template<class T, class U, class A1, class A2, class A3, class A4, class A5,
   311          class A6, class A7, class A8>
   312 struct member_pointer<T (U::*)(A1, A2, A3, A4, A5, A6, A7, A8) volatile> {
   313   typedef T type;
   314   typedef U class_type;
   315   typedef volatile U qualified_class_type;
   316   BOOST_STATIC_CONSTANT(bool, is_data_member = false);
   317   BOOST_STATIC_CONSTANT(bool, is_function_member = true);
   318 };
   319 template<class T, class U, class A1, class A2, class A3, class A4, class A5,
   320          class A6, class A7, class A8, class A9>
   321 struct member_pointer<T (U::*)(A1, A2, A3, A4, A5, A6, A7, A8, A9) volatile> {
   322   typedef T type;
   323   typedef U class_type;
   324   typedef volatile U qualified_class_type;
   325   BOOST_STATIC_CONSTANT(bool, is_data_member = false);
   326   BOOST_STATIC_CONSTANT(bool, is_function_member = true);
   327 };
   328   // -- const volatile
   329 template<class T, class U>
   330 struct member_pointer<T (U::*)() const volatile> {
   331   typedef T type;
   332   typedef U class_type;
   333   typedef const volatile U qualified_class_type;
   334   BOOST_STATIC_CONSTANT(bool, is_data_member = false);
   335   BOOST_STATIC_CONSTANT(bool, is_function_member = true);
   336 };
   337 template<class T, class U, class A1>
   338 struct member_pointer<T (U::*)(A1) const volatile> {
   339   typedef T type;
   340   typedef U class_type;
   341   typedef const volatile U qualified_class_type;
   342   BOOST_STATIC_CONSTANT(bool, is_data_member = false);
   343   BOOST_STATIC_CONSTANT(bool, is_function_member = true);
   344 };
   345 template<class T, class U, class A1, class A2>
   346 struct member_pointer<T (U::*)(A1, A2) const volatile> {
   347   typedef T type;
   348   typedef U class_type;
   349   typedef const volatile U qualified_class_type;
   350   BOOST_STATIC_CONSTANT(bool, is_data_member = false);
   351   BOOST_STATIC_CONSTANT(bool, is_function_member = true);
   352 };
   353 template<class T, class U, class A1, class A2, class A3>
   354 struct member_pointer<T (U::*)(A1, A2, A3) const volatile> {
   355   typedef T type;
   356   typedef U class_type;
   357   typedef const volatile U qualified_class_type;
   358   BOOST_STATIC_CONSTANT(bool, is_data_member = false);
   359   BOOST_STATIC_CONSTANT(bool, is_function_member = true);
   360 };
   361 template<class T, class U, class A1, class A2, class A3, class A4>
   362 struct member_pointer<T (U::*)(A1, A2, A3, A4) const volatile> {
   363   typedef T type;
   364   typedef U class_type;
   365   typedef const volatile U qualified_class_type;
   366 };
   367 template<class T, class U, class A1, class A2, class A3, class A4, class A5>
   368 struct member_pointer<T (U::*)(A1, A2, A3, A4, A5) const volatile> {
   369   typedef T type;
   370   typedef U class_type;
   371   typedef const volatile U qualified_class_type;
   372   BOOST_STATIC_CONSTANT(bool, is_data_member = false);
   373   BOOST_STATIC_CONSTANT(bool, is_function_member = true);
   374 };
   375 template<class T, class U, class A1, class A2, class A3, class A4, class A5,
   376          class A6>
   377 struct member_pointer<T (U::*)(A1, A2, A3, A4, A5, A6) const volatile> {
   378   typedef T type;
   379   typedef U class_type;
   380   typedef const volatile U qualified_class_type;
   381   BOOST_STATIC_CONSTANT(bool, is_data_member = false);
   382   BOOST_STATIC_CONSTANT(bool, is_function_member = true);
   383 };
   384 template<class T, class U, class A1, class A2, class A3, class A4, class A5,
   385          class A6, class A7>
   386 struct member_pointer<T (U::*)(A1, A2, A3, A4, A5, A6, A7) const volatile> {
   387   typedef T type;
   388   typedef U class_type;
   389   typedef const volatile U qualified_class_type;
   390   BOOST_STATIC_CONSTANT(bool, is_data_member = false);
   391   BOOST_STATIC_CONSTANT(bool, is_function_member = true);
   392 };
   393 template<class T, class U, class A1, class A2, class A3, class A4, class A5,
   394          class A6, class A7, class A8>
   395 struct member_pointer<T (U::*)(A1, A2, A3, A4, A5, A6, A7, A8) const volatile> {
   396   typedef T type;
   397   typedef U class_type;
   398   typedef const volatile U qualified_class_type;
   399   BOOST_STATIC_CONSTANT(bool, is_data_member = false);
   400   BOOST_STATIC_CONSTANT(bool, is_function_member = true);
   401 };
   402 template<class T, class U, class A1, class A2, class A3, class A4, class A5,
   403          class A6, class A7, class A8, class A9>
   404 struct member_pointer<T (U::*)(A1, A2, A3, A4, A5, A6, A7, A8, A9) const volatile> {
   405   typedef T type;
   406   typedef U class_type;
   407   typedef const volatile U qualified_class_type;
   408   BOOST_STATIC_CONSTANT(bool, is_data_member = false);
   409   BOOST_STATIC_CONSTANT(bool, is_function_member = true);
   410 };
   411 
   412 } // detail
   413 
   414 namespace detail {
   415 
   416   // this class holds a pointer to a member function and the object.
   417   // when called, it just calls the member function with the parameters 
   418   // provided
   419 
   420   // It would have been possible to use existing lambda_functors to represent
   421   // a bound member function like this, but to have a separate template is 
   422   // safer, since now this functor doesn't mix and match with lambda_functors
   423   // only thing you can do with this is to call it
   424 
   425   // note that previously instantiated classes 
   426   // (other_action<member_pointer_action> and member_pointer_action_helper
   427   // guarantee, that A and B are 
   428   // such types, that for objects a and b of corresponding types, a->*b leads 
   429   // to the builtin ->* to be called. So types that would end in a  call to 
   430   // a user defined ->* do not create a member_pointer_caller object.
   431 
   432 template<class RET, class A, class B>
   433 class member_pointer_caller {
   434   A a; B b;
   435 
   436 public:
   437   member_pointer_caller(const A& aa, const B& bb) : a(aa), b(bb) {}
   438 
   439   RET operator()() const { return (a->*b)(); } 
   440 
   441   template<class A1>
   442   RET operator()(const A1& a1) const { return (a->*b)(a1); } 
   443 
   444   template<class A1, class A2>
   445   RET operator()(const A1& a1, const A2& a2) const { return (a->*b)(a1, a2); } 
   446 
   447   template<class A1, class A2, class A3>
   448   RET operator()(const A1& a1, const A2& a2, const A3& a3) const { 
   449     return (a->*b)(a1, a2, a3); 
   450   } 
   451 
   452   template<class A1, class A2, class A3, class A4>
   453   RET operator()(const A1& a1, const A2& a2, const A3& a3, 
   454                  const A4& a4) const { 
   455     return (a->*b)(a1, a2, a3, a4); 
   456   } 
   457 
   458   template<class A1, class A2, class A3, class A4, class A5>
   459   RET operator()(const A1& a1, const A2& a2, const A3& a3, const A4& a4, 
   460                  const A5& a5) const { 
   461     return (a->*b)(a1, a2, a3, a4, a5); 
   462   } 
   463 
   464   template<class A1, class A2, class A3, class A4, class A5, class A6>
   465   RET operator()(const A1& a1, const A2& a2, const A3& a3, const A4& a4, 
   466                  const A5& a5, const A6& a6) const { 
   467     return (a->*b)(a1, a2, a3, a4, a5, a6); 
   468   } 
   469 
   470   template<class A1, class A2, class A3, class A4, class A5, class A6, 
   471            class A7>
   472   RET operator()(const A1& a1, const A2& a2, const A3& a3, const A4& a4, 
   473                  const A5& a5, const A6& a6, const A7& a7) const { 
   474     return (a->*b)(a1, a2, a3, a4, a5, a6, a7); 
   475   } 
   476 
   477   template<class A1, class A2, class A3, class A4, class A5, class A6, 
   478            class A7, class A8>
   479   RET operator()(const A1& a1, const A2& a2, const A3& a3, const A4& a4, 
   480                  const A5& a5, const A6& a6, const A7& a7,
   481                  const A8& a8) const { 
   482     return (a->*b)(a1, a2, a3, a4, a5, a6, a7, a8); 
   483   } 
   484 
   485   template<class A1, class A2, class A3, class A4, class A5, class A6, 
   486            class A7, class A8, class A9>
   487   RET operator()(const A1& a1, const A2& a2, const A3& a3, const A4& a4, 
   488                  const A5& a5, const A6& a6, const A7& a7,
   489                  const A8& a8, const A9& a9) const { 
   490     return (a->*b)(a1, a2, a3, a4, a5, a6, a7, a8, a9); 
   491   } 
   492 
   493 };
   494 
   495 // helper templates for return type deduction and action classes
   496 // different cases for data member, function member, neither
   497 
   498 // true-true case
   499 template <bool Is_data_member, bool Is_function_member>
   500 struct member_pointer_action_helper;
   501   // cannot be both, no body provided
   502 
   503   // data member case
   504   // this means, that B is a data member and A is a pointer type,
   505   // so either built-in ->* should be called, or there is an error
   506 template <>
   507 struct member_pointer_action_helper<true, false> {
   508 public:
   509 
   510   template<class RET, class A, class B>
   511   static RET apply(A& a, B& b) { 
   512     return a->*b; 
   513   }
   514 
   515   template<class A, class B>
   516   struct return_type {
   517   private:
   518     typedef typename detail::remove_reference_and_cv<B>::type plainB;
   519 
   520     typedef typename detail::member_pointer<plainB>::type type0;
   521     // we remove the reference now, as we may have to add cv:s 
   522     typedef typename boost::remove_reference<type0>::type type1;
   523 
   524     // A is a reference to pointer
   525     // remove the top level cv qualifiers and reference
   526     typedef typename 
   527       detail::remove_reference_and_cv<A>::type non_ref_A;
   528 
   529     // A is a pointer type, so take the type pointed to
   530     typedef typename ::boost::remove_pointer<non_ref_A>::type non_pointer_A; 
   531 
   532   public:
   533     // For non-reference types, we must add const and/or volatile if
   534     // the pointer type has these qualifiers
   535     // If the member is a reference, these do not have any effect
   536     //   (cv T == T if T is a reference type)
   537     typedef typename detail::IF<
   538       ::boost::is_const<non_pointer_A>::value, 
   539       typename ::boost::add_const<type1>::type,
   540       type1
   541     >::RET type2;
   542     typedef typename detail::IF<
   543       ::boost::is_volatile<non_pointer_A>::value, 
   544       typename ::boost::add_volatile<type2>::type,
   545       type2
   546     >::RET type3;
   547     // add reference back
   548     typedef typename ::boost::add_reference<type3>::type type;
   549   };
   550 };
   551 
   552   // neither case
   553 template <>
   554 struct member_pointer_action_helper<false, false> {
   555 public:
   556   template<class RET, class A, class B>
   557   static RET apply(A& a, B& b) { 
   558 // not a built in member pointer operator, just call ->*
   559     return a->*b; 
   560   }
   561   // an overloaded member pointer operators, user should have specified
   562   // the return type
   563   // At this point we know that there is no matching specialization for
   564   // return_type_2, so try return_type_2_plain
   565   template<class A, class B>
   566   struct return_type {
   567 
   568     typedef typename plain_return_type_2<
   569       other_action<member_pointer_action>, A, B
   570     >::type type;
   571   };
   572   
   573 };
   574 
   575 
   576 // member pointer function case
   577 // This is a built in ->* call for a member function, 
   578 // the only thing that you can do with that, is to give it some arguments
   579 // note, it is guaranteed that A is a pointer type, and thus it cannot
   580 // be a call to overloaded ->*
   581 template <>
   582 struct member_pointer_action_helper<false, true> {
   583   public:
   584 
   585   template<class RET, class A, class B>
   586   static RET apply(A& a, B& b) { 
   587     typedef typename ::boost::remove_cv<B>::type plainB;
   588     typedef typename detail::member_pointer<plainB>::type ret_t; 
   589     typedef typename ::boost::remove_cv<A>::type plainA;
   590 
   591     // we always strip cv:s to 
   592     // make the two routes (calling and type deduction)
   593     // to give the same results (and the const does not make any functional
   594     // difference)
   595     return detail::member_pointer_caller<ret_t, plainA, plainB>(a, b); 
   596   }
   597 
   598   template<class A, class B>
   599   struct return_type {
   600     typedef typename detail::remove_reference_and_cv<B>::type plainB;
   601     typedef typename detail::member_pointer<plainB>::type ret_t; 
   602     typedef typename detail::remove_reference_and_cv<A>::type plainA; 
   603 
   604     typedef detail::member_pointer_caller<ret_t, plainA, plainB> type; 
   605   };
   606 };
   607 
   608 } // detail
   609 
   610 template<> class other_action<member_pointer_action>  {
   611 public:
   612   template<class RET, class A, class B>
   613   static RET apply(A& a, B& b) {
   614     typedef typename 
   615       ::boost::remove_cv<B>::type plainB;
   616 
   617     return detail::member_pointer_action_helper<
   618         boost::is_pointer<A>::value && 
   619           detail::member_pointer<plainB>::is_data_member,
   620         boost::is_pointer<A>::value && 
   621           detail::member_pointer<plainB>::is_function_member
   622       >::template apply<RET>(a, b); 
   623     }
   624 };
   625 
   626   // return type deduction --
   627 
   628   // If the right argument is a pointer to data member, 
   629   // and the left argument is of compatible pointer to class type
   630   // return type is a reference to the data member type
   631 
   632   // if right argument is a pointer to a member function, and the left 
   633   // argument is of a compatible type, the return type is a 
   634   // member_pointer_caller (see above)
   635 
   636   // Otherwise, return type deduction fails. There is either an error, 
   637   // or the user is trying to call an overloaded ->*
   638   // In such a case either ret<> must be used, or a return_type_2 user 
   639   // defined specialization must be provided
   640 
   641 
   642 template<class A, class B>
   643 struct return_type_2<other_action<member_pointer_action>, A, B> {
   644 private:
   645   typedef typename 
   646     detail::remove_reference_and_cv<B>::type plainB;
   647 public:
   648   typedef typename 
   649     detail::member_pointer_action_helper<
   650       detail::member_pointer<plainB>::is_data_member,
   651       detail::member_pointer<plainB>::is_function_member
   652     >::template return_type<A, B>::type type; 
   653 };
   654 
   655   // this is the way the generic lambda_functor_base functions instantiate
   656   // return type deduction. We turn it into return_type_2, so that the 
   657   // user can provide specializations on that level.
   658 template<class Args>
   659 struct return_type_N<other_action<member_pointer_action>, Args> {
   660   typedef typename boost::tuples::element<0, Args>::type A;
   661   typedef typename boost::tuples::element<1, Args>::type B;
   662   typedef typename 
   663     return_type_2<other_action<member_pointer_action>, 
   664                   typename boost::remove_reference<A>::type, 
   665                   typename boost::remove_reference<B>::type
   666                  >::type type;
   667 };
   668 
   669 
   670 template<class Arg1, class Arg2>
   671 inline const
   672 lambda_functor<
   673   lambda_functor_base<
   674     action<2, other_action<member_pointer_action> >,
   675     tuple<lambda_functor<Arg1>, typename const_copy_argument<Arg2>::type>
   676   >
   677 >
   678 operator->*(const lambda_functor<Arg1>& a1, const Arg2& a2)
   679 {
   680   return 
   681       lambda_functor_base<
   682         action<2, other_action<member_pointer_action> >,
   683         tuple<lambda_functor<Arg1>, typename const_copy_argument<Arg2>::type>
   684       >
   685       (tuple<lambda_functor<Arg1>, 
   686              typename const_copy_argument<Arg2>::type>(a1, a2));
   687 }
   688 
   689 template<class Arg1, class Arg2>
   690 inline const
   691 lambda_functor<
   692   lambda_functor_base<
   693     action<2, other_action<member_pointer_action> >,
   694     tuple<lambda_functor<Arg1>, lambda_functor<Arg2> >
   695   >
   696 >
   697 operator->*(const lambda_functor<Arg1>& a1, const lambda_functor<Arg2>& a2)
   698 {
   699   return 
   700       lambda_functor_base<
   701         action<2, other_action<member_pointer_action> >,
   702         tuple<lambda_functor<Arg1>, lambda_functor<Arg2> >
   703       >
   704     (tuple<lambda_functor<Arg1>, lambda_functor<Arg2> >(a1, a2));
   705 }
   706 
   707 template<class Arg1, class Arg2>
   708 inline const
   709 lambda_functor<
   710   lambda_functor_base<
   711     action<2, other_action<member_pointer_action> >,
   712     tuple<typename const_copy_argument<Arg1>::type, lambda_functor<Arg2> >
   713   >
   714 >
   715 operator->*(const Arg1& a1, const lambda_functor<Arg2>& a2)
   716 {
   717   return 
   718       lambda_functor_base<
   719         action<2, other_action<member_pointer_action> >,
   720         tuple<typename const_copy_argument<Arg1>::type, lambda_functor<Arg2> >
   721       >
   722       (tuple<typename const_copy_argument<Arg1>::type, 
   723              lambda_functor<Arg2> >(a1, a2));
   724 }
   725 
   726 
   727 } // namespace lambda 
   728 } // namespace boost
   729 
   730 
   731 #endif
   732 
   733 
   734 
   735 
   736 
   737