[Proto] Functions returning an expression

I have a DSL defined in proto. What's the best wayt o build functions that returns an expression made of this DSl elements. Like let's say the vec_expr class support+-*/ operators I want to write ??? f( vec_expr<W> const& a, vec_expr<Y> const& b) { return (a+b)/(a-b); } How can I easily (aka no nested make_expr call) build the return type ? TIA -- ___________________________________________ Joel Falcou - Assistant Professor PARALL Team - LRI - Universite Paris Sud XI Tel : (+33)1 69 15 66 35

Joel Falcou wrote:
I have a DSL defined in proto. What's the best wayt o build functions that returns an expression made of this DSl elements. Like let's say the vec_expr class support+-*/ operators
I want to write
??? f( vec_expr<W> const& a, vec_expr<Y> const& b) { return (a+b)/(a-b); }
How can I easily (aka no nested make_expr call) build the return type ?
Why don't you want to use make_expr? That's what it's for. You build the return type with proto::result_of::make_expr, and call proto::make_expr() from with f(). http://tinyurl.com/5nhmgw -- Eric Niebler BoostPro Computing http://www.boostpro.com

Eric Niebler a écrit :
Why don't you want to use make_expr? That's what it's for. You build the return type with proto::result_of::make_expr, and call proto::make_expr() from with f().
I have nothing against make_expr for building a single node of the expression. I have tons of such function combining long chains of call and i don't thin chaing large amount o f make_expr is good. Is there a way to use BOOST_TYPEOF with proto ? So maybe i can write : BOOST_TYPEOF( (vec_expr<A>()+vec_expr<B>())/(vec_expr<A>()-vec_expr<B>()) f( ... ) {} -- ___________________________________________ Joel Falcou - Assistant Professor PARALL Team - LRI - Universite Paris Sud XI Tel : (+33)1 69 15 66 35

Joel Falcou wrote:
Eric Niebler a écrit :
Why don't you want to use make_expr? That's what it's for. You build the return type with proto::result_of::make_expr, and call proto::make_expr() from with f().
I have nothing against make_expr for building a single node of the expression. I have tons of such function combining long chains of call and i don't thin chaing large amount of make_expr is good.
Is there a way to use BOOST_TYPEOF with proto ? So maybe i can write :
BOOST_TYPEOF( (vec_expr<A>()+vec_expr<B>())/(vec_expr<A>()-vec_expr<B>()) f( ... ) {}
You could use BOOST_TYPEOF, but you need to be careful about lifetime
management. The resulting expression will have references to temporary
objects, and returning it without deep-copying it first will cause
dangling references.
You could get some mileage from the operator metafunctions. Eg:
template
::type const f(vec_expr<A> const &a, vec_expr<B> const &b) { vec_expr< typename proto::divides< vec_expr< typename proto::plus< vec_expr<A> const &, vec_expr<B> const & >::type >, vec_expr< typename proto::minus< vec_expr<A> const &, vec_expr<B> const & >::type > >::type that = {{{{a,b}},{{a,b}}}}; // assumes vec_expr uses // BOOST_PROTO_EXTENDS return that; }
This way you can be very explicit about what nodes are stored by reference and which are by value. I don't see this as better than make_expr, though, which is IMO your best bet. -- Eric Niebler BoostPro Computing http://www.boostpro.com

Eric Niebler a écrit :
Joel Falcou wrote:
Eric Niebler a écrit :
Why don't you want to use make_expr? That's what it's for. You build the return type with proto::result_of::make_expr, and call proto::make_expr() from with f().
I have nothing against make_expr for building a single node of the expression. I have tons of such function combining long chains of call and i don't thin chaing large amount of make_expr is good.
Is there a way to use BOOST_TYPEOF with proto ? So maybe i can write :
BOOST_TYPEOF( (vec_expr<A>()+vec_expr<B>())/(vec_expr<A>()-vec_expr<B>()) f( ... ) {}
You could use BOOST_TYPEOF, but you need to be careful about lifetime management. The resulting expression will have references to temporary objects, and returning it without deep-copying it first will cause dangling references.
You could get some mileage from the operator metafunctions. Eg:
template
vec_expr< typename proto::divides< vec_expr< typename proto::plus< vec_expr<A> const &, vec_expr<B> const & >::type >, vec_expr< typename proto::minus< vec_expr<A> const &, vec_expr<B> const & >::type > ::type const f(vec_expr<A> const &a, vec_expr<B> const &b) { vec_expr< typename proto::divides< vec_expr< typename proto::plus< vec_expr<A> const &, vec_expr<B> const & >::type >, vec_expr< typename proto::minus< vec_expr<A> const &, vec_expr<B> const & >::type > >::type that = {{{{a,b}},{{a,b}}}}; // assumes vec_expr uses // BOOST_PROTO_EXTENDS return that; }
This way you can be very explicit about what nodes are stored by reference and which are by value. I don't see this as better than make_expr, though, which is IMO your best bet.
OK, i've just skimmed through my files and well, the solution can't be other thign than make_expr due to this lifetime problem. Thanks for the head up though -- ___________________________________________ Joel Falcou - Assistant Professor PARALL Team - LRI - Universite Paris Sud XI Tel : (+33)1 69 15 66 35
participants (2)
-
Eric Niebler
-
Joel Falcou