Mail Delivery System wrote:
I need a transform property_b that evaluates another transform property_a and returns what property_a returns+1. Simple enough, here's what I do:
struct property_a : proto::or_< proto::when< proto::terminal<_>, mpl::int_<42>()>
{};
struct property_b : proto::or_ < proto::when< _, mpl::next<property_a(_) >() >
{};
proto::or_ in these two is unnecessary. For that matter, so is "(_)" in property_b.
The complete file is attached at the end of this message as "Working example".
But when I move to my real application (of which I attach a very condensed version as "Non-working example") I cannot manage to make it compile. The code in #ifdef BUG...#endif gives an error, the #else branch doesn't (but doesn't compute what I need, which makes the fact it compiles secondary). I cannot see differences, other than my terminals now being in their own domain.
There is an important difference, and it looks like a simple oversight. Here is the definition of actual_width_transform in your non-working example: struct actual_width_transform : proto::or_< //#define BUG #ifdef BUG mpl::next<left_bound_transform (_)>() #else left_bound_transform #endif
{}; Again, proto::or_ is unnecessary ... you only have one alternate. But I bet if you change the code to the following, it'll work: struct actual_width_transform : proto::when<_, mpl::next<left_bound_transform>()> {}; This is pretty much what you have in your "working example," which is why I think this is simply an oversight. You also appear to have gotten your terminology mixed up, and I think that's contributing to your confusion. You're calling these things "_transform", but they're actually grammars with nested transforms. "mpl::next<left_bound_transform>()" is indeed a transform, but transforms cannot be used on their own. They must be part of a grammar. That's what proto::when is for; it associates transforms with rules in a grammar. Hope that clears things up. -- Eric Niebler BoostPro Computing http://www.boostpro.com