
Markus Werle wrote:
Task 4: Write an expand function that for a*(b+c) returns a type representation a*b+a*c
The Expand transform defined below does this. #include <iostream> #include <boost/xpressive/proto/proto.hpp> #include <boost/xpressive/proto/debug.hpp> #include <boost/xpressive/proto/context.hpp> #include <boost/xpressive/proto/transform.hpp> using namespace boost; template<int I> struct arg { friend std::ostream &operator <<(std::ostream &sout, arg) { return sout << "arg<" << I << ">"; } }; proto::terminal<arg<1> >::type a; proto::terminal<arg<2> >::type b; proto::terminal<arg<3> >::type c; proto::terminal<arg<4> >::type d; using namespace proto; struct Expand; struct Recurse; struct Distribute : or_< when< plus<_,_> , _make_plus(Recurse(_left), Recurse(_right)) > , when< minus<_,_> , _make_minus(Recurse(_left), Recurse(_right)) > > {}; struct Recurse : or_< Distribute , when<Expand, _make_multiplies(_state, Expand)> > {}; struct Expand : or_< terminal<_> , when<multiplies<_, Distribute>, Distribute(_right, _left)> , nary_expr<_, vararg<Expand> > > {}; int main() { int ignore = 0; display_expr( Expand()(a*(b+c-d), ignore, ignore) ); } The above code fragment displays: minus( plus( multiplies( terminal(arg<1>) , terminal(arg<2>) ) , multiplies( terminal(arg<1>) , terminal(arg<3>) ) ) , multiplies( terminal(arg<1>) , terminal(arg<4>) ) ) I think that's right. That's a fun little problem. :-) -- Eric Niebler Boost Consulting www.boost-consulting.com