
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; }; 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()); 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. Finally, the is_actor trait doesn't seem work for extended actors.Is there a workaround for that? Thanks, Paul

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@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users

Thanks so much for the help. A couple more questions: 1) Is it possible to add an enable parameter to is_actor in futureversions of phoenix? 2) Is the is_actor trait used internally by phoenix? The reason I ask is I am thinking about using my own is_actor trait for my extended actors unitl maybe this gets updated in boost. ----- Original Message -----
From: Thomas Heller <thom.heller@googlemail.com> To: boost-users@lists.boost.org Cc: Sent: Thursday, February 23, 2012 2:42 AM Subject: Re: [Boost-users] [phoenix] Extending actors
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@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users

On 02/24/2012 06:11 PM, paul Fultz wrote:
Thanks so much for the help. A couple more questions:
1) Is it possible to add an enable parameter to is_actor in futureversions of phoenix?
is_actor is defined as: namespace boost { namespace phoenix { /////////////////////////////////////////////////////////////////////////////// // // is_actor<T> // // Tests if T is an actor. Evaluates to mpl::true_ or mpl::false_ // /////////////////////////////////////////////////////////////////////////////// template <typename T, typename Enable = void> struct is_actor : mpl::false_ {}; }}
2) Is the is_actor trait used internally by phoenix? The reason I ask is I am thinking about using my own is_actor trait for my extended actors unitl maybe this gets updated in boost.
At the moment it is not really used internally by phoenix. But it is used by, for example spirit.

Ok Thanks. I was looking at the specializations and didn't even see the enable parameters. ----- Original Message -----
From: Thomas Heller <thom.heller@googlemail.com> To: boost-users@lists.boost.org Cc: Sent: Saturday, February 25, 2012 7:43 AM Subject: Re: [Boost-users] [phoenix] Extending actors
On 02/24/2012 06:11 PM, paul Fultz wrote:
Thanks so much for the help. A couple more questions:
1) Is it possible to add an enable parameter to is_actor in futureversions of phoenix?
is_actor is defined as:
namespace boost { namespace phoenix { /////////////////////////////////////////////////////////////////////////////// // // is_actor<T> // // Tests if T is an actor. Evaluates to mpl::true_ or mpl::false_ // ///////////////////////////////////////////////////////////////////////////////
template <typename T, typename Enable = void> struct is_actor : mpl::false_ {}; }}
2) Is the is_actor trait used internally by phoenix? The reason I ask is I am thinking about using my own is_actor trait for my extended actors unitl maybe this gets updated in boost.
At the moment it is not really used internally by phoenix. But it is used by, for example spirit. _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
participants (2)
-
paul Fultz
-
Thomas Heller