|
Proto : |
Subject: Re: [proto] restructuring expression
From: Eric Niebler (eric_at_[hidden])
Date: 2012-05-30 21:08:09
On 5/30/2012 4:22 PM, Karsten Ahnert wrote:
> Next trial:
>
> template< typename I > struct placeholder : I {};
>
> proto::terminal< placeholder< mpl::size_t< 0 > > >::type const arg1 = {};
>
> proto::display_expr(
> fusion::fold(
> proto::flatten( arg1 ) ,
> proto::functional::make_terminal()( 1.0 ) ,
> proto::functional::make_multiplies()
> )
> );
>
> gives a compilation error:
>
> /boost/proto/fusion.hpp:86:20: error: no type named proto_tag in
> const struct placeholder<mpl_::size_t<0ul> >
>
> It is difficult for me to figure out what happens here. Any ideas?
Right. proto::flatten uses the type of the top-most node to figure out
how to flatten the expression tree. E.g., if you passed arg1 * 32, the
top-most node is a multiplication, so it would produce a list [arg1,
32]. You're passing just a terminal, so it creates a 1-element list
containing the value of the terminal: [placeholder<I>]. Passing this to
proto::functional::make_multiplies results in the above error because
it's expecting a proto expression.
Try this:
#include <string>
#include <iostream>
#include <boost/proto/proto.hpp>
namespace mpl = boost::mpl;
namespace proto = boost::proto;
namespace fusion = boost::fusion;
using proto::_;
template< typename I > struct placeholder : I {};
proto::terminal< placeholder< mpl::size_t< 0 > > >::type const arg1
= {};
template< class Expr >
void eval( const Expr &e )
{
proto::display_expr(
fusion::fold(
proto::flatten( e ) ,
proto::functional::make_terminal()( 1.0 ) ,
proto::when<_,
proto::_make_multiplies(proto::_byval(proto::_state), proto::_byval(_))>()
)
);
}
int main()
{
eval( 2 * arg1 * 42.0 * arg1 );
}
It takes the multiplication tree, flattens it, and turns it back into a
multiplication tree in reversed order.
HTH,
-- Eric Niebler BoostPro Computing http://www.boostpro.com
Proto list run by eric at boostpro.com