Boost logo

Boost Users :

Subject: [Boost-users] [proto] : Proto transform with state
From: Manjunath Kudlur (keveman_at_[hidden])
Date: 2010-11-17 01:47:48


I am trying to create a transform where I replace occurrences of
proto::terminal<term> with proto::terminal<newterm<mpl::int_<N> > >. I
want N to increment for every proto::terminal<term> encountered. So
far I have the following code :

#include <boost/proto/proto.hpp>
#include <boost/mpl/int.hpp>
#include <boost/mpl/arithmetic.hpp>
#include <iostream>

using namespace std;

namespace proto=boost::proto;
namespace mpl=boost::mpl;

struct term {};

template<typename>
struct newterm {};

proto::terminal<term>::type const a = {{}};
proto::terminal<term>::type const b = {{}};
proto::terminal<term>::type const c = {{}};

struct xform_callable
  : proto::callable {

  template<typename>
  struct result;

  template<typename This, typename N>
  struct result<This(const term &, N)> {
    typedef typename proto::result_of::make_expr<proto::tag::terminal,
newterm<N> >::type type;
  };

  template<typename This, typename tag, typename LHS, typename RHS>
  struct result<This(tag, LHS, RHS)> {
    typedef typename proto::result_of::make_expr<tag, LHS, RHS>::type type;
  };

  template<typename N>
  typename proto::result_of::make_expr<proto::tag::terminal, newterm<N> >::type
  operator()(const term &, N) {
    return proto::make_expr<proto::tag::terminal>(newterm<N>());
  }

  template<typename tag, typename LHS, typename RHS>
  typename proto::result_of::make_expr<tag, LHS, RHS>::type
  operator()(tag, LHS l, RHS r) const {
    return proto::make_expr<tag>(l, r);
  }
};

struct xform
  : proto::or_<
    proto::when<
      proto::terminal<term>,
    xform_callable(proto::_value, mpl::next<proto::_state>())>,
    proto::when<
      proto::plus<xform, xform>,
      xform_callable(proto::tag_of<proto::_expr>(),
xform(proto::_left, proto::_state), xform(proto::_right,
proto::_state))>
>
{};

int main()
{
  mpl::plus<mpl::int_<0>, mpl::int_<1> >();
  proto::display_expr(xform()(a+b/c, mpl::int_<0>()));
  return 0;
}

I pass in mpl::int_<0>() as the initial state and call mpl::next when
I match proto::terminal<term>. As the output would indicate, this is
not working. Every time I think I understand proto transforms,
something basic like this stumps me. I will be grateful for any hints
on how to accomplish this.

Thanks,
Manjunath


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net