On 5/29/2012 3:29 PM, Karsten Ahnert wrote: > 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?
Yes, I know. I said you should use fusion::fold, not proto::fold. Once you flatten a proto expression, you get a fusion sequence. That means you have to use a fusion algorithm on it. Proto's transforms expect their first parameter to be proto expression trees. The result of proto::flatten is emphatically not. -- Eric Niebler BoostPro Computing http://www.boostpro.com _______________________________________________ proto mailing list proto@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/proto