[proto]howto generate extended tree top down instead of bottom up?

http://boost-sandbox.sourceforge.net/libs/proto/doc/html/boost_proto/users_g... contains: we want all expressions that involve the calculator placeholders to be calculators which means, IIUC, that calulator expressions are built bottom up. IOW, to build a calculator expressions, you must start with a proto terminal calculator expression. However, I would like to start from a non-terminal expression (e.g. any binary or unary expression) and convert all the nodes to calculator expressions. What's the simplest way to do this? I've tried understanding trans::construct and other trans templates; however, I can't figure it out so far :( TIA for any clues. -regards, Larry

Larry Evans wrote:
http://boost-sandbox.sourceforge.net/libs/proto/doc/html/boost_proto/users_g...
contains:
we want all expressions that involve the calculator placeholders to be calculators
which means, IIUC, that calulator expressions are built bottom up. IOW, to build a calculator expressions, you must start with a proto terminal calculator expression. However, I would like to start from a non-terminal expression (e.g. any binary or unary expression) and convert all the nodes to calculator expressions. What's the simplest way to do this? I've tried understanding trans::construct and other trans templates; however, I can't figure it out so far :(
TIA for any clues.
If you have an expression tree, and you want to wrap each node in some wrapper, the construct transform is what you want. For instance: #include <boost/xpressive/proto/proto.hpp> #include <boost/xpressive/proto/transform/construct.hpp> using namespace boost; using namespace proto; template<typename Expr> struct wrap { explicit wrap(Expr const &expr) {} }; struct WrapItUp : transform::construct< or_< terminal<_> , nary_expr<_, vararg<WrapItUp> > > , wrap<_>(_) > {}; terminal<int>::type const _1 = {1}; terminal<int>::type const _2 = {2}; int main() { int i = 0; WrapItUp::call( _1 + _2, i, i ); return 0; } This little example works, but if the wrap struct inherits from proto::extends, it doesn't compile because of a bug in construct<> which causes the eager instantiation of wrap<_>. You could write your own as_wrap transform which doesn't have that problem and use that instead of construct. HTH, -- Eric Niebler Boost Consulting www.boost-consulting.com

On 07/07/2007 11:49 AM, Eric Niebler wrote: [snip]
template<typename Expr> struct wrap { explicit wrap(Expr const &expr) {} };
Thanks very much Eric; however, I found that with the following: template<typename Expr> struct wrap #define INHERIT_EXPR #ifdef INHERIT_EXPR : Expr #endif { explicit wrap(Expr const &expr) { std::cout<<"Wrap::CTOR\n"; } }; the wrap CTOR is not called when: WrapItUp::call( _1 + _2, i, i ); is executed. OTOH, if INHERIT_EXPR is undefined, then wrap CTOR *is* called. There must be some typedef needed by wrap in order for WrapItUp::call to actually call the wrap CTOR. I'll start looking for it, but I'd appreciate any clues. TIA. -Larry

Larry Evans wrote:
On 07/07/2007 11:49 AM, Eric Niebler wrote: [snip]
template<typename Expr> struct wrap { explicit wrap(Expr const &expr) {} };
Thanks very much Eric; however, I found that with the following:
template<typename Expr> struct wrap #define INHERIT_EXPR #ifdef INHERIT_EXPR : Expr #endif { explicit wrap(Expr const &expr) { std::cout<<"Wrap::CTOR\n"; } };
the wrap CTOR is not called when:
WrapItUp::call( _1 + _2, i, i );
is executed. OTOH, if INHERIT_EXPR is undefined, then wrap CTOR *is* called.
This is construct<> being too clever by a half. The expr<> struct doesn't have a constructor. It uses brace initialization. The construct<> transform tries to accommodate that by using brace initialization for things that look like Proto expressions. But I see now that it can't really know, so I should break this up into separate construct<> and pod_construct<> transforms. -- Eric Niebler Boost Consulting www.boost-consulting.com

On 07/08/2007 09:42 AM, Eric Niebler wrote: [snip]
now that it can't really know, so I should break this up into separate construct<> and pod_construct<> transforms.
Thanks Eric. I starting looking for some typedef in proto::expr and tried "overriding" the: typedef expr proto_derived_expr; in proto::expr<> with: typedef wrap proto_derived_expr; in wrap, but that didn't work. I was planning on looking further; however, I guess I'd better just wait for a revised construct<>. Your last message just saved me, probably, a lot of time. Thanks again. Could you let me know when the revised construct<> is ready? TIA. -Larry

Larry Evans wrote:
Could you let me know when the revised construct<> is ready?
I've fixed the construct<> transform, and added pod_construct<> for use with aggregate types. In order to guarantee that these transforms do the right thing, I had to add a proto::is_transform<> metafunction. For any custom transforms that may appear within construct<> or pod_construct<>, this trait must be specialized. (It's already specialized for all of Proto's transforms.) I'll update the docs soon. -- Eric Niebler Boost Consulting www.boost-consulting.com
participants (2)
-
Eric Niebler
-
Larry Evans