williamr@2: // Boost Lambda Library -- member_ptr.hpp --------------------- williamr@2: williamr@2: // Copyright (C) 1999, 2000 Jaakko Järvi (jaakko.jarvi@cs.utu.fi) williamr@2: // Copyright (C) 2000 Gary Powell (gary.powell@sierra.com) williamr@2: // williamr@2: // Distributed under the Boost Software License, Version 1.0. (See williamr@2: // accompanying file LICENSE_1_0.txt or copy at williamr@2: // http://www.boost.org/LICENSE_1_0.txt) williamr@2: // williamr@2: // For more information, see www.boost.org williamr@2: williamr@2: // -------------------------------------------------------------------------- williamr@2: williamr@2: #if !defined(BOOST_LAMBDA_MEMBER_PTR_HPP) williamr@2: #define BOOST_LAMBDA_MEMBER_PTR_HPP williamr@2: williamr@2: namespace boost { williamr@2: namespace lambda { williamr@2: williamr@2: williamr@2: class member_pointer_action {}; williamr@2: williamr@2: williamr@2: namespace detail { williamr@2: williamr@2: // the boost type_traits member_pointer traits are not enough, williamr@2: // need to know more details. williamr@2: template<class T> williamr@2: struct member_pointer { williamr@2: typedef typename boost::add_reference<T>::type type; williamr@2: typedef detail::unspecified class_type; williamr@2: typedef detail::unspecified qualified_class_type; williamr@2: BOOST_STATIC_CONSTANT(bool, is_data_member = false); williamr@2: BOOST_STATIC_CONSTANT(bool, is_function_member = false); williamr@2: }; williamr@2: williamr@2: template<class T, class U> williamr@2: struct member_pointer<T U::*> { williamr@2: typedef typename boost::add_reference<T>::type type; williamr@2: typedef U class_type; williamr@2: typedef U qualified_class_type; williamr@2: BOOST_STATIC_CONSTANT(bool, is_data_member = true); williamr@2: BOOST_STATIC_CONSTANT(bool, is_function_member = false); williamr@2: }; williamr@2: williamr@2: template<class T, class U> williamr@2: struct member_pointer<const T U::*> { williamr@2: typedef typename boost::add_reference<const T>::type type; williamr@2: typedef U class_type; williamr@2: typedef const U qualified_class_type; williamr@2: BOOST_STATIC_CONSTANT(bool, is_data_member = true); williamr@2: BOOST_STATIC_CONSTANT(bool, is_function_member = false); williamr@2: }; williamr@2: williamr@2: template<class T, class U> williamr@2: struct member_pointer<volatile T U::*> { williamr@2: typedef typename boost::add_reference<volatile T>::type type; williamr@2: typedef U class_type; williamr@2: typedef volatile U qualified_class_type; williamr@2: BOOST_STATIC_CONSTANT(bool, is_data_member = true); williamr@2: BOOST_STATIC_CONSTANT(bool, is_function_member = false); williamr@2: }; williamr@2: williamr@2: template<class T, class U> williamr@2: struct member_pointer<const volatile T U::*> { williamr@2: typedef typename boost::add_reference<const volatile T>::type type; williamr@2: typedef U class_type; williamr@2: typedef const volatile U qualified_class_type; williamr@2: BOOST_STATIC_CONSTANT(bool, is_data_member = true); williamr@2: BOOST_STATIC_CONSTANT(bool, is_function_member = false); williamr@2: }; williamr@2: williamr@2: // -- nonconst member functions -- williamr@2: template<class T, class U> williamr@2: struct member_pointer<T (U::*)()> { williamr@2: typedef T type; williamr@2: typedef U class_type; williamr@2: typedef U qualified_class_type; williamr@2: BOOST_STATIC_CONSTANT(bool, is_data_member = false); williamr@2: BOOST_STATIC_CONSTANT(bool, is_function_member = true); williamr@2: }; williamr@2: template<class T, class U, class A1> williamr@2: struct member_pointer<T (U::*)(A1)> { williamr@2: typedef T type; williamr@2: typedef U class_type; williamr@2: typedef U qualified_class_type; williamr@2: BOOST_STATIC_CONSTANT(bool, is_data_member = false); williamr@2: BOOST_STATIC_CONSTANT(bool, is_function_member = true); williamr@2: }; williamr@2: template<class T, class U, class A1, class A2> williamr@2: struct member_pointer<T (U::*)(A1, A2)> { williamr@2: typedef T type; williamr@2: typedef U class_type; williamr@2: typedef U qualified_class_type; williamr@2: BOOST_STATIC_CONSTANT(bool, is_data_member = false); williamr@2: BOOST_STATIC_CONSTANT(bool, is_function_member = true); williamr@2: }; williamr@2: template<class T, class U, class A1, class A2, class A3> williamr@2: struct member_pointer<T (U::*)(A1, A2, A3)> { williamr@2: typedef T type; williamr@2: typedef U class_type; williamr@2: typedef U qualified_class_type; williamr@2: BOOST_STATIC_CONSTANT(bool, is_data_member = false); williamr@2: BOOST_STATIC_CONSTANT(bool, is_function_member = true); williamr@2: }; williamr@2: template<class T, class U, class A1, class A2, class A3, class A4> williamr@2: struct member_pointer<T (U::*)(A1, A2, A3, A4)> { williamr@2: typedef T type; williamr@2: typedef U class_type; williamr@2: typedef U qualified_class_type; williamr@2: BOOST_STATIC_CONSTANT(bool, is_data_member = false); williamr@2: BOOST_STATIC_CONSTANT(bool, is_function_member = true); williamr@2: }; williamr@2: template<class T, class U, class A1, class A2, class A3, class A4, class A5> williamr@2: struct member_pointer<T (U::*)(A1, A2, A3, A4, A5)> { williamr@2: typedef T type; williamr@2: typedef U class_type; williamr@2: typedef U qualified_class_type; williamr@2: BOOST_STATIC_CONSTANT(bool, is_data_member = false); williamr@2: BOOST_STATIC_CONSTANT(bool, is_function_member = true); williamr@2: }; williamr@2: template<class T, class U, class A1, class A2, class A3, class A4, class A5, williamr@2: class A6> williamr@2: struct member_pointer<T (U::*)(A1, A2, A3, A4, A5, A6)> { williamr@2: typedef T type; williamr@2: typedef U class_type; williamr@2: typedef U qualified_class_type; williamr@2: BOOST_STATIC_CONSTANT(bool, is_data_member = false); williamr@2: BOOST_STATIC_CONSTANT(bool, is_function_member = true); williamr@2: }; williamr@2: template<class T, class U, class A1, class A2, class A3, class A4, class A5, williamr@2: class A6, class A7> williamr@2: struct member_pointer<T (U::*)(A1, A2, A3, A4, A5, A6, A7)> { williamr@2: typedef T type; williamr@2: typedef U class_type; williamr@2: typedef U qualified_class_type; williamr@2: BOOST_STATIC_CONSTANT(bool, is_data_member = false); williamr@2: BOOST_STATIC_CONSTANT(bool, is_function_member = true); williamr@2: }; williamr@2: template<class T, class U, class A1, class A2, class A3, class A4, class A5, williamr@2: class A6, class A7, class A8> williamr@2: struct member_pointer<T (U::*)(A1, A2, A3, A4, A5, A6, A7, A8)> { williamr@2: typedef T type; williamr@2: typedef U class_type; williamr@2: typedef U qualified_class_type; williamr@2: BOOST_STATIC_CONSTANT(bool, is_data_member = false); williamr@2: BOOST_STATIC_CONSTANT(bool, is_function_member = true); williamr@2: }; williamr@2: template<class T, class U, class A1, class A2, class A3, class A4, class A5, williamr@2: class A6, class A7, class A8, class A9> williamr@2: struct member_pointer<T (U::*)(A1, A2, A3, A4, A5, A6, A7, A8, A9)> { williamr@2: typedef T type; williamr@2: typedef U class_type; williamr@2: typedef U qualified_class_type; williamr@2: BOOST_STATIC_CONSTANT(bool, is_data_member = false); williamr@2: BOOST_STATIC_CONSTANT(bool, is_function_member = true); williamr@2: }; williamr@2: // -- const member functions -- williamr@2: template<class T, class U> williamr@2: struct member_pointer<T (U::*)() const> { williamr@2: typedef T type; williamr@2: typedef U class_type; williamr@2: typedef const U qualified_class_type; williamr@2: BOOST_STATIC_CONSTANT(bool, is_data_member = false); williamr@2: BOOST_STATIC_CONSTANT(bool, is_function_member = true); williamr@2: }; williamr@2: template<class T, class U, class A1> williamr@2: struct member_pointer<T (U::*)(A1) const> { williamr@2: typedef T type; williamr@2: typedef U class_type; williamr@2: typedef const U qualified_class_type; williamr@2: BOOST_STATIC_CONSTANT(bool, is_data_member = false); williamr@2: BOOST_STATIC_CONSTANT(bool, is_function_member = true); williamr@2: }; williamr@2: template<class T, class U, class A1, class A2> williamr@2: struct member_pointer<T (U::*)(A1, A2) const> { williamr@2: typedef T type; williamr@2: typedef U class_type; williamr@2: typedef const U qualified_class_type; williamr@2: BOOST_STATIC_CONSTANT(bool, is_data_member = false); williamr@2: BOOST_STATIC_CONSTANT(bool, is_function_member = true); williamr@2: }; williamr@2: template<class T, class U, class A1, class A2, class A3> williamr@2: struct member_pointer<T (U::*)(A1, A2, A3) const> { williamr@2: typedef T type; williamr@2: typedef U class_type; williamr@2: typedef const U qualified_class_type; williamr@2: BOOST_STATIC_CONSTANT(bool, is_data_member = false); williamr@2: BOOST_STATIC_CONSTANT(bool, is_function_member = true); williamr@2: }; williamr@2: template<class T, class U, class A1, class A2, class A3, class A4> williamr@2: struct member_pointer<T (U::*)(A1, A2, A3, A4) const> { williamr@2: typedef T type; williamr@2: typedef U class_type; williamr@2: typedef const U qualified_class_type; williamr@2: BOOST_STATIC_CONSTANT(bool, is_data_member = false); williamr@2: BOOST_STATIC_CONSTANT(bool, is_function_member = true); williamr@2: }; williamr@2: template<class T, class U, class A1, class A2, class A3, class A4, class A5> williamr@2: struct member_pointer<T (U::*)(A1, A2, A3, A4, A5) const> { williamr@2: typedef T type; williamr@2: typedef U class_type; williamr@2: typedef const U qualified_class_type; williamr@2: BOOST_STATIC_CONSTANT(bool, is_data_member = false); williamr@2: BOOST_STATIC_CONSTANT(bool, is_function_member = true); williamr@2: }; williamr@2: template<class T, class U, class A1, class A2, class A3, class A4, class A5, williamr@2: class A6> williamr@2: struct member_pointer<T (U::*)(A1, A2, A3, A4, A5, A6) const> { williamr@2: typedef T type; williamr@2: typedef U class_type; williamr@2: typedef const U qualified_class_type; williamr@2: BOOST_STATIC_CONSTANT(bool, is_data_member = false); williamr@2: BOOST_STATIC_CONSTANT(bool, is_function_member = true); williamr@2: }; williamr@2: template<class T, class U, class A1, class A2, class A3, class A4, class A5, williamr@2: class A6, class A7> williamr@2: struct member_pointer<T (U::*)(A1, A2, A3, A4, A5, A6, A7) const> { williamr@2: typedef T type; williamr@2: typedef U class_type; williamr@2: typedef const U qualified_class_type; williamr@2: BOOST_STATIC_CONSTANT(bool, is_data_member = false); williamr@2: BOOST_STATIC_CONSTANT(bool, is_function_member = true); williamr@2: }; williamr@2: template<class T, class U, class A1, class A2, class A3, class A4, class A5, williamr@2: class A6, class A7, class A8> williamr@2: struct member_pointer<T (U::*)(A1, A2, A3, A4, A5, A6, A7, A8) const> { williamr@2: typedef T type; williamr@2: typedef U class_type; williamr@2: typedef const U qualified_class_type; williamr@2: BOOST_STATIC_CONSTANT(bool, is_data_member = false); williamr@2: BOOST_STATIC_CONSTANT(bool, is_function_member = true); williamr@2: }; williamr@2: template<class T, class U, class A1, class A2, class A3, class A4, class A5, williamr@2: class A6, class A7, class A8, class A9> williamr@2: struct member_pointer<T (U::*)(A1, A2, A3, A4, A5, A6, A7, A8, A9) const> { williamr@2: typedef T type; williamr@2: typedef U class_type; williamr@2: typedef const U qualified_class_type; williamr@2: BOOST_STATIC_CONSTANT(bool, is_data_member = false); williamr@2: BOOST_STATIC_CONSTANT(bool, is_function_member = true); williamr@2: }; williamr@2: // -- volatile -- williamr@2: template<class T, class U> williamr@2: struct member_pointer<T (U::*)() volatile> { williamr@2: typedef T type; williamr@2: typedef U class_type; williamr@2: typedef volatile U qualified_class_type; williamr@2: BOOST_STATIC_CONSTANT(bool, is_data_member = false); williamr@2: BOOST_STATIC_CONSTANT(bool, is_function_member = true); williamr@2: }; williamr@2: template<class T, class U, class A1> williamr@2: struct member_pointer<T (U::*)(A1) volatile> { williamr@2: typedef T type; williamr@2: typedef U class_type; williamr@2: typedef volatile U qualified_class_type; williamr@2: BOOST_STATIC_CONSTANT(bool, is_data_member = false); williamr@2: BOOST_STATIC_CONSTANT(bool, is_function_member = true); williamr@2: }; williamr@2: template<class T, class U, class A1, class A2> williamr@2: struct member_pointer<T (U::*)(A1, A2) volatile> { williamr@2: typedef T type; williamr@2: typedef U class_type; williamr@2: typedef volatile U qualified_class_type; williamr@2: BOOST_STATIC_CONSTANT(bool, is_data_member = false); williamr@2: BOOST_STATIC_CONSTANT(bool, is_function_member = true); williamr@2: }; williamr@2: template<class T, class U, class A1, class A2, class A3> williamr@2: struct member_pointer<T (U::*)(A1, A2, A3) volatile> { williamr@2: typedef T type; williamr@2: typedef U class_type; williamr@2: typedef volatile U qualified_class_type; williamr@2: BOOST_STATIC_CONSTANT(bool, is_data_member = false); williamr@2: BOOST_STATIC_CONSTANT(bool, is_function_member = true); williamr@2: }; williamr@2: template<class T, class U, class A1, class A2, class A3, class A4> williamr@2: struct member_pointer<T (U::*)(A1, A2, A3, A4) volatile> { williamr@2: typedef T type; williamr@2: typedef U class_type; williamr@2: typedef volatile U qualified_class_type; williamr@2: BOOST_STATIC_CONSTANT(bool, is_data_member = false); williamr@2: BOOST_STATIC_CONSTANT(bool, is_function_member = true); williamr@2: }; williamr@2: template<class T, class U, class A1, class A2, class A3, class A4, class A5> williamr@2: struct member_pointer<T (U::*)(A1, A2, A3, A4, A5) volatile> { williamr@2: typedef T type; williamr@2: typedef U class_type; williamr@2: typedef volatile U qualified_class_type; williamr@2: BOOST_STATIC_CONSTANT(bool, is_data_member = false); williamr@2: BOOST_STATIC_CONSTANT(bool, is_function_member = true); williamr@2: }; williamr@2: template<class T, class U, class A1, class A2, class A3, class A4, class A5, williamr@2: class A6> williamr@2: struct member_pointer<T (U::*)(A1, A2, A3, A4, A5, A6) volatile> { williamr@2: typedef T type; williamr@2: typedef U class_type; williamr@2: typedef volatile U qualified_class_type; williamr@2: BOOST_STATIC_CONSTANT(bool, is_data_member = false); williamr@2: BOOST_STATIC_CONSTANT(bool, is_function_member = true); williamr@2: }; williamr@2: template<class T, class U, class A1, class A2, class A3, class A4, class A5, williamr@2: class A6, class A7> williamr@2: struct member_pointer<T (U::*)(A1, A2, A3, A4, A5, A6, A7) volatile> { williamr@2: typedef T type; williamr@2: typedef U class_type; williamr@2: typedef volatile U qualified_class_type; williamr@2: BOOST_STATIC_CONSTANT(bool, is_data_member = false); williamr@2: BOOST_STATIC_CONSTANT(bool, is_function_member = true); williamr@2: }; williamr@2: template<class T, class U, class A1, class A2, class A3, class A4, class A5, williamr@2: class A6, class A7, class A8> williamr@2: struct member_pointer<T (U::*)(A1, A2, A3, A4, A5, A6, A7, A8) volatile> { williamr@2: typedef T type; williamr@2: typedef U class_type; williamr@2: typedef volatile U qualified_class_type; williamr@2: BOOST_STATIC_CONSTANT(bool, is_data_member = false); williamr@2: BOOST_STATIC_CONSTANT(bool, is_function_member = true); williamr@2: }; williamr@2: template<class T, class U, class A1, class A2, class A3, class A4, class A5, williamr@2: class A6, class A7, class A8, class A9> williamr@2: struct member_pointer<T (U::*)(A1, A2, A3, A4, A5, A6, A7, A8, A9) volatile> { williamr@2: typedef T type; williamr@2: typedef U class_type; williamr@2: typedef volatile U qualified_class_type; williamr@2: BOOST_STATIC_CONSTANT(bool, is_data_member = false); williamr@2: BOOST_STATIC_CONSTANT(bool, is_function_member = true); williamr@2: }; williamr@2: // -- const volatile williamr@2: template<class T, class U> williamr@2: struct member_pointer<T (U::*)() const volatile> { williamr@2: typedef T type; williamr@2: typedef U class_type; williamr@2: typedef const volatile U qualified_class_type; williamr@2: BOOST_STATIC_CONSTANT(bool, is_data_member = false); williamr@2: BOOST_STATIC_CONSTANT(bool, is_function_member = true); williamr@2: }; williamr@2: template<class T, class U, class A1> williamr@2: struct member_pointer<T (U::*)(A1) const volatile> { williamr@2: typedef T type; williamr@2: typedef U class_type; williamr@2: typedef const volatile U qualified_class_type; williamr@2: BOOST_STATIC_CONSTANT(bool, is_data_member = false); williamr@2: BOOST_STATIC_CONSTANT(bool, is_function_member = true); williamr@2: }; williamr@2: template<class T, class U, class A1, class A2> williamr@2: struct member_pointer<T (U::*)(A1, A2) const volatile> { williamr@2: typedef T type; williamr@2: typedef U class_type; williamr@2: typedef const volatile U qualified_class_type; williamr@2: BOOST_STATIC_CONSTANT(bool, is_data_member = false); williamr@2: BOOST_STATIC_CONSTANT(bool, is_function_member = true); williamr@2: }; williamr@2: template<class T, class U, class A1, class A2, class A3> williamr@2: struct member_pointer<T (U::*)(A1, A2, A3) const volatile> { williamr@2: typedef T type; williamr@2: typedef U class_type; williamr@2: typedef const volatile U qualified_class_type; williamr@2: BOOST_STATIC_CONSTANT(bool, is_data_member = false); williamr@2: BOOST_STATIC_CONSTANT(bool, is_function_member = true); williamr@2: }; williamr@2: template<class T, class U, class A1, class A2, class A3, class A4> williamr@2: struct member_pointer<T (U::*)(A1, A2, A3, A4) const volatile> { williamr@2: typedef T type; williamr@2: typedef U class_type; williamr@2: typedef const volatile U qualified_class_type; williamr@2: }; williamr@2: template<class T, class U, class A1, class A2, class A3, class A4, class A5> williamr@2: struct member_pointer<T (U::*)(A1, A2, A3, A4, A5) const volatile> { williamr@2: typedef T type; williamr@2: typedef U class_type; williamr@2: typedef const volatile U qualified_class_type; williamr@2: BOOST_STATIC_CONSTANT(bool, is_data_member = false); williamr@2: BOOST_STATIC_CONSTANT(bool, is_function_member = true); williamr@2: }; williamr@2: template<class T, class U, class A1, class A2, class A3, class A4, class A5, williamr@2: class A6> williamr@2: struct member_pointer<T (U::*)(A1, A2, A3, A4, A5, A6) const volatile> { williamr@2: typedef T type; williamr@2: typedef U class_type; williamr@2: typedef const volatile U qualified_class_type; williamr@2: BOOST_STATIC_CONSTANT(bool, is_data_member = false); williamr@2: BOOST_STATIC_CONSTANT(bool, is_function_member = true); williamr@2: }; williamr@2: template<class T, class U, class A1, class A2, class A3, class A4, class A5, williamr@2: class A6, class A7> williamr@2: struct member_pointer<T (U::*)(A1, A2, A3, A4, A5, A6, A7) const volatile> { williamr@2: typedef T type; williamr@2: typedef U class_type; williamr@2: typedef const volatile U qualified_class_type; williamr@2: BOOST_STATIC_CONSTANT(bool, is_data_member = false); williamr@2: BOOST_STATIC_CONSTANT(bool, is_function_member = true); williamr@2: }; williamr@2: template<class T, class U, class A1, class A2, class A3, class A4, class A5, williamr@2: class A6, class A7, class A8> williamr@2: struct member_pointer<T (U::*)(A1, A2, A3, A4, A5, A6, A7, A8) const volatile> { williamr@2: typedef T type; williamr@2: typedef U class_type; williamr@2: typedef const volatile U qualified_class_type; williamr@2: BOOST_STATIC_CONSTANT(bool, is_data_member = false); williamr@2: BOOST_STATIC_CONSTANT(bool, is_function_member = true); williamr@2: }; williamr@2: template<class T, class U, class A1, class A2, class A3, class A4, class A5, williamr@2: class A6, class A7, class A8, class A9> williamr@2: struct member_pointer<T (U::*)(A1, A2, A3, A4, A5, A6, A7, A8, A9) const volatile> { williamr@2: typedef T type; williamr@2: typedef U class_type; williamr@2: typedef const volatile U qualified_class_type; williamr@2: BOOST_STATIC_CONSTANT(bool, is_data_member = false); williamr@2: BOOST_STATIC_CONSTANT(bool, is_function_member = true); williamr@2: }; williamr@2: williamr@2: } // detail williamr@2: williamr@2: namespace detail { williamr@2: williamr@2: // this class holds a pointer to a member function and the object. williamr@2: // when called, it just calls the member function with the parameters williamr@2: // provided williamr@2: williamr@2: // It would have been possible to use existing lambda_functors to represent williamr@2: // a bound member function like this, but to have a separate template is williamr@2: // safer, since now this functor doesn't mix and match with lambda_functors williamr@2: // only thing you can do with this is to call it williamr@2: williamr@2: // note that previously instantiated classes williamr@2: // (other_action<member_pointer_action> and member_pointer_action_helper williamr@2: // guarantee, that A and B are williamr@2: // such types, that for objects a and b of corresponding types, a->*b leads williamr@2: // to the builtin ->* to be called. So types that would end in a call to williamr@2: // a user defined ->* do not create a member_pointer_caller object. williamr@2: williamr@2: template<class RET, class A, class B> williamr@2: class member_pointer_caller { williamr@2: A a; B b; williamr@2: williamr@2: public: williamr@2: member_pointer_caller(const A& aa, const B& bb) : a(aa), b(bb) {} williamr@2: williamr@2: RET operator()() const { return (a->*b)(); } williamr@2: williamr@2: template<class A1> williamr@2: RET operator()(const A1& a1) const { return (a->*b)(a1); } williamr@2: williamr@2: template<class A1, class A2> williamr@2: RET operator()(const A1& a1, const A2& a2) const { return (a->*b)(a1, a2); } williamr@2: williamr@2: template<class A1, class A2, class A3> williamr@2: RET operator()(const A1& a1, const A2& a2, const A3& a3) const { williamr@2: return (a->*b)(a1, a2, a3); williamr@2: } williamr@2: williamr@2: template<class A1, class A2, class A3, class A4> williamr@2: RET operator()(const A1& a1, const A2& a2, const A3& a3, williamr@2: const A4& a4) const { williamr@2: return (a->*b)(a1, a2, a3, a4); williamr@2: } williamr@2: williamr@2: template<class A1, class A2, class A3, class A4, class A5> williamr@2: RET operator()(const A1& a1, const A2& a2, const A3& a3, const A4& a4, williamr@2: const A5& a5) const { williamr@2: return (a->*b)(a1, a2, a3, a4, a5); williamr@2: } williamr@2: williamr@2: template<class A1, class A2, class A3, class A4, class A5, class A6> williamr@2: RET operator()(const A1& a1, const A2& a2, const A3& a3, const A4& a4, williamr@2: const A5& a5, const A6& a6) const { williamr@2: return (a->*b)(a1, a2, a3, a4, a5, a6); williamr@2: } williamr@2: williamr@2: template<class A1, class A2, class A3, class A4, class A5, class A6, williamr@2: class A7> williamr@2: RET operator()(const A1& a1, const A2& a2, const A3& a3, const A4& a4, williamr@2: const A5& a5, const A6& a6, const A7& a7) const { williamr@2: return (a->*b)(a1, a2, a3, a4, a5, a6, a7); williamr@2: } williamr@2: williamr@2: template<class A1, class A2, class A3, class A4, class A5, class A6, williamr@2: class A7, class A8> williamr@2: RET operator()(const A1& a1, const A2& a2, const A3& a3, const A4& a4, williamr@2: const A5& a5, const A6& a6, const A7& a7, williamr@2: const A8& a8) const { williamr@2: return (a->*b)(a1, a2, a3, a4, a5, a6, a7, a8); williamr@2: } williamr@2: williamr@2: template<class A1, class A2, class A3, class A4, class A5, class A6, williamr@2: class A7, class A8, class A9> williamr@2: RET operator()(const A1& a1, const A2& a2, const A3& a3, const A4& a4, williamr@2: const A5& a5, const A6& a6, const A7& a7, williamr@2: const A8& a8, const A9& a9) const { williamr@2: return (a->*b)(a1, a2, a3, a4, a5, a6, a7, a8, a9); williamr@2: } williamr@2: williamr@2: }; williamr@2: williamr@2: // helper templates for return type deduction and action classes williamr@2: // different cases for data member, function member, neither williamr@2: williamr@2: // true-true case williamr@2: template <bool Is_data_member, bool Is_function_member> williamr@2: struct member_pointer_action_helper; williamr@2: // cannot be both, no body provided williamr@2: williamr@2: // data member case williamr@2: // this means, that B is a data member and A is a pointer type, williamr@2: // so either built-in ->* should be called, or there is an error williamr@2: template <> williamr@2: struct member_pointer_action_helper<true, false> { williamr@2: public: williamr@2: williamr@2: template<class RET, class A, class B> williamr@2: static RET apply(A& a, B& b) { williamr@2: return a->*b; williamr@2: } williamr@2: williamr@2: template<class A, class B> williamr@2: struct return_type { williamr@2: private: williamr@2: typedef typename detail::remove_reference_and_cv<B>::type plainB; williamr@2: williamr@2: typedef typename detail::member_pointer<plainB>::type type0; williamr@2: // we remove the reference now, as we may have to add cv:s williamr@2: typedef typename boost::remove_reference<type0>::type type1; williamr@2: williamr@2: // A is a reference to pointer williamr@2: // remove the top level cv qualifiers and reference williamr@2: typedef typename williamr@2: detail::remove_reference_and_cv<A>::type non_ref_A; williamr@2: williamr@2: // A is a pointer type, so take the type pointed to williamr@2: typedef typename ::boost::remove_pointer<non_ref_A>::type non_pointer_A; williamr@2: williamr@2: public: williamr@2: // For non-reference types, we must add const and/or volatile if williamr@2: // the pointer type has these qualifiers williamr@2: // If the member is a reference, these do not have any effect williamr@2: // (cv T == T if T is a reference type) williamr@2: typedef typename detail::IF< williamr@2: ::boost::is_const<non_pointer_A>::value, williamr@2: typename ::boost::add_const<type1>::type, williamr@2: type1 williamr@2: >::RET type2; williamr@2: typedef typename detail::IF< williamr@2: ::boost::is_volatile<non_pointer_A>::value, williamr@2: typename ::boost::add_volatile<type2>::type, williamr@2: type2 williamr@2: >::RET type3; williamr@2: // add reference back williamr@2: typedef typename ::boost::add_reference<type3>::type type; williamr@2: }; williamr@2: }; williamr@2: williamr@2: // neither case williamr@2: template <> williamr@2: struct member_pointer_action_helper<false, false> { williamr@2: public: williamr@2: template<class RET, class A, class B> williamr@2: static RET apply(A& a, B& b) { williamr@2: // not a built in member pointer operator, just call ->* williamr@2: return a->*b; williamr@2: } williamr@2: // an overloaded member pointer operators, user should have specified williamr@2: // the return type williamr@2: // At this point we know that there is no matching specialization for williamr@2: // return_type_2, so try return_type_2_plain williamr@2: template<class A, class B> williamr@2: struct return_type { williamr@2: williamr@2: typedef typename plain_return_type_2< williamr@2: other_action<member_pointer_action>, A, B williamr@2: >::type type; williamr@2: }; williamr@2: williamr@2: }; williamr@2: williamr@2: williamr@2: // member pointer function case williamr@2: // This is a built in ->* call for a member function, williamr@2: // the only thing that you can do with that, is to give it some arguments williamr@2: // note, it is guaranteed that A is a pointer type, and thus it cannot williamr@2: // be a call to overloaded ->* williamr@2: template <> williamr@2: struct member_pointer_action_helper<false, true> { williamr@2: public: williamr@2: williamr@2: template<class RET, class A, class B> williamr@2: static RET apply(A& a, B& b) { williamr@2: typedef typename ::boost::remove_cv<B>::type plainB; williamr@2: typedef typename detail::member_pointer<plainB>::type ret_t; williamr@2: typedef typename ::boost::remove_cv<A>::type plainA; williamr@2: williamr@2: // we always strip cv:s to williamr@2: // make the two routes (calling and type deduction) williamr@2: // to give the same results (and the const does not make any functional williamr@2: // difference) williamr@2: return detail::member_pointer_caller<ret_t, plainA, plainB>(a, b); williamr@2: } williamr@2: williamr@2: template<class A, class B> williamr@2: struct return_type { williamr@2: typedef typename detail::remove_reference_and_cv<B>::type plainB; williamr@2: typedef typename detail::member_pointer<plainB>::type ret_t; williamr@2: typedef typename detail::remove_reference_and_cv<A>::type plainA; williamr@2: williamr@2: typedef detail::member_pointer_caller<ret_t, plainA, plainB> type; williamr@2: }; williamr@2: }; williamr@2: williamr@2: } // detail williamr@2: williamr@2: template<> class other_action<member_pointer_action> { williamr@2: public: williamr@2: template<class RET, class A, class B> williamr@2: static RET apply(A& a, B& b) { williamr@2: typedef typename williamr@2: ::boost::remove_cv<B>::type plainB; williamr@2: williamr@2: return detail::member_pointer_action_helper< williamr@2: boost::is_pointer<A>::value && williamr@2: detail::member_pointer<plainB>::is_data_member, williamr@2: boost::is_pointer<A>::value && williamr@2: detail::member_pointer<plainB>::is_function_member williamr@2: >::template apply<RET>(a, b); williamr@2: } williamr@2: }; williamr@2: williamr@2: // return type deduction -- williamr@2: williamr@2: // If the right argument is a pointer to data member, williamr@2: // and the left argument is of compatible pointer to class type williamr@2: // return type is a reference to the data member type williamr@2: williamr@2: // if right argument is a pointer to a member function, and the left williamr@2: // argument is of a compatible type, the return type is a williamr@2: // member_pointer_caller (see above) williamr@2: williamr@2: // Otherwise, return type deduction fails. There is either an error, williamr@2: // or the user is trying to call an overloaded ->* williamr@2: // In such a case either ret<> must be used, or a return_type_2 user williamr@2: // defined specialization must be provided williamr@2: williamr@2: williamr@2: template<class A, class B> williamr@2: struct return_type_2<other_action<member_pointer_action>, A, B> { williamr@2: private: williamr@2: typedef typename williamr@2: detail::remove_reference_and_cv<B>::type plainB; williamr@2: public: williamr@2: typedef typename williamr@2: detail::member_pointer_action_helper< williamr@2: detail::member_pointer<plainB>::is_data_member, williamr@2: detail::member_pointer<plainB>::is_function_member williamr@2: >::template return_type<A, B>::type type; williamr@2: }; williamr@2: williamr@2: // this is the way the generic lambda_functor_base functions instantiate williamr@2: // return type deduction. We turn it into return_type_2, so that the williamr@2: // user can provide specializations on that level. williamr@2: template<class Args> williamr@2: struct return_type_N<other_action<member_pointer_action>, Args> { williamr@2: typedef typename boost::tuples::element<0, Args>::type A; williamr@2: typedef typename boost::tuples::element<1, Args>::type B; williamr@2: typedef typename williamr@2: return_type_2<other_action<member_pointer_action>, williamr@2: typename boost::remove_reference<A>::type, williamr@2: typename boost::remove_reference<B>::type williamr@2: >::type type; williamr@2: }; williamr@2: williamr@2: williamr@2: template<class Arg1, class Arg2> williamr@2: inline const williamr@2: lambda_functor< williamr@2: lambda_functor_base< williamr@2: action<2, other_action<member_pointer_action> >, williamr@2: tuple<lambda_functor<Arg1>, typename const_copy_argument<Arg2>::type> williamr@2: > williamr@2: > williamr@2: operator->*(const lambda_functor<Arg1>& a1, const Arg2& a2) williamr@2: { williamr@2: return williamr@2: lambda_functor_base< williamr@2: action<2, other_action<member_pointer_action> >, williamr@2: tuple<lambda_functor<Arg1>, typename const_copy_argument<Arg2>::type> williamr@2: > williamr@2: (tuple<lambda_functor<Arg1>, williamr@2: typename const_copy_argument<Arg2>::type>(a1, a2)); williamr@2: } williamr@2: williamr@2: template<class Arg1, class Arg2> williamr@2: inline const williamr@2: lambda_functor< williamr@2: lambda_functor_base< williamr@2: action<2, other_action<member_pointer_action> >, williamr@2: tuple<lambda_functor<Arg1>, lambda_functor<Arg2> > williamr@2: > williamr@2: > williamr@2: operator->*(const lambda_functor<Arg1>& a1, const lambda_functor<Arg2>& a2) williamr@2: { williamr@2: return williamr@2: lambda_functor_base< williamr@2: action<2, other_action<member_pointer_action> >, williamr@2: tuple<lambda_functor<Arg1>, lambda_functor<Arg2> > williamr@2: > williamr@2: (tuple<lambda_functor<Arg1>, lambda_functor<Arg2> >(a1, a2)); williamr@2: } williamr@2: williamr@2: template<class Arg1, class Arg2> williamr@2: inline const williamr@2: lambda_functor< williamr@2: lambda_functor_base< williamr@2: action<2, other_action<member_pointer_action> >, williamr@2: tuple<typename const_copy_argument<Arg1>::type, lambda_functor<Arg2> > williamr@2: > williamr@2: > williamr@2: operator->*(const Arg1& a1, const lambda_functor<Arg2>& a2) williamr@2: { williamr@2: return williamr@2: lambda_functor_base< williamr@2: action<2, other_action<member_pointer_action> >, williamr@2: tuple<typename const_copy_argument<Arg1>::type, lambda_functor<Arg2> > williamr@2: > williamr@2: (tuple<typename const_copy_argument<Arg1>::type, williamr@2: lambda_functor<Arg2> >(a1, a2)); williamr@2: } williamr@2: williamr@2: williamr@2: } // namespace lambda williamr@2: } // namespace boost williamr@2: williamr@2: williamr@2: #endif williamr@2: williamr@2: williamr@2: williamr@2: williamr@2: williamr@2: