
David A. Greene wrote:
Ok, I think I see what you're getting at. Yes, I think this is what I want. I was getting confused about transform::call() vs. Grammar::call(), thinking that what you suggest here would be infinite recursion. But I see that's not the case. In essence the code here is "walking up" the inheritance tree from subclass (transform) to superclass (Grammar), yes? And Grammar::call will do the same with whatever it's inherited from. And by default built-in proto expressions do a pass-through.
Yes, that's mostly correct. The types proto::shift_right and proto::unary_expr, for example, do a pass-through transform. Other types like proto::if_ and proto::expr have an identity transform. The docs describe the difference between these two, and which types have which transform.
Because proto uses CRTP, "walking up" the inheritance tree is in effect "walking down" the proto expression tree, and since Grammar::call is always invoked first, transforms are built bottom-up.
I hope I've got that right.
Well, you're getting warmer. :-) When you chain transforms by invoking Grammar::call(), the transforms are successively applied to the *same node* in the expression tree. Recursing into child nodes is the job of special transforms like pass-through (often the default) and fold. Here's how the pass-through transform works. Take a grammar like right_shift<A,B> and an expression like right_shift<X,Y>::type. (Assume that X matches A and Y matches B.) Applying the grammar's transform to the expression results in a new expression with this type: right_shift< A::apply<X,S,V>::type ,B::apply<Y,S,V>::type
::type
Here S and V are the types of the state and visitor parameters that just come along for the ride. So, calling Grammar::call() doesn't recurse to the children in general *unless* Grammar is one of these special transforms like pass-through. <snip>
Yes, it's possible, but not documented anywhere. My fault. You can say Expr::proto_arity::value, which is a compile-time integral constant. Nicer would be a proto::arity<> metafunction. I'll add it.
Cool.
I added it, and it's called proto::arity_of<>. -- Eric Niebler Boost Consulting www.boost-consulting.com The Astoria Seminar ==> http://www.astoriaseminar.com