code:
// Boost Lambda Library -- member_ptr.hpp ---------------------

// Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 2000 Gary Powell (gary.powell@sierra.com)
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see www.boost.org

// --------------------------------------------------------------------------

#if !defined(BOOST_LAMBDA_MEMBER_PTR_HPP)
#define BOOST_LAMBDA_MEMBER_PTR_HPP

namespace boost {
namespace lambda {

class member_pointer_action {};

namespace detail {

// the boost type_traits member_pointer traits are not enough,
// need to know more details.
template<class T>
struct member_pointer {
  typedef typename boost::add_reference<T>::type type;
  typedef detail::unspecified class_type;
  typedef detail::unspecified qualified_class_type;
  BOOST_STATIC_CONSTANT(bool, is_data_member = false);
  BOOST_STATIC_CONSTANT(bool, is_function_member = false);
};

template<class T, class U>
struct member_pointer<T U::*> {
  typedef typename boost::add_reference<T>::type type;
  typedef U class_type;
  typedef U qualified_class_type;
  BOOST_STATIC_CONSTANT(bool, is_data_member = true);
  BOOST_STATIC_CONSTANT(bool, is_function_member = false);
};

template<class T, class U>
struct member_pointer<const T U::*> {
  typedef typename boost::add_reference<const T>::type type;
  typedef U class_type;
  typedef const U qualified_class_type;
  BOOST_STATIC_CONSTANT(bool, is_data_member = true);
  BOOST_STATIC_CONSTANT(bool, is_function_member = false);
};

template<class T, class U>
struct member_pointer<volatile T U::*> {
  typedef typename boost::add_reference<volatile T>::type type;
  typedef U class_type;
  typedef volatile U qualified_class_type;
  BOOST_STATIC_CONSTANT(bool, is_data_member = true);
  BOOST_STATIC_CONSTANT(bool, is_function_member = false);
};

template<class T, class U>
struct member_pointer<const volatile T U::*> {
  typedef typename boost::add_reference<const volatile T>::type type;
  typedef U class_type;
  typedef const volatile U qualified_class_type;
  BOOST_STATIC_CONSTANT(bool, is_data_member = true);
  BOOST_STATIC_CONSTANT(bool, is_function_member = false);
};

// -- nonconst member functions --
template<class T, class U>
struct member_pointer<T (U::*)()> {
  typedef T type;
  typedef U class_type;
  typedef U qualified_class_type;
  BOOST_STATIC_CONSTANT(bool, is_data_member = false);
  BOOST_STATIC_CONSTANT(bool, is_function_member = true);
};
template<class T, class U, class A1>
struct member_pointer<T (U::*)(A1)> {
  typedef T type;
  typedef U class_type;
  typedef U qualified_class_type;
  BOOST_STATIC_CONSTANT(bool, is_data_member = false);
  BOOST_STATIC_CONSTANT(bool, is_function_member = true);
};
template<class T, class U, class A1, class A2>
struct member_pointer<T (U::*)(A1, A2)> {
  typedef T type;
  typedef U class_type;
  typedef U qualified_class_type;
  BOOST_STATIC_CONSTANT(bool, is_data_member = false);
  BOOST_STATIC_CONSTANT(bool, is_function_member = true);
};
template<class T, class U, class A1, class A2, class A3>
struct member_pointer<T (U::*)(A1, A2, A3)> {
  typedef T type;
  typedef U class_type;
  typedef U qualified_class_type;
  BOOST_STATIC_CONSTANT(bool, is_data_member = false);
  BOOST_STATIC_CONSTANT(bool, is_function_member = true);
};
template<class T, class U, class A1, class A2, class A3, class A4>
struct member_pointer<T (U::*)(A1, A2, A3, A4)> {
  typedef T type;
  typedef U class_type;
  typedef U qualified_class_type;
  BOOST_STATIC_CONSTANT(bool, is_data_member = false);
  BOOST_STATIC_CONSTANT(bool, is_function_member = true);
};
template<class T, class U, class A1, class A2, class A3, class A4, class A5>
struct member_pointer<T (U::*)(A1, A2, A3, A4, A5)> {
  typedef T type;
  typedef U class_type;
  typedef U qualified_class_type;
  BOOST_STATIC_CONSTANT(bool, is_data_member = false);
  BOOST_STATIC_CONSTANT(bool, is_function_member = true);
};
template<class T, class U, class A1, class A2, class A3, class A4, class A5,
         class A6>
struct member_pointer<T (U::*)(A1, A2, A3, A4, A5, A6)> {
  typedef T type;
  typedef U class_type;
  typedef U qualified_class_type;
  BOOST_STATIC_CONSTANT(bool, is_data_member = false);
  BOOST_STATIC_CONSTANT(bool, is_function_member = true);
};
template<class T, class U, class A1, class A2, class A3, class A4, class A5,
         class A6, class A7>
struct member_pointer<T (U::*)(A1, A2, A3, A4, A5, A6, A7)> {
  typedef T type;
  typedef U class_type;
  typedef U qualified_class_type;
  BOOST_STATIC_CONSTANT(bool, is_data_member = false);
  BOOST_STATIC_CONSTANT(bool, is_function_member = true);
};
template<class T, class U, class A1, class A2, class A3, class A4, class A5,
         class A6, class A7, class A8>
struct member_pointer<T (U::*)(A1, A2, A3, A4, A5, A6, A7, A8)> {
  typedef T type;
  typedef U class_type;
  typedef U qualified_class_type;
  BOOST_STATIC_CONSTANT(bool, is_data_member = false);
  BOOST_STATIC_CONSTANT(bool, is_function_member = true);
};
template<class T, class U, class A1, class A2, class A3, class A4, class A5,
         class A6, class A7, class A8, class A9>
struct member_pointer<T (U::*)(A1, A2, A3, A4, A5, A6, A7, A8, A9)> {
  typedef T type;
  typedef U class_type;
  typedef U qualified_class_type;
  BOOST_STATIC_CONSTANT(bool, is_data_member = false);
  BOOST_STATIC_CONSTANT(bool, is_function_member = true);
};
// -- const member functions --
template<class T, class U>
struct member_pointer<T (U::*)() const> {
  typedef T type;
  typedef U class_type;
  typedef const U qualified_class_type;
  BOOST_STATIC_CONSTANT(bool, is_data_member = false);
  BOOST_STATIC_CONSTANT(bool, is_function_member = true);
};
template<class T, class U, class A1>
struct member_pointer<T (U::*)(A1) const> {
  typedef T type;
  typedef U class_type;
  typedef const U qualified_class_type;
  BOOST_STATIC_CONSTANT(bool, is_data_member = false);
  BOOST_STATIC_CONSTANT(bool, is_function_member = true);
};
template<class T, class U, class A1, class A2>
struct member_pointer<T (U::*)(A1, A2) const> {
  typedef T type;
  typedef U class_type;
  typedef const U qualified_class_type;
  BOOST_STATIC_CONSTANT(bool, is_data_member = false);
  BOOST_STATIC_CONSTANT(bool, is_function_member = true);
};
template<class T, class U, class A1, class A2, class A3>
struct member_pointer<T (U::*)(A1, A2, A3) const> {
  typedef T type;
  typedef U class_type;
  typedef const U qualified_class_type;
  BOOST_STATIC_CONSTANT(bool, is_data_member = false);
  BOOST_STATIC_CONSTANT(bool, is_function_member = true);
};
template<class T, class U, class A1, class A2, class A3, class A4>
struct member_pointer<T (U::*)(A1, A2, A3, A4) const> {
  typedef T type;
  typedef U class_type;
  typedef const U qualified_class_type;
  BOOST_STATIC_CONSTANT(bool, is_data_member = false);
  BOOST_STATIC_CONSTANT(bool, is_function_member = true);
};
template<class T, class U, class A1, class A2, class A3, class A4, class A5>
struct member_pointer<T (U::*)(A1, A2, A3, A4, A5) const> {
  typedef T type;
  typedef U class_type;
  typedef const U qualified_class_type;
  BOOST_STATIC_CONSTANT(bool, is_data_member = false);
  BOOST_STATIC_CONSTANT(bool, is_function_member = true);
};
template<class T, class U, class A1, class A2, class A3, class A4, class A5,
         class A6>
struct member_pointer<T (U::*)(A1, A2, A3, A4, A5, A6) const> {
  typedef T type;
  typedef U class_type;
  typedef const U qualified_class_type;
  BOOST_STATIC_CONSTANT(bool, is_data_member = false);
  BOOST_STATIC_CONSTANT(bool, is_function_member = true);
};
template<class T, class U, class A1, class A2, class A3, class A4, class A5,
         class A6, class A7>
struct member_pointer<T (U::*)(A1, A2, A3, A4, A5, A6, A7) const> {
  typedef T type;
  typedef U class_type;
  typedef const U qualified_class_type;
  BOOST_STATIC_CONSTANT(bool, is_data_member = false);
  BOOST_STATIC_CONSTANT(bool, is_function_member = true);
};
template<class T, class U, class A1, class A2, class A3, class A4, class A5,
         class A6, class A7, class A8>
struct member_pointer<T (U::*)(A1, A2, A3, A4, A5, A6, A7, A8) const> {
  typedef T type;
  typedef U class_type;
  typedef const U qualified_class_type;
  BOOST_STATIC_CONSTANT(bool, is_data_member = false);
  BOOST_STATIC_CONSTANT(bool, is_function_member = true);
};
template<class T, class U, class A1, class A2, class A3, class A4, class A5,
         class A6, class A7, class A8, class A9>
struct member_pointer<T (U::*)(A1, A2, A3, A4, A5, A6, A7, A8, A9) const> {
  typedef T type;
  typedef U class_type;
  typedef const U qualified_class_type;
  BOOST_STATIC_CONSTANT(bool, is_data_member = false);
  BOOST_STATIC_CONSTANT(bool, is_function_member = true);
};
  // -- volatile --
template<class T, class U>
struct member_pointer<T (U::*)() volatile> {
  typedef T type;
  typedef U class_type;
  typedef volatile U qualified_class_type;
  BOOST_STATIC_CONSTANT(bool, is_data_member = false);
  BOOST_STATIC_CONSTANT(bool, is_function_member = true);
};
template<class T, class U, class A1>
struct member_pointer<T (U::*)(A1) volatile> {
  typedef T type;
  typedef U class_type;
  typedef volatile U qualified_class_type;
  BOOST_STATIC_CONSTANT(bool, is_data_member = false);
  BOOST_STATIC_CONSTANT(bool, is_function_member = true);
};
template<class T, class U, class A1, class A2>
struct member_pointer<T (U::*)(A1, A2) volatile> {
  typedef T type;
  typedef U class_type;
  typedef volatile U qualified_class_type;
  BOOST_STATIC_CONSTANT(bool, is_data_member = false);
  BOOST_STATIC_CONSTANT(bool, is_function_member = true);
};
template<class T, class U, class A1, class A2, class A3>
struct member_pointer<T (U::*)(A1, A2, A3) volatile> {
  typedef T type;
  typedef U class_type;
  typedef volatile U qualified_class_type;
  BOOST_STATIC_CONSTANT(bool, is_data_member = false);
  BOOST_STATIC_CONSTANT(bool, is_function_member = true);
};
template<class T, class U, class A1, class A2, class A3, class A4>
struct member_pointer<T (U::*)(A1, A2, A3, A4) volatile> {
  typedef T type;
  typedef U class_type;
  typedef volatile U qualified_class_type;
  BOOST_STATIC_CONSTANT(bool, is_data_member = false);
  BOOST_STATIC_CONSTANT(bool, is_function_member = true);
};
template<class T, class U, class A1, class A2, class A3, class A4, class A5>
struct member_pointer<T (U::*)(A1, A2, A3, A4, A5) volatile> {
  typedef T type;
  typedef U class_type;
  typedef volatile U qualified_class_type;
  BOOST_STATIC_CONSTANT(bool, is_data_member = false);
  BOOST_STATIC_CONSTANT(bool, is_function_member = true);
};
template<class T, class U, class A1, class A2, class A3, class A4, class A5,
         class A6>
struct member_pointer<T (U::*)(A1, A2, A3, A4, A5, A6) volatile> {
  typedef T type;
  typedef U class_type;
  typedef volatile U qualified_class_type;
  BOOST_STATIC_CONSTANT(bool, is_data_member = false);
  BOOST_STATIC_CONSTANT(bool, is_function_member = true);
};
template<class T, class U, class A1, class A2, class A3, class A4, class A5,
         class A6, class A7>
struct member_pointer<T (U::*)(A1, A2, A3, A4, A5, A6, A7) volatile> {
  typedef T type;
  typedef U class_type;
  typedef volatile U qualified_class_type;
  BOOST_STATIC_CONSTANT(bool, is_data_member = false);
  BOOST_STATIC_CONSTANT(bool, is_function_member = true);
};
template<class T, class U, class A1, class A2, class A3, class A4, class A5,
         class A6, class A7, class A8>
struct member_pointer<T (U::*)(A1, A2, A3, A4, A5, A6, A7, A8) volatile> {
  typedef T type;
  typedef U class_type;
  typedef volatile U qualified_class_type;
  BOOST_STATIC_CONSTANT(bool, is_data_member = false);
  BOOST_STATIC_CONSTANT(bool, is_function_member = true);
};
template<class T, class U, class A1, class A2, class A3, class A4, class A5,
         class A6, class A7, class A8, class A9>
struct member_pointer<T (U::*)(A1, A2, A3, A4, A5, A6, A7, A8, A9) volatile> {
  typedef T type;
  typedef U class_type;
  typedef volatile U qualified_class_type;
  BOOST_STATIC_CONSTANT(bool, is_data_member = false);
  BOOST_STATIC_CONSTANT(bool, is_function_member = true);
};
  // -- const volatile
template<class T, class U>
struct member_pointer<T (U::*)() const volatile> {
  typedef T type;
  typedef U class_type;
  typedef const volatile U qualified_class_type;
  BOOST_STATIC_CONSTANT(bool, is_data_member = false);
  BOOST_STATIC_CONSTANT(bool, is_function_member = true);
};
template<class T, class U, class A1>
struct member_pointer<T (U::*)(A1) const volatile> {
  typedef T type;
  typedef U class_type;
  typedef const volatile U qualified_class_type;
  BOOST_STATIC_CONSTANT(bool, is_data_member = false);
  BOOST_STATIC_CONSTANT(bool, is_function_member = true);
};
template<class T, class U, class A1, class A2>
struct member_pointer<T (U::*)(A1, A2) const volatile> {
  typedef T type;
  typedef U class_type;
  typedef const volatile U qualified_class_type;
  BOOST_STATIC_CONSTANT(bool, is_data_member = false);
  BOOST_STATIC_CONSTANT(bool, is_function_member = true);
};
template<class T, class U, class A1, class A2, class A3>
struct member_pointer<T (U::*)(A1, A2, A3) const volatile> {
  typedef T type;
  typedef U class_type;
  typedef const volatile U qualified_class_type;
  BOOST_STATIC_CONSTANT(bool, is_data_member = false);
  BOOST_STATIC_CONSTANT(bool, is_function_member = true);
};
template<class T, class U, class A1, class A2, class A3, class A4>
struct member_pointer<T (U::*)(A1, A2, A3, A4) const volatile> {
  typedef T type;
  typedef U class_type;
  typedef const volatile U qualified_class_type;
};
template<class T, class U, class A1, class A2, class A3, class A4, class A5>
struct member_pointer<T (U::*)(A1, A2, A3, A4, A5) const volatile> {
  typedef T type;
  typedef U class_type;
  typedef const volatile U qualified_class_type;
  BOOST_STATIC_CONSTANT(bool, is_data_member = false);
  BOOST_STATIC_CONSTANT(bool, is_function_member = true);
};
template<class T, class U, class A1, class A2, class A3, class A4, class A5,
         class A6>
struct member_pointer<T (U::*)(A1, A2, A3, A4, A5, A6) const volatile> {
  typedef T type;
  typedef U class_type;
  typedef const volatile U qualified_class_type;
  BOOST_STATIC_CONSTANT(bool, is_data_member = false);
  BOOST_STATIC_CONSTANT(bool, is_function_member = true);
};
template<class T, class U, class A1, class A2, class A3, class A4, class A5,
         class A6, class A7>
struct member_pointer<T (U::*)(A1, A2, A3, A4, A5, A6, A7) const volatile> {
  typedef T type;
  typedef U class_type;
  typedef const volatile U qualified_class_type;
  BOOST_STATIC_CONSTANT(bool, is_data_member = false);
  BOOST_STATIC_CONSTANT(bool, is_function_member = true);
};
template<class T, class U, class A1, class A2, class A3, class A4, class A5,
         class A6, class A7, class A8>
struct member_pointer<T (U::*)(A1, A2, A3, A4, A5, A6, A7, A8) const volatile> {
  typedef T type;
  typedef U class_type;
  typedef const volatile U qualified_class_type;
  BOOST_STATIC_CONSTANT(bool, is_data_member = false);
  BOOST_STATIC_CONSTANT(bool, is_function_member = true);
};
template<class T, class U, class A1, class A2, class A3, class A4, class A5,
         class A6, class A7, class A8, class A9>
struct member_pointer<T (U::*)(A1, A2, A3, A4, A5, A6, A7, A8, A9) const volatile> {
  typedef T type;
  typedef U class_type;
  typedef const volatile U qualified_class_type;
  BOOST_STATIC_CONSTANT(bool, is_data_member = false);
  BOOST_STATIC_CONSTANT(bool, is_function_member = true);
};

} // detail

namespace detail {

  // this class holds a pointer to a member function and the object.
  // when called, it just calls the member function with the parameters
  // provided

  // It would have been possible to use existing lambda_functors to represent
  // a bound member function like this, but to have a separate template is
  // safer, since now this functor doesn't mix and match with lambda_functors
  // only thing you can do with this is to call it

  // note that previously instantiated classes
  // (other_action<member_pointer_action> and member_pointer_action_helper
  // guarantee, that A and B are
  // such types, that for objects a and b of corresponding types, a->*b leads
  // to the builtin ->* to be called. So types that would end in a  call to
  // a user defined ->* do not create a member_pointer_caller object.

template<class RET, class A, class B>
class member_pointer_caller {
  A a; B b;

public:
  member_pointer_caller(const A& aa, const B& bb) : a(aa), b(bb) {}

  RET operator()() const { return (a->*b)(); }

  template<class A1>
  RET operator()(const A1& a1) const { return (a->*b)(a1); }

  template<class A1, class A2>
  RET operator()(const A1& a1, const A2& a2) const { return (a->*b)(a1, a2); }

  template<class A1, class A2, class A3>
  RET operator()(const A1& a1, const A2& a2, const A3& a3) const {
    return (a->*b)(a1, a2, a3);
  }

  template<class A1, class A2, class A3, class A4>
  RET operator()(const A1& a1, const A2& a2, const A3& a3,
                 const A4& a4) const {
    return (a->*b)(a1, a2, a3, a4);
  }

  template<class A1, class A2, class A3, class A4, class A5>
  RET operator()(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
                 const A5& a5) const {
    return (a->*b)(a1, a2, a3, a4, a5);
  }

  template<class A1, class A2, class A3, class A4, class A5, class A6>
  RET operator()(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
                 const A5& a5, const A6& a6) const {
    return (a->*b)(a1, a2, a3, a4, a5, a6);
  }

  template<class A1, class A2, class A3, class A4, class A5, class A6,
           class A7>
  RET operator()(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
                 const A5& a5, const A6& a6, const A7& a7) const {
    return (a->*b)(a1, a2, a3, a4, a5, a6, a7);
  }

  template<class A1, class A2, class A3, class A4, class A5, class A6,
           class A7, class A8>
  RET operator()(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
                 const A5& a5, const A6& a6, const A7& a7,
                 const A8& a8) const {
    return (a->*b)(a1, a2, a3, a4, a5, a6, a7, a8);
  }

  template<class A1, class A2, class A3, class A4, class A5, class A6,
           class A7, class A8, class A9>
  RET operator()(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
                 const A5& a5, const A6& a6, const A7& a7,
                 const A8& a8, const A9& a9) const {
    return (a->*b)(a1, a2, a3, a4, a5, a6, a7, a8, a9);
  }

};

// helper templates for return type deduction and action classes
// different cases for data member, function member, neither

// true-true case
template <bool Is_data_member, bool Is_function_member>
struct member_pointer_action_helper;
  // cannot be both, no body provided

  // data member case
  // this means, that B is a data member and A is a pointer type,
  // so either built-in ->* should be called, or there is an error
template <>
struct member_pointer_action_helper<true, false> {
public:

  template<class RET, class A, class B>
  static RET apply(A& a, B& b) {
    return a->*b;
  }

  template<class A, class B>
  struct return_type {
  private:
    typedef typename detail::remove_reference_and_cv<B>::type plainB;

    typedef typename detail::member_pointer<plainB>::type type0;
    // we remove the reference now, as we may have to add cv:s
    typedef typename boost::remove_reference<type0>::type type1;

    // A is a reference to pointer
    // remove the top level cv qualifiers and reference
    typedef typename
      detail::remove_reference_and_cv<A>::type non_ref_A;

    // A is a pointer type, so take the type pointed to
    typedef typename ::boost::remove_pointer<non_ref_A>::type non_pointer_A;

  public:
    // For non-reference types, we must add const and/or volatile if
    // the pointer type has these qualifiers
    // If the member is a reference, these do not have any effect
    //   (cv T == T if T is a reference type)
    typedef typename detail::IF<
      ::boost::is_const<non_pointer_A>::value,
      typename ::boost::add_const<type1>::type,
      type1
    >::RET type2;
    typedef typename detail::IF<
      ::boost::is_volatile<non_pointer_A>::value,
      typename ::boost::add_volatile<type2>::type,
      type2
    >::RET type3;
    // add reference back
    typedef typename ::boost::add_reference<type3>::type type;
  };
};

  // neither case
template <>
struct member_pointer_action_helper<false, false> {
public:
  template<class RET, class A, class B>
  static RET apply(A& a, B& b) {
// not a built in member pointer operator, just call ->*
    return a->*b;
  }
  // an overloaded member pointer operators, user should have specified
  // the return type
  // At this point we know that there is no matching specialization for
  // return_type_2, so try return_type_2_plain
  template<class A, class B>
  struct return_type {

    typedef typename plain_return_type_2<
      other_action<member_pointer_action>, A, B
    >::type type;
  };

};

// member pointer function case
// This is a built in ->* call for a member function,
// the only thing that you can do with that, is to give it some arguments
// note, it is guaranteed that A is a pointer type, and thus it cannot
// be a call to overloaded ->*
template <>
struct member_pointer_action_helper<false, true> {
  public:

  template<class RET, class A, class B>
  static RET apply(A& a, B& b) {
    typedef typename ::boost::remove_cv<B>::type plainB;
    typedef typename detail::member_pointer<plainB>::type ret_t;
    typedef typename ::boost::remove_cv<A>::type plainA;

    // we always strip cv:s to
    // make the two routes (calling and type deduction)
    // to give the same results (and the const does not make any functional
    // difference)
    return detail::member_pointer_caller<ret_t, plainA, plainB>(a, b);
  }

  template<class A, class B>
  struct return_type {
    typedef typename detail::remove_reference_and_cv<B>::type plainB;
    typedef typename detail::member_pointer<plainB>::type ret_t;
    typedef typename detail::remove_reference_and_cv<A>::type plainA;

    typedef detail::member_pointer_caller<ret_t, plainA, plainB> type;
  };
};

} // detail

template<> class other_action<member_pointer_action>  {
public:
  template<class RET, class A, class B>
  static RET apply(A& a, B& b) {
    typedef typename
      ::boost::remove_cv<B>::type plainB;

    return detail::member_pointer_action_helper<
        boost::is_pointer<A>::value &&
          detail::member_pointer<plainB>::is_data_member,
        boost::is_pointer<A>::value &&
          detail::member_pointer<plainB>::is_function_member
      >::template apply<RET>(a, b);
    }
};

  // return type deduction --

  // If the right argument is a pointer to data member,
  // and the left argument is of compatible pointer to class type
  // return type is a reference to the data member type

  // if right argument is a pointer to a member function, and the left
  // argument is of a compatible type, the return type is a
  // member_pointer_caller (see above)

  // Otherwise, return type deduction fails. There is either an error,
  // or the user is trying to call an overloaded ->*
  // In such a case either ret<> must be used, or a return_type_2 user
  // defined specialization must be provided

template<class A, class B>
struct return_type_2<other_action<member_pointer_action>, A, B> {
private:
  typedef typename
    detail::remove_reference_and_cv<B>::type plainB;
public:
  typedef typename
    detail::member_pointer_action_helper<
      detail::member_pointer<plainB>::is_data_member,
      detail::member_pointer<plainB>::is_function_member
    >::template return_type<A, B>::type type;
};

  // this is the way the generic lambda_functor_base functions instantiate
  // return type deduction. We turn it into return_type_2, so that the
  // user can provide specializations on that level.
template<class Args>
struct return_type_N<other_action<member_pointer_action>, Args> {
  typedef typename boost::tuples::element<0, Args>::type A;
  typedef typename boost::tuples::element<1, Args>::type B;
  typedef typename
    return_type_2<other_action<member_pointer_action>,
                  typename boost::remove_reference<A>::type,
                  typename boost::remove_reference<B>::type
                 >::type type;
};

template<class Arg1, class Arg2>
inline const
lambda_functor<
  lambda_functor_base<
    action<2, other_action<member_pointer_action> >,
    tuple<lambda_functor<Arg1>, typename const_copy_argument<Arg2>::type>
  >
>
operator->*(const lambda_functor<Arg1>& a1, const Arg2& a2)
{
  return
      lambda_functor_base<
        action<2, other_action<member_pointer_action> >,
        tuple<lambda_functor<Arg1>, typename const_copy_argument<Arg2>::type>
      >
      (tuple<lambda_functor<Arg1>,
             typename const_copy_argument<Arg2>::type>(a1, a2));
}

template<class Arg1, class Arg2>
inline const
lambda_functor<
  lambda_functor_base<
    action<2, other_action<member_pointer_action> >,
    tuple<lambda_functor<Arg1>, lambda_functor<Arg2> >
  >
>
operator->*(const lambda_functor<Arg1>& a1, const lambda_functor<Arg2>& a2)
{
  return
      lambda_functor_base<
        action<2, other_action<member_pointer_action> >,
        tuple<lambda_functor<Arg1>, lambda_functor<Arg2> >
      >
    (tuple<lambda_functor<Arg1>, lambda_functor<Arg2> >(a1, a2));
}

template<class Arg1, class Arg2>
inline const
lambda_functor<
  lambda_functor_base<
    action<2, other_action<member_pointer_action> >,
    tuple<typename const_copy_argument<Arg1>::type, lambda_functor<Arg2> >
  >
>
operator->*(const Arg1& a1, const lambda_functor<Arg2>& a2)
{
  return
      lambda_functor_base<
        action<2, other_action<member_pointer_action> >,
        tuple<typename const_copy_argument<Arg1>::type, lambda_functor<Arg2> >
      >
      (tuple<typename const_copy_argument<Arg1>::type,
             lambda_functor<Arg2> >(a1, a2));
}

} // namespace lambda
} // namespace boost

#endif


code:
// -- operator_actions.hpp - Boost Lambda Library ----------------------

// Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)

// For more information, see http://lambda.cs.utu.fi

#ifndef BOOST_LAMBDA_OPERATOR_ACTIONS_HPP
#define BOOST_LAMBDA_OPERATOR_ACTIONS_HPP

namespace boost {
namespace lambda {

// -- artihmetic ----------------------

class plus_action {};
class minus_action {};
class multiply_action {};
class divide_action {};
class remainder_action {};

// -- bitwise  -------------------

class leftshift_action {};
class rightshift_action {};
class xor_action {};

// -- bitwise/logical -------------------

class and_action {};
class or_action {};
class not_action {};

// -- relational -------------------------

class less_action {};
class greater_action {};
class lessorequal_action {};
class greaterorequal_action {};
class equal_action {};
class notequal_action {};

// -- increment/decrement ------------------------------

class increment_action {};
class decrement_action {};

// -- void return ------------------------------

// -- other  ------------------------------

class addressof_action {};
  // class comma_action {}; // defined in actions.hpp
class contentsof_action {};
// class member_pointer_action {}; (defined in member_ptr.hpp)

// -- actioun group templates --------------------

template <class Action> class arithmetic_action;
template <class Action> class bitwise_action;
template <class Action> class logical_action;
template <class Action> class relational_action;
template <class Action> class arithmetic_assignment_action;
template <class Action> class bitwise_assignment_action;
template <class Action> class unary_arithmetic_action;
template <class Action> class pre_increment_decrement_action;
template <class Action> class post_increment_decrement_action;

// ---------------------------------------------------------

  // actions, for which the existence of protect is checked in return type
  // deduction.

template <class Act> struct is_protectable<arithmetic_action<Act> > {
  BOOST_STATIC_CONSTANT(bool, value = true);
};
template <class Act> struct is_protectable<bitwise_action<Act> > {
  BOOST_STATIC_CONSTANT(bool, value = true);
};
template <class Act> struct is_protectable<logical_action<Act> > {
  BOOST_STATIC_CONSTANT(bool, value = true);
};
template <class Act> struct is_protectable<relational_action<Act> > {
  BOOST_STATIC_CONSTANT(bool, value = true);
};
template <class Act>
struct is_protectable<arithmetic_assignment_action<Act> > {
  BOOST_STATIC_CONSTANT(bool, value = true);
};
template <class Act> struct is_protectable<bitwise_assignment_action<Act> > {
  BOOST_STATIC_CONSTANT(bool, value = true);
};
template <class Act> struct is_protectable<unary_arithmetic_action<Act> > {
  BOOST_STATIC_CONSTANT(bool, value = true);
};
template <class Act>
struct is_protectable<pre_increment_decrement_action<Act> > {
  BOOST_STATIC_CONSTANT(bool, value = true);
};
template <class Act> struct
is_protectable<post_increment_decrement_action<Act> > {
  BOOST_STATIC_CONSTANT(bool, value = true);
};

template <> struct is_protectable<other_action<addressof_action> > {
  BOOST_STATIC_CONSTANT(bool, value = true);
};
template <> struct is_protectable<other_action<contentsof_action> > {
  BOOST_STATIC_CONSTANT(bool, value = true);
};

template<> struct is_protectable<other_action<subscript_action> > {
  BOOST_STATIC_CONSTANT(bool, value = true);
};
template<> struct is_protectable<other_action<assignment_action> > {
  BOOST_STATIC_CONSTANT(bool, value = true);
};

// NOTE: comma action is also protectable, but the specialization is
  // in actions.hpp

} // namespace lambda
} // namespace boost

#endif

license: mit


code:
// Boost Lambda Library  - operator_lambda_func_base.hpp -----------------
//
// Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see www.boost.org

// ------------------------------------------------------------

#ifndef BOOST_LAMBDA_OPERATOR_LAMBDA_FUNC_BASE_HPP
#define BOOST_LAMBDA_OPERATOR_LAMBDA_FUNC_BASE_HPP

namespace boost {
namespace lambda {

// These operators cannot be implemented as apply functions of action
// templates

// Specialization for comma.
template<class Args>
class lambda_functor_base<other_action<comma_action>, Args> {
public:
  Args args;
public:
  explicit lambda_functor_base(const Args& a) : args(a) {}

  template<class RET, CALL_TEMPLATE_ARGS>
  RET call(CALL_FORMAL_ARGS) const {
    return detail::select(boost::tuples::get<0>(args), CALL_ACTUAL_ARGS),
           detail::select(boost::tuples::get<1>(args), CALL_ACTUAL_ARGS);
  }

  template<class SigArgs> struct sig {
  private:
    typedef typename
      detail::deduce_argument_types<Args, SigArgs>::type rets_t;
  public:
    typedef typename return_type_2_comma< // comma needs special handling
      typename detail::element_or_null<0, rets_t>::type,
      typename detail::element_or_null<1, rets_t>::type
    >::type type;
  };

};

namespace detail {

// helper traits to make the expression shorter, takes binary action
// bound argument tuple, open argument tuple and gives the return type

template<class Action, class Bound, class Open> class binary_rt {
  private:
    typedef typename
      detail::deduce_argument_types<Bound, Open>::type rets_t;
  public:
    typedef typename return_type_2_prot<
      Action,
      typename detail::element_or_null<0, rets_t>::type,
      typename detail::element_or_null<1, rets_t>::type
    >::type type;
};

  // same for unary actions
template<class Action, class Bound, class Open> class unary_rt {
  private:
    typedef typename
      detail::deduce_argument_types<Bound, Open>::type rets_t;
  public:
    typedef typename return_type_1_prot<
      Action,
      typename detail::element_or_null<0, rets_t>::type
    >::type type;
};

} // end detail

// Specialization for logical and (to preserve shortcircuiting)
// this could be done with a macro as the others, code used to be different
template<class Args>
class lambda_functor_base<logical_action<and_action>, Args> {
public:
  Args args;
public:
  explicit lambda_functor_base(const Args& a) : args(a) {}

  template<class RET, CALL_TEMPLATE_ARGS>
  RET call(CALL_FORMAL_ARGS) const {
    return detail::select(boost::tuples::get<0>(args), CALL_ACTUAL_ARGS) &&
           detail::select(boost::tuples::get<1>(args), CALL_ACTUAL_ARGS);
  }
  template<class SigArgs> struct sig {
    typedef typename
      detail::binary_rt<logical_action<and_action>, Args, SigArgs>::type type;
  };
};

// Specialization for logical or (to preserve shortcircuiting)
// this could be done with a macro as the others, code used to be different
template<class Args>
class lambda_functor_base<logical_action< or_action>, Args> {
public:
  Args args;
public:
  explicit lambda_functor_base(const Args& a) : args(a) {}

  template<class RET, CALL_TEMPLATE_ARGS>
  RET call(CALL_FORMAL_ARGS) const {
    return detail::select(boost::tuples::get<0>(args), CALL_ACTUAL_ARGS) ||
           detail::select(boost::tuples::get<1>(args), CALL_ACTUAL_ARGS);
  }

  template<class SigArgs> struct sig {
    typedef typename
      detail::binary_rt<logical_action<or_action>, Args, SigArgs>::type type;
  };
};

// Specialization for subscript
template<class Args>
class lambda_functor_base<other_action<subscript_action>, Args> {
public:
  Args args;
public:
  explicit lambda_functor_base(const Args& a) : args(a) {}

  template<class RET, CALL_TEMPLATE_ARGS>
  RET call(CALL_FORMAL_ARGS) const {
    return detail::select(boost::tuples::get<0>(args), CALL_ACTUAL_ARGS)
           [detail::select(boost::tuples::get<1>(args), CALL_ACTUAL_ARGS)];
  }

  template<class SigArgs> struct sig {
    typedef typename
      detail::binary_rt<other_action<subscript_action>, Args, SigArgs>::type
        type;
  };
};

#define BOOST_LAMBDA_BINARY_ACTION(SYMBOL, ACTION_CLASS)  \
template<class Args>                                                      \
class lambda_functor_base<ACTION_CLASS, Args> {                           \
public:                                                                   \
  Args args;                                                              \
public:                                                                   \
  explicit lambda_functor_base(const Args& a) : args(a) {}                \
                                                                          \
  template<class RET, CALL_TEMPLATE_ARGS>                                 \
  RET call(CALL_FORMAL_ARGS) const {                                      \
    return detail::select(boost::tuples::get<0>(args), CALL_ACTUAL_ARGS)  \
           SYMBOL                                                         \
           detail::select(boost::tuples::get<1>(args), CALL_ACTUAL_ARGS); \
  }                                                                       \
  template<class SigArgs> struct sig {                                    \
    typedef typename                                                      \
      detail::binary_rt<ACTION_CLASS, Args, SigArgs>::type type;          \
  };                                                                      \
};

#define BOOST_LAMBDA_PREFIX_UNARY_ACTION(SYMBOL, ACTION_CLASS)            \
template<class Args>                                                      \
class lambda_functor_base<ACTION_CLASS, Args> {                           \
public:                                                                   \
  Args args;                                                              \
public:                                                                   \
  explicit lambda_functor_base(const Args& a) : args(a) {}                \
                                                                          \
  template<class RET, CALL_TEMPLATE_ARGS>                                 \
  RET call(CALL_FORMAL_ARGS) const {                                      \
    return SYMBOL                                                         \
           detail::select(boost::tuples::get<0>(args), CALL_ACTUAL_ARGS); \
  }                                                                       \
  template<class SigArgs> struct sig {                                    \
    typedef typename                                                      \
      detail::unary_rt<ACTION_CLASS, Args, SigArgs>::type type;           \
  };                                                                      \
};

#define BOOST_LAMBDA_POSTFIX_UNARY_ACTION(SYMBOL, ACTION_CLASS)           \
template<class Args>                                                      \
class lambda_functor_base<ACTION_CLASS, Args> {                           \
public:                                                                   \
  Args args;                                                              \
public:                                                                   \
  explicit lambda_functor_base(const Args& a) : args(a) {}                \
                                                                          \
  template<class RET, CALL_TEMPLATE_ARGS>                                 \
  RET call(CALL_FORMAL_ARGS) const {                                      \
    return                                                                \
    detail::select(boost::tuples::get<0>(args), CALL_ACTUAL_ARGS) SYMBOL; \
  }                                                                       \
  template<class SigArgs> struct sig {                                    \
    typedef typename                                                      \
      detail::unary_rt<ACTION_CLASS, Args, SigArgs>::type type;           \
  };                                                                      \
};

BOOST_LAMBDA_BINARY_ACTION(+,arithmetic_action<plus_action>)
BOOST_LAMBDA_BINARY_ACTION(-,arithmetic_action<minus_action>)
BOOST_LAMBDA_BINARY_ACTION(*,arithmetic_action<multiply_action>)
BOOST_LAMBDA_BINARY_ACTION(/,arithmetic_action<divide_action>)
BOOST_LAMBDA_BINARY_ACTION(%,arithmetic_action<remainder_action>)

BOOST_LAMBDA_BINARY_ACTION(<<,bitwise_action<leftshift_action>)
BOOST_LAMBDA_BINARY_ACTION(>>,bitwise_action<rightshift_action>)
BOOST_LAMBDA_BINARY_ACTION(&,bitwise_action<and_action>)
BOOST_LAMBDA_BINARY_ACTION(|,bitwise_action<or_action>)
BOOST_LAMBDA_BINARY_ACTION(^,bitwise_action<xor_action>)

BOOST_LAMBDA_BINARY_ACTION(<,relational_action<less_action>)
BOOST_LAMBDA_BINARY_ACTION(>,relational_action<greater_action>)
BOOST_LAMBDA_BINARY_ACTION(<=,relational_action<lessorequal_action>)
BOOST_LAMBDA_BINARY_ACTION(>=,relational_action<greaterorequal_action>)
BOOST_LAMBDA_BINARY_ACTION(==,relational_action<equal_action>)
BOOST_LAMBDA_BINARY_ACTION(!=,relational_action<notequal_action>)

BOOST_LAMBDA_BINARY_ACTION(+=,arithmetic_assignment_action<plus_action>)
BOOST_LAMBDA_BINARY_ACTION(-=,arithmetic_assignment_action<minus_action>)
BOOST_LAMBDA_BINARY_ACTION(*=,arithmetic_assignment_action<multiply_action>)
BOOST_LAMBDA_BINARY_ACTION(/=,arithmetic_assignment_action<divide_action>)
BOOST_LAMBDA_BINARY_ACTION(%=,arithmetic_assignment_action<remainder_action>)

BOOST_LAMBDA_BINARY_ACTION(<<=,bitwise_assignment_action<leftshift_action>)
BOOST_LAMBDA_BINARY_ACTION(>>=,bitwise_assignment_action<rightshift_action>)
BOOST_LAMBDA_BINARY_ACTION(&=,bitwise_assignment_action<and_action>)
BOOST_LAMBDA_BINARY_ACTION(|=,bitwise_assignment_action<or_action>)
BOOST_LAMBDA_BINARY_ACTION(^=,bitwise_assignment_action<xor_action>)

BOOST_LAMBDA_BINARY_ACTION(=,other_action< assignment_action>)

BOOST_LAMBDA_PREFIX_UNARY_ACTION(+, unary_arithmetic_action<plus_action>)
BOOST_LAMBDA_PREFIX_UNARY_ACTION(-, unary_arithmetic_action<minus_action>)
BOOST_LAMBDA_PREFIX_UNARY_ACTION(~, bitwise_action<not_action>)
BOOST_LAMBDA_PREFIX_UNARY_ACTION(!, logical_action<not_action>)
BOOST_LAMBDA_PREFIX_UNARY_ACTION(++, pre_increment_decrement_action<increment_action>)
BOOST_LAMBDA_PREFIX_UNARY_ACTION(--, pre_increment_decrement_action<decrement_action>)

BOOST_LAMBDA_PREFIX_UNARY_ACTION(&,other_action<addressof_action>)
BOOST_LAMBDA_PREFIX_UNARY_ACTION(*,other_action<contentsof_action>)

BOOST_LAMBDA_POSTFIX_UNARY_ACTION(++, post_increment_decrement_action<increment_action>)
BOOST_LAMBDA_POSTFIX_UNARY_ACTION(--, post_increment_decrement_action<decrement_action>)

#undef BOOST_LAMBDA_POSTFIX_UNARY_ACTION
#undef BOOST_LAMBDA_PREFIX_UNARY_ACTION
#undef BOOST_LAMBDA_BINARY_ACTION

} // namespace lambda
} // namespace boost

#endif


code:
//  operator_return_type_traits.hpp -- Boost Lambda Library ------------------

// Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see www.boost.org

#ifndef BOOST_LAMBDA_OPERATOR_RETURN_TYPE_TRAITS_HPP
#define BOOST_LAMBDA_OPERATOR_RETURN_TYPE_TRAITS_HPP

#include "boost/lambda/detail/is_instance_of.hpp"
#include "boost/type_traits/is_same.hpp"
#include "boost/type_traits/is_pointer.hpp"
#include "boost/type_traits/is_float.hpp"
#include "boost/type_traits/is_convertible.hpp"
#include "boost/type_traits/remove_pointer.hpp"
#include "boost/type_traits/remove_const.hpp"
#include "boost/type_traits/remove_reference.hpp"

#include "boost/indirect_reference.hpp"
#include "boost/detail/container_fwd.hpp"

#include <cstddef> // needed for the ptrdiff_t
#include <iosfwd>  // for istream and ostream

#include <iterator> // needed for operator&

namespace boost {
namespace lambda {
namespace detail {

// -- general helper templates for type deduction ------------------

// Much of the type deduction code for standard arithmetic types from Gary Powell

template <class A> struct promote_code { static const int value = -1; };
// this means that a code is not defined for A

// -- the next 5 types are needed in if_then_else_return
// the promotion order is not important, but they must have distinct values.
template <> struct promote_code<bool> { static const int value = 10; };
template <> struct promote_code<char> { static const int value = 20; };
template <> struct promote_code<unsigned char> { static const int value = 30; };
template <> struct promote_code<signed char> { static const int value = 40; };
template <> struct promote_code<short int> { static const int value = 50; };
// ----------

template <> struct promote_code<int> { static const int value = 100; };
template <> struct promote_code<unsigned int> { static const int value = 200; };
template <> struct promote_code<long> { static const int value = 300; };
template <> struct promote_code<unsigned long> { static const int value = 400; };

template <> struct promote_code<float> { static const int value = 500; };
template <> struct promote_code<double> { static const int value = 600; };
template <> struct promote_code<long double> { static const int value = 700; };

// TODO: wchar_t

// forward delcaration of complex.

} // namespace detail
} // namespace lambda
} // namespace boost

namespace boost {
namespace lambda {
namespace detail {

template <> struct promote_code< std::complex<float> > { static const int value = 800; };
template <> struct promote_code< std::complex<double> > { static const int value = 900; };
template <> struct promote_code< std::complex<long double> > { static const int value = 1000; };

// -- int promotion -------------------------------------------
template <class T> struct promote_to_int { typedef T type; };

template <> struct promote_to_int<bool> { typedef int type; };
template <> struct promote_to_int<char> { typedef int type; };
template <> struct promote_to_int<unsigned char> { typedef int type; };
template <> struct promote_to_int<signed char> { typedef int type; };
template <> struct promote_to_int<short int> { typedef int type; };

// The unsigned short int promotion rule is this:
// unsigned short int to signed int if a signed int can hold all values
// of unsigned short int, otherwise go to unsigned int.
template <> struct promote_to_int<unsigned short int>
{
        typedef
                detail::IF<sizeof(int) <= sizeof(unsigned short int),
// I had the logic reversed but ">" messes up the parsing.
                unsigned int,
                int>::RET type;
};

// TODO: think, should there be default behaviour for non-standard types?

} // namespace detail

// ------------------------------------------
// Unary actions ----------------------------
// ------------------------------------------

template<class Act, class A>
struct plain_return_type_1 {
  typedef detail::unspecified type;
};

template<class Act, class A>
struct plain_return_type_1<unary_arithmetic_action<Act>, A> {
  typedef A type;
};

template<class Act, class A>
struct return_type_1<unary_arithmetic_action<Act>, A> {
  typedef
    typename plain_return_type_1<
      unary_arithmetic_action<Act>,
      typename detail::remove_reference_and_cv::type
    >::type type;
};

template<class A>
struct plain_return_type_1<bitwise_action<not_action>, A> {
  typedef A type;
};

// bitwise not, operator~()
template<class A> struct return_type_1<bitwise_action<not_action>, A> {
  typedef
    typename plain_return_type_1<
      bitwise_action<not_action>,
      typename detail::remove_reference_and_cv::type
    >::type type;
};

// prefix increment and decrement operators return
// their argument by default as a non-const reference
template<class Act, class A>
struct plain_return_type_1<pre_increment_decrement_action<Act>, A> {
  typedef A& type;
};

template<class Act, class A>
struct return_type_1<pre_increment_decrement_action<Act>, A> {
  typedef
    typename plain_return_type_1<
      pre_increment_decrement_action<Act>,
      typename detail::remove_reference_and_cv::type
    >::type type;
};

// post decrement just returns the same plain type.
template<class Act, class A>
struct plain_return_type_1<post_increment_decrement_action<Act>, A> {
  typedef A type;
};

template<class Act, class A>
struct return_type_1<post_increment_decrement_action<Act>, A>
{
  typedef
    typename plain_return_type_1<
      post_increment_decrement_action<Act>,
      typename detail::remove_reference_and_cv::type
    >::type type;
};

// logical not, operator!()
template<class A>
struct plain_return_type_1<logical_action<not_action>, A> {
  typedef bool type;
};

template<class A>
struct return_type_1<logical_action<not_action>, A> {
  typedef
    typename plain_return_type_1<
      logical_action<not_action>,
      typename detail::remove_reference_and_cv::type
    >::type type;
};

// address of action ---------------------------------------

template<class A>
struct return_type_1<other_action<addressof_action>, A> {
  typedef
    typename plain_return_type_1<
      other_action<addressof_action>,
      typename detail::remove_reference_and_cv::type
    >::type type1;

  // If no user defined specialization for A, then return the
  // cv qualified pointer to A
  typedef typename detail::IF<
    boost::is_same<type1, detail::unspecified>::value,
    typename boost::remove_reference::type*,
    type1
  >::RET type;
};

// contentsof action ------------------------------------

// TODO: this deduction may lead to fail directly,
// (if A has no specialization for iterator_traits and has no
// typedef A::reference.
// There is no easy way around this, cause there doesn't seem to be a way
// to test whether a class is an iterator or not.

// The default works with std::iterators.

namespace detail {

  // A is a nonreference type
template <class A> struct contentsof_type {
  typedef typename boost::indirect_reference::type type;
};

  // this is since the nullary () in lambda_functor is always instantiated
template <> struct contentsof_type<null_type> {
  typedef detail::unspecified type;
};

template <class A> struct contentsof_type<const A> {
  typedef typename contentsof_type::type type;
};

template <class A> struct contentsof_type<volatile A> {
  typedef typename contentsof_type::type type;
};

template <class A> struct contentsof_type<const volatile A> {
  typedef typename contentsof_type::type type;
};

  // standard iterator traits should take care of the pointer types
  // but just to be on the safe side, we have the specializations here:
  // these work even if A is cv-qualified.
template <class A> struct contentsof_type {
  typedef A& type;
};
template <class A> struct contentsof_type {
  typedef A& type;
};
template <class A> struct contentsof_type {
  typedef A& type;
};
template <class A> struct contentsof_type {
  typedef A& type;
};

template<class A, int N> struct contentsof_type {
  typedef A& type;
};
template<class A, int N> struct contentsof_type<const A[N]> {
  typedef const A& type;
};
template<class A, int N> struct contentsof_type<volatile A[N]> {
  typedef volatile A& type;
};
template<class A, int N> struct contentsof_type<const volatile A[N]> {
  typedef const volatile A& type;
};

} // end detail

template<class A>
struct return_type_1<other_action<contentsof_action>, A> {

  typedef
    typename plain_return_type_1<
      other_action<contentsof_action>,
      typename detail::remove_reference_and_cv::type
    >::type type1;

  // If no user defined specialization for A, then return the
  // cv qualified pointer to A
  typedef typename
  detail::IF_type<
    boost::is_same<type1, detail::unspecified>::value,
    detail::contentsof_type<
      typename boost::remove_reference::type
    >,
    detail::identity_mapping<type1>
  >::type type;
};

// ------------------------------------------------------------------
// binary actions ---------------------------------------------------
// ------------------------------------------------------------------

// here the default case is: no user defined versions:
template <class Act, class A, class B>
struct plain_return_type_2 {
  typedef detail::unspecified type;
};

namespace detail {

// error classes
class illegal_pointer_arithmetic{};

// pointer arithmetic type deductions ----------------------
// value = false means that this is not a pointer arithmetic case
// value = true means, that this can be a pointer arithmetic case, but not necessarily is
// This means, that for user defined operators for pointer types, say for some operator+(X, *Y),
// the deductions must be coded at an earliel level (return_type_2).

template<class Act, class A, class B>
struct pointer_arithmetic_traits { static const bool value = false; };

template<class A, class B>
struct pointer_arithmetic_traits<plus_action, A, B> {

  typedef typename
    array_to_pointer<typename boost::remove_reference::type>::type AP;
  typedef typename
    array_to_pointer<typename boost::remove_reference::type>::type BP;

  static const bool is_pointer_A = boost::is_pointer<AP>::value;
  static const bool is_pointer_B = boost::is_pointer<BP>::value;

  static const bool value = is_pointer_A || is_pointer_B;

  // can't add two pointers.
  // note, that we do not check wether the other type is valid for
  // addition with a pointer.
  // the compiler will catch it in the apply function

  typedef typename
  detail::IF<
    is_pointer_A && is_pointer_B,
      detail::return_type_deduction_failure<
        detail::illegal_pointer_arithmetic
      >,
      typename detail::IF<is_pointer_A, AP, BP>::RET
  >::RET type;

};

template<class A, class B>
struct pointer_arithmetic_traits<minus_action, A, B> {
  typedef typename
    array_to_pointer<typename boost::remove_reference::type>::type AP;
  typedef typename
    array_to_pointer<typename boost::remove_reference::type>::type BP;

  static const bool is_pointer_A = boost::is_pointer<AP>::value;
  static const bool is_pointer_B = boost::is_pointer<BP>::value;

  static const bool value = is_pointer_A || is_pointer_B;

  static const bool same_pointer_type =
    is_pointer_A && is_pointer_B &&
    boost::is_same<
      typename boost::remove_const<
        typename boost::remove_pointer<
          typename boost::remove_const<AP>::type
        >::type
      >::type,
      typename boost::remove_const<
        typename boost::remove_pointer<
          typename boost::remove_const<BP>::type
        >::type
      >::type
    >::value;

  // ptr - ptr has type ptrdiff_t
  // note, that we do not check if, in ptr - B, B is
  // valid for subtraction with a pointer.
  // the compiler will catch it in the apply function

  typedef typename
  detail::IF<
    same_pointer_type, const std::ptrdiff_t,
    typename detail::IF<
      is_pointer_A,
      AP,
      detail::return_type_deduction_failure<detail::illegal_pointer_arithmetic>
    >::RET
  >::RET type;
};

} // namespace detail

// -- arithmetic actions ---------------------------------------------

namespace detail {

template<bool is_pointer_arithmetic, class Act, class A, class B>
struct return_type_2_arithmetic_phase_1;

template<class A, class B> struct return_type_2_arithmetic_phase_2;
template<class A, class B> struct return_type_2_arithmetic_phase_3;

} // namespace detail

// drop any qualifiers from the argument types within arithmetic_action
template<class A, class B, class Act>
struct return_type_2<arithmetic_action<Act>, A, B>
{
  typedef typename detail::remove_reference_and_cv::type plain_A;
  typedef typename detail::remove_reference_and_cv::type plain_B;

  typedef typename
    plain_return_type_2<arithmetic_action<Act>, plain_A, plain_B>::type type1;

  // if user defined return type, do not enter the whole arithmetic deductions
  typedef typename
    detail::IF_type<
      boost::is_same<type1, detail::unspecified>::value,
      detail::return_type_2_arithmetic_phase_1<
         detail::pointer_arithmetic_traits<Act, A, B>::value, Act, A, B
      >,
      plain_return_type_2<arithmetic_action<Act>, plain_A, plain_B>
    >::type type;
};

namespace detail {

// perform integral promotion, no pointer arithmetic
template<bool is_pointer_arithmetic, class Act, class A, class B>
struct return_type_2_arithmetic_phase_1
{
  typedef typename
    return_type_2_arithmetic_phase_2<
      typename remove_reference_and_cv::type,
      typename remove_reference_and_cv::type
    >::type type;
};

// pointer_arithmetic
template<class Act, class A, class B>
struct return_type_2_arithmetic_phase_1<true, Act, A, B>
{
  typedef typename
    pointer_arithmetic_traits<Act, A, B>::type type;
};

template<class A, class B>
struct return_type_2_arithmetic_phase_2 {
  typedef typename
    return_type_2_arithmetic_phase_3<
      typename promote_to_int::type,
      typename promote_to_int::type
    >::type type;
};

// specialization for unsigned int.
// We only have to do these two specialization because the value promotion will
// take care of the other cases.
// The unsigned int promotion rule is this:
// unsigned int to long if a long can hold all values of unsigned int,
// otherwise go to unsigned long.

// struct so I don't have to type this twice.
struct promotion_of_unsigned_int
{
        typedef
        detail::IF<sizeof(long) <= sizeof(unsigned int),
                unsigned long,
                long>::RET type;
};

template<>
struct return_type_2_arithmetic_phase_2<unsigned int, long>
{
        typedef promotion_of_unsigned_int::type type;
};
template<>
struct return_type_2_arithmetic_phase_2<long, unsigned int>
{
        typedef promotion_of_unsigned_int::type type;
};

template<class A, class B> struct return_type_2_arithmetic_phase_3 {
   enum { promote_code_A_value = promote_code::value,
         promote_code_B_value = promote_code::value }; // enums for KCC
  typedef typename
    detail::IF<
      promote_code_A_value == -1 || promote_code_B_value == -1,
      detail::return_type_deduction_failure<return_type_2_arithmetic_phase_3>,
      typename detail::IF<
        ((int)promote_code_A_value > (int)promote_code_B_value),
        A,
        B
      >::RET
    >::RET type;
};

} // namespace detail

// --  bitwise actions -------------------------------------------
// note: for integral types deuduction is similar to arithmetic actions.

// drop any qualifiers from the argument types within arithmetic action
template<class A, class B, class Act>
struct return_type_2<bitwise_action<Act>, A, B>
{

  typedef typename detail::remove_reference_and_cv::type plain_A;
  typedef typename detail::remove_reference_and_cv::type plain_B;

  typedef typename
    plain_return_type_2<bitwise_action<Act>, plain_A, plain_B>::type type1;

  // if user defined return type, do not enter type deductions
  typedef typename
    detail::IF_type<
      boost::is_same<type1, detail::unspecified>::value,
      return_type_2<arithmetic_action<plus_action>, A, B>,
      plain_return_type_2<bitwise_action<Act>, plain_A, plain_B>
    >::type type;

  // plus_action is just a random pick, has to be a concrete instance

  // TODO: This check is only valid for built-in types, overloaded types might
  // accept floating point operators

  // bitwise operators not defined for floating point types
  // these test are not strictly needed here, since the error will be caught in
  // the apply function
  BOOST_STATIC_ASSERT(!(boost::is_float<plain_A>::value && boost::is_float<plain_B>::value));

};

namespace detail {

template <class T> struct get_ostream_type {
  typedef std::basic_ostream<typename T::char_type,
                             typename T::traits_type>& type;
};

template <class T> struct get_istream_type {
  typedef std::basic_istream<typename T::char_type,
                             typename T::traits_type>& type;
};

template<class A, class B>
struct leftshift_type {
private:
  typedef typename boost::remove_reference::type plainA;
public:
  typedef typename detail::IF_type<
    is_instance_of_2<plainA, std::basic_ostream>::value,
    get_ostream_type<plainA>, //reference to the stream
    detail::remove_reference_and_cv
  >::type type;
};

template<class A, class B>
struct rightshift_type {
private:
  typedef typename boost::remove_reference::type plainA;
public:
  typedef typename detail::IF_type<
    is_instance_of_2<plainA, std::basic_istream>::value,
    get_istream_type<plainA>, //reference to the stream
    detail::remove_reference_and_cv
  >::type type;
};

} // end detail

// ostream
template<class A, class B>
struct return_type_2<bitwise_action<leftshift_action>, A, B>
{
  typedef typename detail::remove_reference_and_cv::type plain_A;
  typedef typename detail::remove_reference_and_cv::type plain_B;

  typedef typename
    plain_return_type_2<bitwise_action<leftshift_action>, plain_A, plain_B>::type type1;

  // if user defined return type, do not enter type deductions
  typedef typename
    detail::IF_type<
      boost::is_same<type1, detail::unspecified>::value,
      detail::leftshift_type,
      plain_return_type_2<bitwise_action<leftshift_action>, plain_A, plain_B>
    >::type type;
};

// istream
template<class A, class B>
struct return_type_2<bitwise_action<rightshift_action>, A, B>
{
  typedef typename detail::remove_reference_and_cv::type plain_A;
  typedef typename detail::remove_reference_and_cv::type plain_B;

  typedef typename
    plain_return_type_2<bitwise_action<rightshift_action>, plain_A, plain_B>::type type1;

  // if user defined return type, do not enter type deductions
  typedef typename
    detail::IF_type<
      boost::is_same<type1, detail::unspecified>::value,
      detail::rightshift_type,
      plain_return_type_2<bitwise_action<rightshift_action>, plain_A, plain_B>
    >::type type;
};

// -- logical actions ----------------------------------------
// always bool
// NOTE: this may not be true for some weird user-defined types,
template<class A, class B, class Act>
struct plain_return_type_2<logical_action<Act>, A, B> {
  typedef bool type;
};

template<class A, class B, class Act>
struct return_type_2<logical_action<Act>, A, B> {

  typedef typename detail::remove_reference_and_cv::type plain_A;
  typedef typename detail::remove_reference_and_cv::type plain_B;

  typedef typename
    plain_return_type_2<logical_action<Act>, plain_A, plain_B>::type type;

};

// -- relational actions ----------------------------------------
// always bool
// NOTE: this may not be true for some weird user-defined types,
template<class A, class B, class Act>
struct plain_return_type_2<relational_action<Act>, A, B> {
  typedef bool type;
};

template<class A, class B, class Act>
struct return_type_2<relational_action<Act>, A, B> {

  typedef typename detail::remove_reference_and_cv::type plain_A;
  typedef typename detail::remove_reference_and_cv::type plain_B;

  typedef typename
    plain_return_type_2<relational_action<Act>, plain_A, plain_B>::type type;
};

// Assingment actions -----------------------------------------------
// return type is the type of the first argument as reference

// note that cv-qualifiers are preserved.
// Yes, assignment operator can be const!

// NOTE: this may not be true for some weird user-defined types,

template<class A, class B, class Act>
struct return_type_2<arithmetic_assignment_action<Act>, A, B> {

  typedef typename detail::remove_reference_and_cv::type plain_A;
  typedef typename detail::remove_reference_and_cv::type plain_B;

  typedef typename
    plain_return_type_2<
      arithmetic_assignment_action<Act>, plain_A, plain_B
    >::type type1;

  typedef typename
    detail::IF<
      boost::is_same<type1, detail::unspecified>::value,
      typename boost::add_reference::type,
      type1
    >::RET type;
};

template<class A, class B, class Act>
struct return_type_2<bitwise_assignment_action<Act>, A, B> {

  typedef typename detail::remove_reference_and_cv::type plain_A;
  typedef typename detail::remove_reference_and_cv::type plain_B;

  typedef typename
    plain_return_type_2<
      bitwise_assignment_action<Act>, plain_A, plain_B
    >::type type1;

  typedef typename
    detail::IF<
      boost::is_same<type1, detail::unspecified>::value,
      typename boost::add_reference::type,
      type1
    >::RET type;
};

template<class A, class B>
struct return_type_2<other_action<assignment_action>, A, B> {
  typedef typename detail::remove_reference_and_cv::type plain_A;
  typedef typename detail::remove_reference_and_cv::type plain_B;

  typedef typename
    plain_return_type_2<
      other_action<assignment_action>, plain_A, plain_B
    >::type type1;

  typedef typename
    detail::IF<
      boost::is_same<type1, detail::unspecified>::value,
      typename boost::add_reference::type,
      type1
    >::RET type;
};

// -- other actions ----------------------------------------

// comma action ----------------------------------
// Note: this may not be true for some weird user-defined types,

// NOTE! This only tries the plain_return_type_2 layer and gives
// detail::unspecified as default. If no such specialization is found, the
// type rule in the spcecialization of the return_type_2_prot is used
// to give the type of the right argument (which can be a reference too)
// (The built in operator, can return a l- or rvalue).
template<class A, class B>
struct return_type_2<other_action<comma_action>, A, B> {

  typedef typename detail::remove_reference_and_cv::type plain_A;
  typedef typename detail::remove_reference_and_cv::type plain_B;

  typedef typename
    plain_return_type_2<
      other_action<comma_action>, plain_A, plain_B
    >::type type;
  };

// subscript action -----------------------------------------------

namespace detail {
  // A and B are nonreference types
template <class A, class B> struct subscript_type {
  typedef detail::unspecified type;
};

template <class A, class B> struct subscript_type {
  typedef A& type;
};
template <class A, class B> struct subscript_type {
  typedef A& type;
};
template <class A, class B> struct subscript_type {
  typedef A& type;
};
template <class A, class B> struct subscript_type {
  typedef A& type;
};

template<class A, class B, int N> struct subscript_type {
  typedef A& type;
};

  // these 3 specializations are needed to make gcc <3 happy
template<class A, class B, int N> struct subscript_type<const A[N], B> {
  typedef const A& type;
};
template<class A, class B, int N> struct subscript_type<volatile A[N], B> {
  typedef volatile A& type;
};
template<class A, class B, int N> struct subscript_type<const volatile A[N], B> {
  typedef const volatile A& type;
};

} // end detail

template<class A, class B>
struct return_type_2<other_action<subscript_action>, A, B> {

  typedef typename detail::remove_reference_and_cv::type plain_A;
  typedef typename detail::remove_reference_and_cv::type plain_B;

  typedef typename boost::remove_reference::type nonref_A;
  typedef typename boost::remove_reference::type nonref_B;

  typedef typename
    plain_return_type_2<
      other_action<subscript_action>, plain_A, plain_B
    >::type type1;

  typedef typename
    detail::IF_type<
      boost::is_same<type1, detail::unspecified>::value,
      detail::subscript_type<nonref_A, nonref_B>,
      plain_return_type_2<other_action<subscript_action>, plain_A, plain_B>
    >::type type;

};

template<class Key, class T, class Cmp, class Allocator, class B>
struct plain_return_type_2<other_action<subscript_action>, std::map<Key, T, Cmp, Allocator>, B> {
  typedef T& type;
  // T == std::map<Key, T, Cmp, Allocator>::mapped_type;
};

template<class Key, class T, class Cmp, class Allocator, class B>
struct plain_return_type_2<other_action<subscript_action>, std::multimap<Key, T, Cmp, Allocator>, B> {
  typedef T& type;
  // T == std::map<Key, T, Cmp, Allocator>::mapped_type;
};

  // deque
template<class T, class Allocator, class B>
struct plain_return_type_2<other_action<subscript_action>, std::deque<T, Allocator>, B> {
  typedef typename std::deque<T, Allocator>::reference type;
};
template<class T, class Allocator, class B>
struct plain_return_type_2<other_action<subscript_action>, const std::deque<T, Allocator>, B> {
  typedef typename std::deque<T, Allocator>::const_reference type;
};

  // vector
template<class T, class Allocator, class B>
struct plain_return_type_2<other_action<subscript_action>, std::vector<T, Allocator>, B> {
  typedef typename std::vector<T, Allocator>::reference type;
};
template<class T, class Allocator, class B>
struct plain_return_type_2<other_action<subscript_action>, const std::vector<T, Allocator>, B> {
  typedef typename std::vector<T, Allocator>::const_reference type;
};

  // basic_string
template<class Char, class Traits, class Allocator, class B>
struct plain_return_type_2<other_action<subscript_action>, std::basic_string<Char, Traits, Allocator>, B> {
  typedef typename std::basic_string<Char, Traits, Allocator>::reference type;
};
template<class Char, class Traits, class Allocator, class B>
struct plain_return_type_2<other_action<subscript_action>, const std::basic_string<Char, Traits, Allocator>, B> {
  typedef typename std::basic_string<Char, Traits, Allocator>::const_reference type;
};

template<class Char, class Traits, class Allocator>
struct plain_return_type_2<arithmetic_action<plus_action>,
                           std::basic_string<Char, Traits, Allocator>,
                           std::basic_string<Char, Traits, Allocator> > {
  typedef std::basic_string<Char, Traits, Allocator> type;
};

template<class Char, class Traits, class Allocator>
struct plain_return_type_2<arithmetic_action<plus_action>,
                           const Char*,
                           std::basic_string<Char, Traits, Allocator> > {
  typedef std::basic_string<Char, Traits, Allocator> type;
};

template<class Char, class Traits, class Allocator>
struct plain_return_type_2<arithmetic_action<plus_action>,
                           std::basic_string<Char, Traits, Allocator>,
                           const Char*> {
  typedef std::basic_string<Char, Traits, Allocator> type;
};

template<class Char, class Traits, class Allocator, std::size_t N>
struct plain_return_type_2<arithmetic_action<plus_action>,
                           Char[N],
                           std::basic_string<Char, Traits, Allocator> > {
  typedef std::basic_string<Char, Traits, Allocator> type;
};

template<class Char, class Traits, class Allocator, std::size_t N>
struct plain_return_type_2<arithmetic_action<plus_action>,
                           std::basic_string<Char, Traits, Allocator>,
                           Char[N]> {
  typedef std::basic_string<Char, Traits, Allocator> type;
};

} // namespace lambda
} // namespace boost

#endif


code:
// Boost Lambda Library - operators.hpp --------------------------------------

// Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see www.boost.org

// ---------------------------------------------------------------

#ifndef BOOST_LAMBDA_OPERATORS_HPP
#define BOOST_LAMBDA_OPERATORS_HPP

#include "boost/lambda/detail/is_instance_of.hpp"

namespace boost {
namespace lambda {

#if defined BOOST_LAMBDA_BE1
#error "Multiple defines of BOOST_LAMBDA_BE1"
#endif

  // For all BOOSTA_LAMBDA_BE* macros:

  // CONSTA must be either 'A' or 'const A'
  // CONSTB must be either 'B' or 'const B'

  // It is stupid to have the names A and B as macro arguments, but it avoids
  // the need to pass in emtpy macro arguments, which gives warnings on some
  // compilers

#define BOOST_LAMBDA_BE1(OPER_NAME, ACTION, CONSTA, CONSTB, CONVERSION)      \
template<class Arg, class B>                                                 \
inline const                                                                 \
lambda_functor<                                                              \
  lambda_functor_base<                                                       \
    ACTION,                                                                  \
    tuple<lambda_functor<Arg>, typename const_copy_argument <CONSTB>::type>  \
  >                                                                          \
>                                                                            \
OPER_NAME (const lambda_functor<Arg>& a, CONSTB& b) {                      \
  return                                                                     \
    lambda_functor_base<                                                     \
      ACTION,                                                                \
      tuple<lambda_functor<Arg>, typename const_copy_argument <CONSTB>::type>\
    >                                                                        \
   (tuple<lambda_functor<Arg>, typename const_copy_argument <CONSTB>::type>(a, b)); \
}

#if defined BOOST_LAMBDA_BE2
#error "Multiple defines of BOOST_LAMBDA_BE2"
#endif

#define BOOST_LAMBDA_BE2(OPER_NAME, ACTION, CONSTA, CONSTB, CONVERSION)      \
template<class A, class Arg>                                                 \
inline const                                                                 \
lambda_functor<                                                              \
  lambda_functor_base<                                                       \
    ACTION,                                                                  \
    tuple<typename CONVERSION <CONSTA>::type, lambda_functor<Arg> >        \
  >                                                                          \
>                                                                            \
OPER_NAME (CONSTA& a, const lambda_functor<Arg>& b) {                      \
  return                                                                     \
    lambda_functor_base<                                                     \
      ACTION,                                                                \
      tuple<typename CONVERSION <CONSTA>::type, lambda_functor<Arg> >      \
    >                                                                        \
  (tuple<typename CONVERSION <CONSTA>::type, lambda_functor<Arg> >(a, b)); \
}

#if defined BOOST_LAMBDA_BE3
#error "Multiple defines of BOOST_LAMBDA_BE3"
#endif

#define BOOST_LAMBDA_BE3(OPER_NAME, ACTION, CONSTA, CONSTB, CONVERSION)    \
template<class ArgA, class ArgB>                                           \
inline const                                                               \
lambda_functor<                                                            \
  lambda_functor_base<                                                     \
    ACTION,                                                                \
    tuple<lambda_functor<ArgA>, lambda_functor<ArgB> >                     \
  >                                                                        \
>                                                                          \
OPER_NAME (const lambda_functor<ArgA>& a, const lambda_functor<ArgB>& b) { \
  return                                                                   \
    lambda_functor_base<                                                   \
      ACTION,                                                              \
      tuple<lambda_functor<ArgA>, lambda_functor<ArgB> >                   \
    >                                                                      \
  (tuple<lambda_functor<ArgA>, lambda_functor<ArgB> >(a, b));              \
}

#if defined BOOST_LAMBDA_BE
#error "Multiple defines of BOOST_LAMBDA_BE"
#endif

#define BOOST_LAMBDA_BE(OPER_NAME, ACTION, CONSTA, CONSTB, CONST_CONVERSION) \
BOOST_LAMBDA_BE1(OPER_NAME, ACTION, CONSTA, CONSTB, CONST_CONVERSION)        \
BOOST_LAMBDA_BE2(OPER_NAME, ACTION, CONSTA, CONSTB, CONST_CONVERSION)        \
BOOST_LAMBDA_BE3(OPER_NAME, ACTION, CONSTA, CONSTB, CONST_CONVERSION)

#define BOOST_LAMBDA_EMPTY()

BOOST_LAMBDA_BE(operator+, arithmetic_action<plus_action>, const A, const B, const_copy_argument)
BOOST_LAMBDA_BE(operator-, arithmetic_action<minus_action>, const A, const B, const_copy_argument)
BOOST_LAMBDA_BE(operator*, arithmetic_action<multiply_action>, const A, const B, const_copy_argument)
BOOST_LAMBDA_BE(operator/, arithmetic_action<divide_action>, const A, const B, const_copy_argument)
BOOST_LAMBDA_BE(operator%, arithmetic_action<remainder_action>, const A, const B, const_copy_argument)
BOOST_LAMBDA_BE(operator<<, bitwise_action<leftshift_action>, const A, const B, const_copy_argument)
BOOST_LAMBDA_BE(operator>>, bitwise_action<rightshift_action>, const A, const B, const_copy_argument)
BOOST_LAMBDA_BE(operator&, bitwise_action<and_action>, const A, const B, const_copy_argument)
BOOST_LAMBDA_BE(operator|, bitwise_action<or_action>, const A, const B, const_copy_argument)
BOOST_LAMBDA_BE(operator^, bitwise_action<xor_action>, const A, const B, const_copy_argument)
BOOST_LAMBDA_BE(operator&&, logical_action<and_action>, const A, const B, const_copy_argument)
BOOST_LAMBDA_BE(operator||, logical_action<or_action>, const A, const B, const_copy_argument)
BOOST_LAMBDA_BE(operator<, relational_action<less_action>, const A, const B, const_copy_argument)
BOOST_LAMBDA_BE(operator>, relational_action<greater_action>, const A, const B, const_copy_argument)
BOOST_LAMBDA_BE(operator<=, relational_action<lessorequal_action>, const A, const B, const_copy_argument)
BOOST_LAMBDA_BE(operator>=, relational_action<greaterorequal_action>, const A, const B, const_copy_argument)
BOOST_LAMBDA_BE(operator==, relational_action<equal_action>, const A, const B, const_copy_argument)
BOOST_LAMBDA_BE(operator!=, relational_action<notequal_action>, const A, const B, const_copy_argument)

BOOST_LAMBDA_BE(operator+=, arithmetic_assignment_action<plus_action>, A, const B, reference_argument)
BOOST_LAMBDA_BE(operator-=, arithmetic_assignment_action<minus_action>, A, const B, reference_argument)
BOOST_LAMBDA_BE(operator*=, arithmetic_assignment_action<multiply_action>, A, const B, reference_argument)
BOOST_LAMBDA_BE(operator/=, arithmetic_assignment_action<divide_action>, A, const B, reference_argument)
BOOST_LAMBDA_BE(operator%=, arithmetic_assignment_action<remainder_action>, A, const B, reference_argument)
BOOST_LAMBDA_BE(operator<<=, bitwise_assignment_action<leftshift_action>, A, const B, reference_argument)
BOOST_LAMBDA_BE(operator>>=, bitwise_assignment_action<rightshift_action>, A, const B, reference_argument)
BOOST_LAMBDA_BE(operator&=, bitwise_assignment_action<and_action>, A, const B, reference_argument)
BOOST_LAMBDA_BE(operator|=, bitwise_assignment_action<or_action>, A, const B, reference_argument)
BOOST_LAMBDA_BE(operator^=, bitwise_assignment_action<xor_action>, A, const B, reference_argument)

// A special trick for comma operator for correct preprocessing
#if defined BOOST_LAMBDA_COMMA_OPERATOR_NAME
#error "Multiple defines of BOOST_LAMBDA_COMMA_OPERATOR_NAME"
#endif

#define BOOST_LAMBDA_COMMA_OPERATOR_NAME operator,

BOOST_LAMBDA_BE1(BOOST_LAMBDA_COMMA_OPERATOR_NAME, other_action<comma_action>, const A, const B, const_copy_argument)
BOOST_LAMBDA_BE2(BOOST_LAMBDA_COMMA_OPERATOR_NAME, other_action<comma_action>, const A, const B, const_copy_argument)
BOOST_LAMBDA_BE3(BOOST_LAMBDA_COMMA_OPERATOR_NAME, other_action<comma_action>, const A, const B, const_copy_argument)

namespace detail {

// special cases for ostream& << Any and istream& >> Any ---------------
// the actual stream classes may vary and thus a specialisation for,
// say ostream& does not match (the general case above is chosen).
// Therefore we specialise for non-const reference:
// if the left argument is a stream, we store the stream as reference
// if it is something else, we store a const plain by default

// Note that the overloading is const vs. non-const first argument

template<class T> struct convert_ostream_to_ref_others_to_c_plain_by_default {
  typedef typename detail::IF<
                       is_instance_of_2<
                         T, std::basic_ostream
                       >::value,
                       T&,
                       typename const_copy_argument <T>::type
                     >::RET type;
};

template<class T> struct convert_istream_to_ref_others_to_c_plain_by_default {
  typedef typename detail::IF<
                       is_instance_of_2<
                         T, std::basic_istream
                       >::value,
                       T&,
                       typename const_copy_argument <T>::type
                     >::RET type;
};

} // detail

BOOST_LAMBDA_BE2(operator<<, bitwise_action< leftshift_action>, A, const B, detail::convert_ostream_to_ref_others_to_c_plain_by_default)
BOOST_LAMBDA_BE2(operator>>, bitwise_action< rightshift_action>, A, const B, detail::convert_istream_to_ref_others_to_c_plain_by_default)

// special case for io_manipulators.
// function references cannot be given as arguments to lambda operator
// expressions in general. With << and >> the use of manipulators is
// so common, that specializations are provided to make them work.

template<class Arg, class Ret, class ManipArg>
inline const
lambda_functor<
  lambda_functor_base<
    bitwise_action<leftshift_action>,
    tuple<lambda_functor<Arg>, Ret(&)(ManipArg)>
  >
>
operator<<(const lambda_functor<Arg>& a, Ret(&b)(ManipArg))
{
  return
      lambda_functor_base<
        bitwise_action<leftshift_action>,
        tuple<lambda_functor<Arg>, Ret(&)(ManipArg)>
      >
    ( tuple<lambda_functor<Arg>, Ret(&)(ManipArg)>(a, b) );
}

template<class Arg, class Ret, class ManipArg>
inline const
lambda_functor<
  lambda_functor_base<
    bitwise_action<rightshift_action>,
    tuple<lambda_functor<Arg>, Ret(&)(ManipArg)>
  >
>
operator>>(const lambda_functor<Arg>& a, Ret(&b)(ManipArg))
{
  return
      lambda_functor_base<
        bitwise_action<rightshift_action>,
        tuple<lambda_functor<Arg>, Ret(&)(ManipArg)>
      >
    ( tuple<lambda_functor<Arg>, Ret(&)(ManipArg)>(a, b) );
}

// (+ and -) take their arguments as const references.
// This has consquences with pointer artihmetic
// E.g int a[]; ... *a = 1 works but not *(a+1) = 1.
// the result of a+1 would be const
// To make the latter work too,
// non-const arrays are taken as non-const and stored as non-const as well.
#if defined  BOOST_LAMBDA_PTR_ARITHMETIC_E1
#error "Multiple defines of  BOOST_LAMBDA_PTR_ARITHMETIC_E1"
#endif

#define BOOST_LAMBDA_PTR_ARITHMETIC_E1(OPER_NAME, ACTION, CONSTB)           \
template<class Arg, int N, class B>                                         \
inline const                                                                \
lambda_functor<                                                             \
  lambda_functor_base<ACTION, tuple<lambda_functor<Arg>, CONSTB(&)[N]> >    \
>                                                                           \
OPER_NAME (const lambda_functor<Arg>& a, CONSTB(&b)[N])                     \
{                                                                           \
  return                                                                    \
    lambda_functor_base<ACTION, tuple<lambda_functor<Arg>, CONSTB(&)[N]> >  \
  (tuple<lambda_functor<Arg>, CONSTB(&)[N]>(a, b));                         \
}

#if defined  BOOST_LAMBDA_PTR_ARITHMETIC_E2
#error "Multiple defines of  BOOST_LAMBDA_PTR_ARITHMETIC_E2"
#endif

#define BOOST_LAMBDA_PTR_ARITHMETIC_E2(OPER_NAME, ACTION, CONSTA)           \
template<int N, class A, class Arg>                                         \
inline const                                                                \
lambda_functor<                                                             \
  lambda_functor_base<ACTION, tuple<CONSTA(&)[N], lambda_functor<Arg> > >   \
>                                                                           \
OPER_NAME (CONSTA(&a)[N], const lambda_functor<Arg>& b)                     \
{                                                                           \
  return                                                                    \
    lambda_functor_base<ACTION, tuple<CONSTA(&)[N], lambda_functor<Arg> > > \
    (tuple<CONSTA(&)[N], lambda_functor<Arg> >(a, b));                      \
}

BOOST_LAMBDA_PTR_ARITHMETIC_E1(operator+, arithmetic_action<plus_action>, B)
BOOST_LAMBDA_PTR_ARITHMETIC_E2(operator+, arithmetic_action<plus_action>, A)
BOOST_LAMBDA_PTR_ARITHMETIC_E1(operator+, arithmetic_action<plus_action>,const B)
BOOST_LAMBDA_PTR_ARITHMETIC_E2(operator+, arithmetic_action<plus_action>,const A)

//BOOST_LAMBDA_PTR_ARITHMETIC_E1(operator-, arithmetic_action<minus_action>)
// This is not needed, since the result of ptr-ptr is an rvalue anyway

BOOST_LAMBDA_PTR_ARITHMETIC_E2(operator-, arithmetic_action<minus_action>, A)
BOOST_LAMBDA_PTR_ARITHMETIC_E2(operator-, arithmetic_action<minus_action>, const A)

#undef BOOST_LAMBDA_BE1
#undef BOOST_LAMBDA_BE2
#undef BOOST_LAMBDA_BE3
#undef BOOST_LAMBDA_BE
#undef BOOST_LAMBDA_COMMA_OPERATOR_NAME

#undef BOOST_LAMBDA_PTR_ARITHMETIC_E1
#undef BOOST_LAMBDA_PTR_ARITHMETIC_E2

// ---------------------------------------------------------------------
// unary operators -----------------------------------------------------
// ---------------------------------------------------------------------

#if defined BOOST_LAMBDA_UE
#error "Multiple defines of BOOST_LAMBDA_UE"
#endif

#define BOOST_LAMBDA_UE(OPER_NAME, ACTION)                                 \
template<class Arg>                                                        \
inline const                                                               \
lambda_functor<lambda_functor_base<ACTION, tuple<lambda_functor<Arg> > > > \
OPER_NAME (const lambda_functor<Arg>& a)                                   \
{                                                                          \
  return                                                                   \
    lambda_functor_base<ACTION, tuple<lambda_functor<Arg> > >              \
    ( tuple<lambda_functor<Arg> >(a) );                                    \
}

BOOST_LAMBDA_UE(operator+, unary_arithmetic_action<plus_action>)
BOOST_LAMBDA_UE(operator-, unary_arithmetic_action<minus_action>)
BOOST_LAMBDA_UE(operator~, bitwise_action<not_action>)
BOOST_LAMBDA_UE(operator!, logical_action<not_action>)
BOOST_LAMBDA_UE(operator++, pre_increment_decrement_action<increment_action>)
BOOST_LAMBDA_UE(operator--, pre_increment_decrement_action<decrement_action>)
BOOST_LAMBDA_UE(operator*, other_action<contentsof_action>)
BOOST_LAMBDA_UE(operator&, other_action<addressof_action>)

#if defined BOOST_LAMBDA_POSTFIX_UE
#error "Multiple defines of BOOST_LAMBDA_POSTFIX_UE"
#endif

#define BOOST_LAMBDA_POSTFIX_UE(OPER_NAME, ACTION)                         \
template<class Arg>                                                        \
inline const                                                               \
lambda_functor<lambda_functor_base<ACTION, tuple<lambda_functor<Arg> > > > \
OPER_NAME (const lambda_functor<Arg>& a, int)                              \
{                                                                          \
  return                                                                   \
    lambda_functor_base<ACTION, tuple<lambda_functor<Arg> > >              \
    ( tuple<lambda_functor<Arg> >(a) );                                    \
}

BOOST_LAMBDA_POSTFIX_UE(operator++, post_increment_decrement_action<increment_action>)
BOOST_LAMBDA_POSTFIX_UE(operator--, post_increment_decrement_action<decrement_action>)

#undef BOOST_LAMBDA_UE
#undef BOOST_LAMBDA_POSTFIX_UE

} // namespace lambda
} // namespace boost

#endif


code:
// Boost Lambda Library  ret.hpp -----------------------------------------

// Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see www.boost.org

#ifndef BOOST_LAMBDA_RET_HPP
#define BOOST_LAMBDA_RET_HPP

namespace boost {
namespace lambda {

  // TODO:

//  Add specializations for function references for ret, protect and unlambda
//  e.g void foo(); unlambda(foo); fails, as it would add a const qualifier
  // for a function type.
  // on the other hand unlambda(*foo) does work

// -- ret -------------------------
// the explicit return type template

  // TODO: It'd be nice to make ret a nop for other than lambda functors
  // but causes an ambiguiyty with gcc (not with KCC), check what is the
  // right interpretation.

  //  // ret for others than lambda functors has no effect
  // template <class U, class T>
  // inline const T& ret(const T& t) { return t; }

template<class RET, class Arg>
inline const
lambda_functor<
  lambda_functor_base<
    explicit_return_type_action<RET>,
    tuple<lambda_functor<Arg> >
  >
>
ret(const lambda_functor<Arg>& a1)
{
  return
    lambda_functor_base<
      explicit_return_type_action<RET>,
      tuple<lambda_functor<Arg> >
    >
    (tuple<lambda_functor<Arg> >(a1));
}

// protect ------------------

  // protecting others than lambda functors has no effect
template <class T>
inline const T& protect(const T& t) { return t; }

template<class Arg>
inline const
lambda_functor<
  lambda_functor_base<
    protect_action,
    tuple<lambda_functor<Arg> >
  >
>
protect(const lambda_functor<Arg>& a1)
{
  return
      lambda_functor_base<
        protect_action,
        tuple<lambda_functor<Arg> >
      >
    (tuple<lambda_functor<Arg> >(a1));
}

// -------------------------------------------------------------------

// Hides the lambda functorness of a lambda functor.
// After this, the functor is immune to argument substitution, etc.
// This can be used, e.g. to make it safe to pass lambda functors as
// arguments to functions, which might use them as target functions

// note, unlambda and protect are different things. Protect hides the lambda
// functor for one application, unlambda for good.

template <class LambdaFunctor>
class non_lambda_functor
{
  LambdaFunctor lf;
public:

  // This functor defines the result_type typedef.
  // The result type must be deducible without knowing the arguments

  template <class SigArgs> struct sig {
    typedef typename
      LambdaFunctor::inherited::
        template sig<typename SigArgs::tail_type>::type type;
  };

  explicit non_lambda_functor(const LambdaFunctor& a) : lf(a) {}

  typename LambdaFunctor::nullary_return_type
  operator()() const {
    return lf.template
      call<typename LambdaFunctor::nullary_return_type>
        (cnull_type(), cnull_type(), cnull_type(), cnull_type());
  }

  template<class A>
  typename sig<tuple<const non_lambda_functor, A&> >::type
  operator()(A& a) const {
    return lf.template call<typename sig<tuple<const non_lambda_functor, A&> >::type >(a, cnull_type(), cnull_type(), cnull_type());
  }

  template<class A, class B>
  typename sig<tuple<const non_lambda_functor, A&, B&> >::type
  operator()(A& a, B& b) const {
    return lf.template call<typename sig<tuple<const non_lambda_functor, A&, B&> >::type >(a, b, cnull_type(), cnull_type());
  }

  template<class A, class B, class C>
  typename sig<tuple<const non_lambda_functor, A&, B&, C&> >::type
  operator()(A& a, B& b, C& c) const {
    return lf.template call<typename sig<tuple<const non_lambda_functor, A&, B&, C&> >::type>(a, b, c, cnull_type());
  }
};

template <class Arg>
inline const Arg& unlambda(const Arg& a) { return a; }

template <class Arg>
inline const non_lambda_functor<lambda_functor<Arg> >
unlambda(const lambda_functor<Arg>& a)
{
  return non_lambda_functor<lambda_functor<Arg> >(a);
}

  // Due to a language restriction, lambda functors cannot be made to
  // accept non-const rvalue arguments. Usually iterators do not return
  // temporaries, but sometimes they do. That's why a workaround is provided.
  // Note, that this potentially breaks const correctness, so be careful!

// any lambda functor can be turned into a const_incorrect_lambda_functor
// The operator() takes arguments as consts and then casts constness
// away. So this breaks const correctness!!! but is a necessary workaround
// in some cases due to language limitations.
// Note, that this is not a lambda_functor anymore, so it can not be used
// as a sub lambda expression.

template <class LambdaFunctor>
struct const_incorrect_lambda_functor {
  LambdaFunctor lf;
public:

  explicit const_incorrect_lambda_functor(const LambdaFunctor& a) : lf(a) {}

  template <class SigArgs> struct sig {
    typedef typename
      LambdaFunctor::inherited::template
        sig<typename SigArgs::tail_type>::type type;
  };

  // The nullary case is not needed (no arguments, no parameter type problems)

  template<class A>
  typename sig<tuple<const const_incorrect_lambda_functor, A&> >::type
  operator()(const A& a) const {
    return lf.template call<typename sig<tuple<const const_incorrect_lambda_functor, A&> >::type >(const_cast<A&>(a), cnull_type(), cnull_type(), cnull_type());
  }

  template<class A, class B>
  typename sig<tuple<const const_incorrect_lambda_functor, A&, B&> >::type
  operator()(const A& a, const B& b) const {
    return lf.template call<typename sig<tuple<const const_incorrect_lambda_functor, A&, B&> >::type >(const_cast<A&>(a), const_cast<B&>(b), cnull_type(), cnull_type());
  }

  template<class A, class B, class C>
  typename sig<tuple<const const_incorrect_lambda_functor, A&, B&, C&> >::type
  operator()(const A& a, const B& b, const C& c) const {
    return lf.template call<typename sig<tuple<const const_incorrect_lambda_functor, A&, B&, C&> >::type>(const_cast<A&>(a), const_cast<B&>(b), const_cast<C&>(c), cnull_type());
  }
};

// ------------------------------------------------------------------------
// any lambda functor can be turned into a const_parameter_lambda_functor
// The operator() takes arguments as const.
// This is useful if lambda functors are called with non-const rvalues.
// Note, that this is not a lambda_functor anymore, so it can not be used
// as a sub lambda expression.

template <class LambdaFunctor>
struct const_parameter_lambda_functor {
  LambdaFunctor lf;
public:

  explicit const_parameter_lambda_functor(const LambdaFunctor& a) : lf(a) {}

  template <class SigArgs> struct sig {
    typedef typename
      LambdaFunctor::inherited::template
        sig<typename SigArgs::tail_type>::type type;
  };

  // The nullary case is not needed: no arguments, no constness problems.

  template<class A>
  typename sig<tuple<const const_parameter_lambda_functor, const A&> >::type
  operator()(const A& a) const {
    return lf.template call<typename sig<tuple<const const_parameter_lambda_functor, const A&> >::type >(a, cnull_type(), cnull_type(), cnull_type());
  }

  template<class A, class B>
  typename sig<tuple<const const_parameter_lambda_functor, const A&, const B&> >::type
  operator()(const A& a, const B& b) const {
    return lf.template call<typename sig<tuple<const const_parameter_lambda_functor, const A&, const B&> >::type >(a, b, cnull_type(), cnull_type());
  }

  template<class A, class B, class C>
  typename sig<tuple<const const_parameter_lambda_functor, const A&, const B&, const C&>
>::type
  operator()(const A& a, const B& b, const C& c) const {
    return lf.template call<typename sig<tuple<const const_parameter_lambda_functor, const A&, const B&, const C&> >::type>(a, b, c, cnull_type());
  }
};

template <class Arg>
inline const const_incorrect_lambda_functor<lambda_functor<Arg> >
break_const(const lambda_functor<Arg>& lf)
{
  return const_incorrect_lambda_functor<lambda_functor<Arg> >(lf);
}

template <class Arg>
inline const const_parameter_lambda_functor<lambda_functor<Arg> >
const_parameters(const lambda_functor<Arg>& lf)
{
  return const_parameter_lambda_functor<lambda_functor<Arg> >(lf);
}

// make void ------------------------------------------------
// make_void( x ) turns a lambda functor x with some return type y into
// another lambda functor, which has a void return type
// when called, the original return type is discarded

// we use this action. The action class will be called, which means that
// the wrapped lambda functor is evaluated, but we just don't do anything
// with the result.
struct voidifier_action {
  template<class Ret, class A> static void apply(A&) {}
};

template<class Args> struct return_type_N<voidifier_action, Args> {
  typedef void type;
};

template<class Arg1>
inline const
lambda_functor<
  lambda_functor_base<
    action<1, voidifier_action>,
    tuple<lambda_functor<Arg1> >
  >
>
make_void(const lambda_functor<Arg1>& a1) {
return
    lambda_functor_base<
      action<1, voidifier_action>,
      tuple<lambda_functor<Arg1> >
    >
  (tuple<lambda_functor<Arg1> > (a1));
}

// for non-lambda functors, make_void does nothing
// (the argument gets evaluated immediately)

template<class Arg1>
inline const
lambda_functor<
  lambda_functor_base<do_nothing_action, null_type>
>
make_void(const Arg1&) {
return
    lambda_functor_base<do_nothing_action, null_type>();
}

// std_functor -----------------------------------------------------

//  The STL uses the result_type typedef as the convention to let binders know
//  the return type of a function object.
//  LL uses the sig template.
//  To let LL know that the function object has the result_type typedef
//  defined, it can be wrapped with the std_functor function.

// Just inherit form the template parameter (the standard functor),
// and provide a sig template. So we have a class which is still the
// same functor + the sig template.

template<class T>
struct result_type_to_sig : public T {
  template<class Args> struct sig { typedef typename T::result_type type; };
  result_type_to_sig(const T& t) : T(t) {}
};

template<class F>
inline result_type_to_sig<F> std_functor(const F& f) { return f; }

} // namespace lambda
} // namespace boost

#endif