diff --git a/include/boost/lambda/detail/member_ptr.hpp b/include/boost/lambda/detail/member_ptr.hpp new file mode 100644 index 0000000..ad8c387 --- /dev/null +++ b/include/boost/lambda/detail/member_ptr.hpp @@ -0,0 +1,709 @@ +// Boost Lambda Library -- member_ptr.hpp --------------------- + +// Copyright (C) 1999, 2000 Jaakko Järvi (jaakko.jarvi@cs.utu.fi) +// Copyright (C) 2000 Gary Powell (gary.powell@sierra.com) +// +// Permission to copy, use, sell and distribute this software is granted +// provided this copyright notice appears in all copies. +// Permission to modify the code and to distribute modified code is granted +// provided this copyright notice appears in all copies, and a notice +// that the code was modified is included with the copyright notice. +// +// This software is provided "as is" without express or implied warranty, +// and with no claim as of its suitability for any purpose. +// +// For more information, see www.boost.org + +// -------------------------------------------------------------------------- + +#if !defined(BOOST_LAMBDA_MEMBER_PTR_HPP) +#define BOOST_LAMBDA_MEMBER_PTR_HPP + +namespace boost { +namespace lambda { + +namespace detail { + +// the boost type_traits member_pointer traits are not enough, +// need to know more details. +template +struct member_pointer { + BOOST_STATIC_CONSTANT(bool, is_data_member = false); + BOOST_STATIC_CONSTANT(bool, is_function_member = false); +}; + +template +struct member_pointer { + typedef typename boost::add_reference::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 +struct member_pointer { + typedef typename boost::add_reference::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 +struct member_pointer { + typedef typename boost::add_reference::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 +struct member_pointer { + typedef typename boost::add_reference::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 +struct member_pointer { + 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 +struct member_pointer { + 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 +struct member_pointer { + 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 +struct member_pointer { + 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 +struct member_pointer { + 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 +struct member_pointer { + 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 +struct member_pointer { + 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 +struct member_pointer { + 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 +struct member_pointer { + 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 +struct member_pointer { + 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 +struct member_pointer { + 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 +struct member_pointer { + 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 +struct member_pointer { + 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 +struct member_pointer { + 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 +struct member_pointer { + 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 +struct member_pointer { + 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 +struct member_pointer { + 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 +struct member_pointer { + 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 +struct member_pointer { + 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 +struct member_pointer { + 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 +struct member_pointer { + 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 +struct member_pointer { + 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 +struct member_pointer { + 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 +struct member_pointer { + 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 +struct member_pointer { + 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 +struct member_pointer { + 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 +struct member_pointer { + 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 +struct member_pointer { + 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 +struct member_pointer { + 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 +struct member_pointer { + 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 +struct member_pointer { + 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 +struct member_pointer { + 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 +struct member_pointer { + 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 +struct member_pointer { + 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 +struct member_pointer { + typedef T type; + typedef U class_type; + typedef const volatile U qualified_class_type; +}; +template +struct member_pointer { + 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 +struct member_pointer { + 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 +struct member_pointer { + 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 +struct member_pointer { + 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 +struct member_pointer { + 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 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 member_pointer_caller { + A a; + B b; +public: + member_pointer_caller(A aa, B bb) : a(aa), b(bb) {} + + RET operator()() const { return (a->*b)(); } + + template + RET operator()(const A1& a1) const { return (a->*b)(a1); } + + template + RET operator()(const A1& a1, const A2& a2) const { return (a->*b)(a1, a2); } + + template + RET operator()(const A1& a1, const A2& a2, const A3& a3) const { + return (a->*b)(a1, a2, a3); + } + + template + RET operator()(const A1& a1, const A2& a2, const A3& a3, + const A4& a4) const { + return (a->*b)(a1, a2, a3, a4); + } + + template + 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 + 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 + 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 + 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 + 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 +struct member_pointer_action_helper; + // cannot be both, no body provided + + // data member case +template <> +struct member_pointer_action_helper { +public: + template + static RET apply(A& a, B& b) { + return a->*b; + } + + template + struct return_type { + + typedef typename detail::remove_reference_and_cv::type plainB; + + typedef typename detail::member_pointer::type type1; + + // A is a pointer type + typedef typename ::boost::remove_pointer::type non_pointer_A; + + // 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::value, + typename ::boost::add_const::type, + type1 + >::RET type2; + typedef typename detail::IF< + ::boost::is_volatile::value, + typename ::boost::add_volatile::type, + type2 + >::RET type3; + typedef typename ::boost::add_reference::type type; + }; +}; + + // neither case +template <> +struct member_pointer_action_helper { +public: + template + 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 + template + struct return_type { + typedef typename + detail::generate_error::return_type_not_specified 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 +template <> +struct member_pointer_action_helper { + public: + + template + static RET apply(A& a, B& b) { + + typedef typename ::boost::remove_cv::type plainB; + typedef typename detail::member_pointer::type ret_t; + + return detail::member_pointer_caller(a, b); + } + + template + struct return_type { + typedef typename detail::remove_reference_and_cv::type plainB; + typedef typename detail::member_pointer::type ret_t; + typedef detail::member_pointer_caller type; + }; +}; + +} // detail + +class member_pointer_action {}; + +template<> class other_action { +public: + template + static RET apply(A& a, B& b) { + + typedef typename + ::boost::remove_cv::type plainB; + + return + detail::member_pointer_action_helper< + detail::member_pointer::is_data_member, + detail::member_pointer::is_function_member + >::template apply(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 +struct return_type_2, A, B> { + + typedef typename + detail::remove_reference_and_cv::type plainB; + typedef typename + detail::member_pointer::qualified_class_type B_class; + + typedef typename + detail::member_pointer_action_helper< + detail::member_pointer::is_data_member, + detail::member_pointer::is_function_member + >::template return_type::type type; +}; + + +template +inline const +lambda_functor< + lambda_functor_args< + action<2, other_action >, + tuple, typename const_copy_argument::type>, + combine_arities::value + > +> +operator->*(const lambda_functor& a1, const Arg2& a2) +{ + return + lambda_functor< + lambda_functor_args< + action<2, other_action >, + tuple, typename const_copy_argument::type>, + combine_arities::value + > + > (tuple, + typename const_copy_argument::type>(a1, a2)); +} + +template +inline const +lambda_functor< + lambda_functor_args< + action<2, other_action >, + tuple, lambda_functor >, + combine_arities::value + > +> +operator->*(const lambda_functor& a1, const lambda_functor& a2) +{ + return + lambda_functor< + lambda_functor_args< + action<2, other_action >, + tuple, lambda_functor >, + combine_arities::value + > + > (tuple, lambda_functor >(a1, a2)); +} + +template +inline const +lambda_functor< + lambda_functor_args< + action<2, other_action >, + tuple::type, lambda_functor >, + combine_arities::value + > +> +operator->*(const Arg1& a1, const lambda_functor& a2) +{ + return + lambda_functor< + lambda_functor_args< + action<2, other_action >, + tuple::type, lambda_functor >, + combine_arities::value + > + > (tuple::type, + lambda_functor >(a1, a2)); +} + + +} // namespace lambda +} // namespace boost + + +#endif + + + + + +