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 mailing list proto@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/proto