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