|
Boost : |
From: David A. Greene (greened_at_[hidden])
Date: 2007-07-14 17:16:02
On Wednesday 11 July 2007 01:47, Eric Niebler wrote:
> So, how can I look at code like the following and know that it's wrong?
>
> > Grammar::call(proto::right(expr),state,visitor)
>
> Because it violates the Transform Protocol. Grammar::call() invokes the
> transform associated with Grammar. expr matches Grammar, but right(expr)
> probably doesn't. To pass right(expr) to Grammar::call() would be to
> pass it an expression it doesn't know how to handle. A nasty compile
> error is sure to result.
Ok, that makes sense, I think.
> Perhaps what you mean to say is:
> > return(new typename apply<Expr, State, Visitor>::type(
> > proto::arg(proto::left(Grammar::call(expr,state,visitor))),
> > proto::right(Grammar::call(expr,state,visitor))));
>
> But it's hard to know without seeing more of your code.
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.
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.
> transform::arg is implemented in terms of proto::arg, and its
> implementation is simple and perhaps enlightening. Here is the
> implementation of transform::arg<Grammar,N>::call(expr,state,visitor)
>
> return proto::arg<N>(Grammar::call(expr, state, visitor));
>
> It follows the pattern of invoking Grammar's transform, then
> manipulating the result. That is how the chaining of transforms works.
>
> Many of the transforms are just that simple. Once you really grok the
> Transform Protocol, it won't seem so mysterious. I hope. :-)
Yes, this explanation was extremely helpful. I'm not at the level of grok yet
but I'm getting there. I had to stare at what you wrote here for a few
minutes, but it makes good sense.
> > Does this make sense? Is it possible?
>
> 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.
-Dave
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk