Boost logo

Boost-Commit :

From: eric_at_[hidden]
Date: 2008-04-22 13:33:35


Author: eric_niebler
Date: 2008-04-22 13:33:34 EDT (Tue, 22 Apr 2008)
New Revision: 44723
URL: http://svn.boost.org/trac/boost/changeset/44723

Log:
special handling for operator->* when right operand is a member function pointer
Text files modified:
   branches/proto/v4/boost/proto/context/default.hpp | 58 +++++++++++++++++++++++++++++++
   branches/proto/v4/boost/proto/detail/decltype.hpp | 35 +++++++++++++++++++
   branches/proto/v4/boost/proto/proto_fwd.hpp | 2
   branches/proto/v4/boost/proto/transform/default.hpp | 72 +++++++++++++++++++++++++++++++++++++++
   4 files changed, 164 insertions(+), 3 deletions(-)

Modified: branches/proto/v4/boost/proto/context/default.hpp
==============================================================================
--- branches/proto/v4/boost/proto/context/default.hpp (original)
+++ branches/proto/v4/boost/proto/context/default.hpp 2008-04-22 13:33:34 EDT (Tue, 22 Apr 2008)
@@ -118,7 +118,6 @@
             BOOST_PROTO_BINARY_OP_RESULT(&, proto::tag::bitwise_and, make, make)
             BOOST_PROTO_BINARY_OP_RESULT(|, proto::tag::bitwise_or, make, make)
             BOOST_PROTO_BINARY_OP_RESULT(^, proto::tag::bitwise_xor, make, make)
- BOOST_PROTO_BINARY_OP_RESULT(->*, proto::tag::mem_ptr, make_mutable, make)
 
             BOOST_PROTO_BINARY_OP_RESULT(=, proto::tag::assign, make_mutable, make)
             BOOST_PROTO_BINARY_OP_RESULT(<<=, proto::tag::shift_left_assign, make_mutable, make)
@@ -135,6 +134,63 @@
         #undef BOOST_PROTO_UNARY_OP_RESULT
         #undef BOOST_PROTO_BINARY_OP_RESULT
 
+ /// INTERNAL ONLY
+ template<typename Expr, typename Context>
+ struct is_member_function_eval
+ {
+ typedef typename proto::result_of::child_c<Expr, 1>::type e1;
+ typedef typename proto::result_of::eval<UNREF(e1), Context>::type r1;
+ typedef typename remove_const<typename remove_reference<r1>::type>::type uncvref_r1;
+ typedef typename is_member_function_pointer<uncvref_r1>::type type;
+ BOOST_STATIC_CONSTANT(bool, value = type::value);
+ };
+
+ /// INTERNAL ONLY
+ template<typename Expr, typename Context, bool IsMemFunCall>
+ struct memfun_eval
+ {
+ private:
+ typedef typename result_of::child_c<Expr, 0>::type e0;
+ typedef typename result_of::child_c<Expr, 1>::type e1;
+ typedef typename proto::result_of::eval<UNREF(e0), Context>::type r0;
+ typedef typename proto::result_of::eval<UNREF(e1), Context>::type r1;
+ public:
+ BOOST_PROTO_DECLTYPE_(
+ proto::detail::make_mutable<r0>() ->* proto::detail::make<r1>()
+ , result_type
+ )
+ result_type operator ()(Expr &expr, Context &ctx) const
+ {
+ return proto::eval(proto::child_c<0>(expr), ctx)
+ ->* proto::eval(proto::child_c<1>(expr), ctx);
+ }
+ };
+
+ /// INTERNAL ONLY
+ template<typename Expr, typename Context>
+ struct memfun_eval<Expr, Context, true>
+ {
+ private:
+ typedef typename result_of::child_c<Expr, 0>::type e0;
+ typedef typename result_of::child_c<Expr, 1>::type e1;
+ typedef typename proto::result_of::eval<UNREF(e0), Context>::type r0;
+ typedef typename proto::result_of::eval<UNREF(e1), Context>::type r1;
+ public:
+ typedef detail::memfun<r0, r1> result_type;
+ result_type const operator ()(Expr &expr, Context &ctx) const
+ {
+ return detail::memfun<r0, r1>(
+ proto::eval(proto::child_c<0>(expr), ctx)
+ , proto::eval(proto::child_c<1>(expr), ctx)
+ );
+ }
+ };
+
+ template<typename Expr, typename Context>
+ struct default_eval<Expr, Context, tag::mem_ptr, 2>
+ : memfun_eval<Expr, Context, is_member_function_eval<Expr, Context>::value>
+ {};
+
             template<typename Expr, typename Context>
             struct default_eval<Expr, Context, proto::tag::terminal, 0>
             {

Modified: branches/proto/v4/boost/proto/detail/decltype.hpp
==============================================================================
--- branches/proto/v4/boost/proto/detail/decltype.hpp (original)
+++ branches/proto/v4/boost/proto/detail/decltype.hpp 2008-04-22 13:33:34 EDT (Tue, 22 Apr 2008)
@@ -12,9 +12,13 @@
 #include <boost/proto/detail/prefix.hpp> // must be first include
 #include <boost/config.hpp>
 #include <boost/preprocessor/cat.hpp>
+#include <boost/preprocessor/repetition/enum_params.hpp>
+#include <boost/preprocessor/repetition/enum_binary_params.hpp>
+#include <boost/preprocessor/repetition/repeat_from_to.hpp>
 #include <boost/mpl/if.hpp>
 #include <boost/type_traits/is_function.hpp>
 #include <boost/typeof/typeof.hpp>
+#include <boost/utility/result_of.hpp>
 #include <boost/proto/detail/suffix.hpp> // must be last include
 
 // If we're generating doxygen documentation, hide all the nasty
@@ -187,6 +191,37 @@
         //BOOST_MPL_ASSERT((is_same<void(*)(), result_of_fixup<void(* const &)()>::type>));
         //BOOST_MPL_ASSERT((is_same<void(*)(), result_of_fixup<void(&)()>::type>));
 
+ template<typename T, typename PMF>
+ struct memfun
+ {
+ typedef typename remove_const<typename remove_reference<PMF>::type>::type pmf_type;
+ typedef typename boost::result_of<pmf_type(T)>::type result_type;
+
+ memfun(T t, PMF pmf)
+ : obj(t)
+ , pmf(pmf)
+ {}
+
+ result_type operator()() const
+ {
+ return (detail::deref(obj).*pmf)();
+ }
+
+ #define M0(Z, N, DATA) \
+ template<BOOST_PP_ENUM_PARAMS_Z(Z, N, typename A)> \
+ result_type operator()(BOOST_PP_ENUM_BINARY_PARAMS_Z(Z, N, A, const &a)) const \
+ { \
+ return (detail::deref(obj).*pmf)(BOOST_PP_ENUM_PARAMS_Z(Z, N, a)); \
+ } \
+ /**/
+ BOOST_PP_REPEAT_FROM_TO(1, BOOST_PROTO_MAX_ARITY, M0, ~)
+ #undef M0
+
+ private:
+ T obj;
+ PMF pmf;
+ };
+
     } // namespace detail
 }}
 

Modified: branches/proto/v4/boost/proto/proto_fwd.hpp
==============================================================================
--- branches/proto/v4/boost/proto/proto_fwd.hpp (original)
+++ branches/proto/v4/boost/proto/proto_fwd.hpp 2008-04-22 13:33:34 EDT (Tue, 22 Apr 2008)
@@ -724,7 +724,7 @@
     struct make;
 
     template<typename Fun>
- struct bind;
+ struct lazy;
 
     template<typename Sequence, typename State, typename Fun>
     struct fold;

Modified: branches/proto/v4/boost/proto/transform/default.hpp
==============================================================================
--- branches/proto/v4/boost/proto/transform/default.hpp (original)
+++ branches/proto/v4/boost/proto/transform/default.hpp 2008-04-22 13:33:34 EDT (Tue, 22 Apr 2008)
@@ -120,7 +120,6 @@
             BOOST_PROTO_BINARY_OP_RESULT(&, tag::bitwise_and, make, make)
             BOOST_PROTO_BINARY_OP_RESULT(|, tag::bitwise_or, make, make)
             BOOST_PROTO_BINARY_OP_RESULT(^, tag::bitwise_xor, make, make)
- BOOST_PROTO_BINARY_OP_RESULT(->*, tag::mem_ptr, make_mutable, make)
 
             BOOST_PROTO_BINARY_OP_RESULT(=, tag::assign, make_mutable, make)
             BOOST_PROTO_BINARY_OP_RESULT(<<=, tag::shift_left_assign, make_mutable, make)
@@ -136,6 +135,77 @@
 
             #undef BOOST_PROTO_UNARY_OP_RESULT
             #undef BOOST_PROTO_BINARY_OP_RESULT
+
+ /// INTERNAL ONLY
+ template<typename Expr, typename State, typename Data>
+ struct is_member_function_invocation
+ {
+ typedef typename result_of::child_c<Expr, 1>::type e1;
+ typedef typename Grammar::template impl<e1, State, Data>::result_type r1;
+ typedef typename remove_const<typename remove_reference<r1>::type>::type uncvref_r1;
+ typedef typename is_member_function_pointer<uncvref_r1>::type type;
+ BOOST_STATIC_CONSTANT(bool, value = type::value);
+ };
+
+ /// INTERNAL ONLY
+ template<typename Expr, typename State, typename Data, bool IsMemFunCall>
+ struct memfun_impl
+ : transform_impl<Expr, State, Data>
+ {
+ private:
+ typedef typename result_of::child_c<Expr, 0>::type e0;
+ typedef typename result_of::child_c<Expr, 1>::type e1;
+ typedef typename Grammar::template impl<e0, State, Data>::result_type r0;
+ typedef typename Grammar::template impl<e1, State, Data>::result_type r1;
+ public:
+ BOOST_PROTO_DECLTYPE_(
+ proto::detail::make_mutable<r0>() ->* proto::detail::make<r1>()
+ , result_type
+ )
+ result_type operator ()(
+ typename memfun_impl::expr_param expr
+ , typename memfun_impl::state_param state
+ , typename memfun_impl::data_param data
+ ) const
+ {
+ typename Grammar::template impl<e0, State, Data> t0;
+ typename Grammar::template impl<e1, State, Data> t1;
+ return t0(proto::child_c<0>(expr), state, data)
+ ->* t1(proto::child_c<1>(expr), state, data);
+ }
+ };
+
+ /// INTERNAL ONLY
+ template<typename Expr, typename State, typename Data>
+ struct memfun_impl<Expr, State, Data, true>
+ : transform_impl<Expr, State, Data>
+ {
+ private:
+ typedef typename result_of::child_c<Expr, 0>::type e0;
+ typedef typename result_of::child_c<Expr, 1>::type e1;
+ typedef typename Grammar::template impl<e0, State, Data>::result_type r0;
+ typedef typename Grammar::template impl<e1, State, Data>::result_type r1;
+ public:
+ typedef detail::memfun<r0, r1> result_type;
+ result_type const operator ()(
+ typename memfun_impl::expr_param expr
+ , typename memfun_impl::state_param state
+ , typename memfun_impl::data_param data
+ ) const
+ {
+ typename Grammar::template impl<e0, State, Data> t0;
+ typename Grammar::template impl<e1, State, Data> t1;
+ return detail::memfun<r0, r1>(
+ t0(proto::child_c<0>(expr), state, data)
+ , t1(proto::child_c<1>(expr), state, data)
+ );
+ }
+ };
+
+ template<typename Expr, typename State, typename Data>
+ struct impl2<Expr, State, Data, tag::mem_ptr, 2>
+ : memfun_impl<Expr, State, Data, is_member_function_invocation<Expr, State, Data>::value>
+ {};
 
             template<typename Expr, typename State, typename Data>
             struct impl2<Expr, State, Data, tag::post_inc, 1>


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk