Boost logo

Boost Users :

Subject: [Boost-users] [proto] vararg expressions to string
From: Manjunath Kudlur (keveman_at_[hidden])
Date: 2010-02-17 21:12:28


I am trying understand the use of proto::fold to handle vararg
expressions. As an experiment, I am trying to convert expressions of
the form foo(a,b,c) to a string of the form "foo(a,b,c)". I currently
have the following code where I treat the vararg expression as a
fusion sequence and convert each parameter to a string using
appropriate grammar. In the operator() of _foo_tostr, I have a case
for each length of the vararg expression. Please let me know if there
are better ways of doing this.

#include <iostream>
#include <boost/proto/proto.hpp>
#include <boost/fusion/container/list/cons.hpp>
#include <boost/fusion/include/cons.hpp>
#include <boost/fusion/include/transform.hpp>
#include <sstream>
#include <string>

using namespace std;
namespace proto = boost::proto;
namespace fusion = boost::fusion;

unsigned ids;

struct var {
  unsigned id;
  var() {
    id = ++ids;
  }
};

struct foo {};

typedef proto::terminal<var>::type Var;
typedef proto::terminal<foo>::type Foo;

struct _var_tostr
  : proto::callable {
  typedef string result_type;

  result_type operator()(var const &v) const {
    stringstream sout;
    sout << "v" << v.id;
    return sout.str();
  }
};

struct var_tostr
  : proto::or_<
    proto::when<proto::terminal<var>, _var_tostr(proto::_value)>
> {};

struct _foo_tostr
  : proto::callable {

  typedef string result_type;

  template<typename T>
  result_type operator()(T const &e) const {
    stringstream sout;
    sout << "foo(";

    if(fusion::size(e) == 1) {
      sout << ")";
    }
    else if(fusion::size(e) == 2) {
      sout << var_tostr()(fusion::at_c<1>(e))
           << ")";
    }
    else if(fusion::size(e) == 3) {
      sout << var_tostr()(fusion::at_c<1>(e)) << ", "
           << var_tostr()(fusion::at_c<2>(e))
           << ")";
    }
    else if(fusion::size(e) == 4) {
      sout << var_tostr()(fusion::at_c<1>(e)) << ", "
           << var_tostr()(fusion::at_c<2>(e)) << ", "
           << var_tostr()(fusion::at_c<3>(e))
           << ")";
    }

    return sout.str();
  }
};

struct foo_tostr
  : proto::or_ <
  proto::when<proto::function<proto::terminal<foo>,
proto::vararg<proto::terminal<var> > >,
  _foo_tostr(proto::_expr)> > {};

int main()
{
  Var a, b, c;
  Foo f;

  cout << foo_tostr()(f(a,b,c)) << endl;
}


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