|
Boost : |
From: Eric Niebler (eric_at_[hidden])
Date: 2008-03-18 00:00:20
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
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk