Proto :

Subject: Re: [proto] restructuring expression
From: Karsten Ahnert (karsten.ahnert_at_[hidden])
Date: 2012-05-29 18:29:11

On 05/29/2012 08:21 PM, Eric Niebler wrote:
> On 5/29/2012 1:44 AM, Karsten Ahnert wrote:
>> I have an arithmetic expression template where multiplication is
>> commutative. Is there an easy way to order a chain of multiplications
>> such that terminals with values (like proto::terminal< double >) appear
>> at the beginning? For example that
>>
>> arg1 * arg1 * 1.5 * arg1
>>
>> will be transformed to
>>
>> 1.5 * arg1 * arg1 * arg1
>>
>> ?
>>
>> I can imagine some complicated algorithms swapping expressions and child
>> expressions but I wonder if there is a simpler way.
>
> There is no clever built-in Proto algorithm for commutative
> transformations like this, I'm afraid. I was going to suggest flattening
> to a fusion vector and using fusion sort, but I see there is no fusion
> sort! :-( Nevertheless, that seems like a promising direction to me.
> Once you have the sorted vector, you should(?) be able to use
> fusion::fold to build the correct proto tree from it.

Ok, this looks promising. But I failed to get proto::fold to work. As a
first step I tried to flatten an expression and reconstruct it with
proto::fold:

struct back_fold :
proto::fold<
proto::_ ,
proto::_state ,
proto::functional::make_multiplies( proto::_state , proto::_ )
> { };

template< class Expr >
void eval( const Expr &e )
{
back_fold b;
proto::display_expr(
b( proto::flatten( e ) , proto::_make_terminal()( 1.0 ) )
);
}

eval( 2.0 * arg1 * arg1 * arg1 * 1.0 );

Unfortunately this does not compile. Any ideas what is wrong here?

Proto list run by eric at boostpro.com