
I want to process a list that looks something like this: struct List : or_< comma< List, Item
, Item {};
But rather than processing each item separately, I want to pass a fusion (or some other) sequence to a semantic action: when< List, SomeAction(...)
{};
Ideally the argument to SomeAction would be a fusion sequence but I don't know how to produce one. This doesn't work: when< List, SomeAction(flatten(_))
{};
because flatten is not a transform. I don't want to use fold_tree because I don't want to actually fold the sequence. SomeAction is something like this: struct SomeAction : callable { template<typename Seq> void operator()(Seq range) { typedef ... iterator; // Is this legal for fusion sequences? for(iterator i = begin(range), iend = end(range); i != iend; i = next(i)) { ... } } } Is there a way to do this? On a related note, I know I can use varag<> to match a function call expression with an arbitrary number of operands and invoke a transform on each operand. But how would I generate a fusion sequence of all the operands? In other words, with: proto::function< X, proto::vararg<Y> > how do I talk about the vararg<> part in a semantic action? CalculatorGrammar has a use of vararg but it uses fold<> to process it. I don't want to fold a sequence, I want to pass it to a transform. Thanks! -Dave

On Mon, Feb 22, 2010 at 3:29 AM, David Greene
I want to process a list that looks something like this:
struct List : or_< comma< List, Item >, Item
{};
But rather than processing each item separately, I want to pass a fusion (or some other) sequence to a semantic action:
when< List, SomeAction(...)
{};
Ideally the argument to SomeAction would be a fusion sequence but I don't know how to produce one. This doesn't work:
when< List, SomeAction(flatten(_))
{};
because flatten is not a transform. I don't want to use fold_tree because I don't want to actually fold the sequence. SomeAction is something like this:
struct SomeAction : callable { template<typename Seq> void operator()(Seq range) { typedef ... iterator;
// Is this legal for fusion sequences? for(iterator i = begin(range), iend = end(range); i != iend; i = next(i)) { ... } } }
Is there a way to do this?
On a related note, I know I can use varag<> to match a function call expression with an arbitrary number of operands and invoke a transform on each operand. But how would I generate a fusion sequence of all the operands? In other words, with:
proto::function< X, proto::vararg<Y> >
how do I talk about the vararg<> part in a semantic action? CalculatorGrammar has a use of vararg but it uses fold<> to process it. I don't want to fold a sequence, I want to pass it to a transform.
I had something like
struct foo_tostr
: proto::or_
Thanks!
-Dave _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users

Hi David, On 2/22/2010 10:29 PM, David Greene wrote:
I want to process a list that looks something like this:
struct List : or_< comma< List, Item
, Item {};
But rather than processing each item separately, I want to pass a fusion (or some other) sequence to a semantic action:
when< List, SomeAction(...)
{};
Ideally the argument to SomeAction would be a fusion sequence but I don't know how to produce one. This doesn't work:
when< List, SomeAction(flatten(_))
{};
because flatten is not a transform.
You were SO close. You want proto::functional::flatten here (the type of a function object), not proto::flatten (an ordinary function).
I don't want to use fold_tree because I don't want to actually fold the sequence. SomeAction is something like this:
struct SomeAction : callable { template<typename Seq> void operator()(Seq range) { typedef ... iterator;
// Is this legal for fusion sequences? for(iterator i = begin(range), iend = end(range); i != iend; i = next(i)) { ... } } }
Is there a way to do this?
Try this:
#include <iostream>
#include
{};
struct ProcessList : when< List, SomeAction(functional::flatten(_))
{};
int main() { ProcessList()((lit(1), 2, 3, 4)); }
On a related note, I know I can use varag<> to match a function call expression with an arbitrary number of operands and invoke a transform on each operand. But how would I generate a fusion sequence of all the operands? In other words, with:
proto::function< X, proto::vararg<Y> >
how do I talk about the vararg<> part in a semantic action? CalculatorGrammar has a use of vararg but it uses fold<> to process it. I don't want to fold a sequence, I want to pass it to a transform.
Manjunath already answered this one. Proto expressions already are fusion sequences, and proto::_expr returns the current expression. You can use proto::functional::pop_front in a transform to pop off the first bit (the thing that matches X in your example) and pass the result to something that accepts fusion sequences. HTH, -- Eric Niebler BoostPro Computing http://www.boostpro.com

On Tuesday 23 February 2010 03:02:32 Eric Niebler wrote:
You were SO close. You want proto::functional::flatten here (the type of a function object), not proto::flatten (an ordinary function).
Bah! Foiled again! :)
how do I talk about the vararg<> part in a semantic action? CalculatorGrammar has a use of vararg but it uses fold<> to process it. I don't want to fold a sequence, I want to pass it to a transform.
Manjunath already answered this one. Proto expressions already are fusion sequences, and proto::_expr returns the current is, expression. You can use proto::functional::pop_front in a transform to pop off the first bit (the thing that matches X in your example) and pass the result to something that accepts fusion sequences.
I tried this, but the manual says _expr returns the unmodified expression. Is there some way to send this through a transform to get the transformed expressions? For example, for a call operator: Name(Item, Item, Item) I want to get a sequence of the objects returned by processing the Items. In my case I am creating IR symbols, so it would be a sequence of pointers. Each Item is a proto expression that is married to a transform that returns an IR symbol for it. Originally I was going to run a fold<> that returned a std::vector<> of pointers to IR symbols but that seems inefficient and messy. I think it would be better to simply take the transformed results as they are, if it's possible. I'm just learning Fusion and it's a bit confusing as to where the compile-time ends and the run-time starts. I think I probably want to use transform_view, but I'm not sure what kind of function object to give it. I've attached a rather complex testcase to show what I'm attempting to do. I don't claim it's bug-free because I haven't yet got it to compile. I'm sure there's a lot of work to do to fix it. I'm attaching it because it's difficult to describe this in English. :) A function object for transform_view<> should implement something like ConstructUnary/BinarySymbol but there's no way to know what expression nodes are in the sequence and thus which function object should be use (Unary or Binary). I know you're going to tell me something obvious that looks trivial in retrospect. :) The #if 0'd code is the way I'd like to specify the grammar (i.e. without the FunctionTypeWithArgs / FunctionTypeWithoutArgs separation but when I do that I get a compiler error about a reference to void. Probably because I'm sending a null sequence to ConstructBinarySymbol. Any improvements to be had here? BTW, what's the difference between proto::_ and proto::_expr, as pop_front(_) vs. pop_front(_expr)? From what I can tell the manual gives essentially the same short description for both. -Dave
participants (4)
-
David A. Greene
-
David Greene
-
Eric Niebler
-
Manjunath Kudlur