Boost logo

Boost Users :

Subject: Re: [Boost-users] [phoenix] Extending actors
From: Thomas Heller (thom.heller_at_[hidden])
Date: 2012-02-23 02:42:02


DISCLAIMER: All code was written without having been run through a
compiler. It might or might compile. This is due to a missing testcase.

On 02/23/2012 01:57 AM, paul Fultz wrote:
> Hi all,
>
> I am wanting to extend actors to access a member variable from the class. In the
> examples they show extending an acotr by using a lazy function to call the function.
> I was thinking I could use a lazy function to access the member, something like this:
>
> template<typename Expr>
> struct point_actor
> : actor<Expr>
> {
> typedef actor<Expr> base_type;
> typedef point_actor<Expr> that_type;
>
> point_actor( base_type const& base )
> : base_type( base ) {}
>
> typename expression::function<x_impl, that_type>::type x;
> typename expression::function<y_impl, that_type>::type y;
>
> };

The second template argument is the type for the first function
argument. In the example it is *this. and passed to the expression in
the member function.
In your example, you would need to initialize x properly, maybe like that:

typedef expression::function<x_impl, that_type> x_expr;
typedef expression::function<y_impl, that_type> y_expr;

point_actor(base_type const & base)
     : base_type(base)
     , x(x_expr::make(x_impl(), base))
     , y(y_expr::make(y_impl(), base))
{}

Might actually work (NOTE: due to the PODness of the expression, we need
to use the make function to create and initialize the expr properly!)

> Where x_impl and y_impl are lazy functions that access the x and y variable.
> Would this work as member variables, rather than member functions? Also,
> why wouldnt the second parameter to expression::function take just actor
> instead of just point_actor<Expr>? Does that make sense? The reason I ask is I would like to
> control the actor that is returned and do something like this(using the above actor):
>
> template<typename Expr>
> struct rect_actor
> : actor<Expr>
> {
> typedef actor<Expr> base_type;
> typedef rect_actor<Expr> that_type;
>
> rect_actor( base_type const& base )
> : base_type( base ) {}
>
> typename expression::function<top_impl, point_actor>::type top;
> typename expression::function<bottom_impl, point_actor>::type bottom;
>
> };
>
> expression::terminal<phoenix::argument<1>, rect_actor> arg1;
> (cout<< arg1.top.x)(my_rect());

Now this gets interesting ;)
To control the actor that gets returned, you have to implement some
trickery! This is of course possible.
Instead of:

typename expression::function<top_impl, point_actor>::type

You have to use your own expression type:

namespace expression
{
     // This is for a function taking two arguments ... (The functor and
     // the argument to the functor)
     template <template <typename> Actor, typename A0, typename A1>
     struct custom_actor_function
       : boost::phoenix::expr_ext<
         Actor // This is the actor we would
                                       // like to get the expression
                                       // get wrapped in.
       , boost::phoenix::tag::function // This tag is important, this
                                       // tells proto that this
                                       // expression is a lazy function.
       , A0
       , A1
> {};
}

now use it as follows:

typedef
     expression::custom_actor_function<
         rec_actor
       , top_impl
       , point_actor
>
     top_fun_expr;

typename top_fun_expr::type const
top()
{
     return top_fun_expr::make(top_impl(), *this);
}

This should let you write:

expression::terminal<phoenix::argument<1>, rect_actor> arg1;
(cout<< arg1.top().x())(my_rect());

> Does that make sense? I can't seem to find any reference on the predefined
> expressions, and I also can't find the header file for expression::function.

Shame on me ... the reference for the predefined expression is really
rudimentary. I didn't have the time to update them yet. Any help is
appreciated!

>
> Finally, the is_actor trait doesn't seem work for extended actors.Is there a
> workaround for that?

Yes, you need to specialize it for your actor.

> Thanks,
> Paul
>
> _______________________________________________
> Boost-users mailing list
> Boost-users_at_[hidden]
> http://lists.boost.org/mailman/listinfo.cgi/boost-users


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net