Boost logo

Boost :

From: Eric Niebler (eric_at_[hidden])
Date: 2007-07-14 18:12:47


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

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk