Boost logo

Proto :

Subject: Re: [proto] Proto Transform Questions
From: Eric Niebler (eric_at_[hidden])
Date: 2011-01-15 23:36:27


On 1/15/2011 6:41 AM, Nate Knight wrote:
> On Jan 14, 2011, at 12:29 PM, Nate Knight wrote:
>
>> I've pasted some code below where I am trying to transform expressions of the form
>>
>> (a op b op c)[i]
>>
>> to
>>
>> (a[i] op b[i] op c[i])
>>
>> I managed to get this to work for the simple case
>>
>> (a+b)[i]
>>
>> but I'm curious about how to generalize this to include other operators (without explicitly handling them all). Also, as written the transform doesn't recurse properly, and I'm having some trouble seeing how to correct this.

This is a fun little problem. The answer is very simple, but requires
some knowledge of proto's pass_through transform, possessed by
proto::nary_expr (and friends):

// Take any expression and turn each node
// into a subscript expression, using the
// state as the RHS.
struct Distribute
  : or_<
        when<terminal<_>, _make_subscript(_, _state)>
      , nary_expr<_, vararg<Distribute> >
>
{};

struct Vectorize
  : or_<
        terminal<_>
      , when<subscript<_, _>, Distribute(_left, _right)>
      , nary_expr<_, vararg<Vectorize> >
>
{};

int main()
{
    terminal<char const *>::type a = {"a"};
    terminal<char const *>::type b = {"b"};
    terminal<char const *>::type c = {"c"};
    terminal<int>::type i = {42};

    display_expr( (a+b+c)[i] );

    display_expr( Vectorize()((a+b+c)[i]) );
}

HTH,

-- 
Eric Niebler
BoostPro Computing
http://www.boostpro.com

Proto list run by eric at boostpro.com