[proto] vararg expressions to string
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; }
Sorry for the delay. I was away for a bit. On 2/18/2010 1:12 PM, Manjunath Kudlur wrote:
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.
More or less OK so far. 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.
<snip> There's room for improvement here. Like you, I found it simpler to treat the vararg as a Fusion sequence than trying to use proto::fold on the expression. But your code can be made simpler with fusion::fold. See below. #include <string> #include <sstream> #include <iostream> #include <boost/proto/proto.hpp> #include <boost/fusion/include/fold.hpp> using namespace std; namespace proto = boost::proto; namespace fusion = boost::fusion; using proto::_; unsigned ids; struct var { unsigned id; var() { id = ++ids; } }; struct foo {}; typedef proto::terminal<var>::type Var; typedef proto::terminal<foo>::type Foo; string _var_tostr(string const &str, Var const &v) { stringstream sout; if(!str.empty()) sout << str << ", "; sout << "v" << proto::value(v).id; return sout.str(); } struct _foo_tostr : proto::callable { typedef string result_type; template<typename T> result_type operator()(T const &e) const { return "foo(" + fusion::fold(e, string(), &_var_tostr) + ")"; } }; struct foo_tostr : proto::when< proto::function< proto::terminal<foo>, proto::vararg<proto::terminal<var> > >, // Pop the foo terminal off the front of the // current expression (which is a valid Fusion // sequence) and pass the result to _foo_tostr. _foo_tostr(proto::functional::pop_front(_)) > {}; int main() { Var a, b, c; Foo f; cout << foo_tostr()(f(a,b,c)) << endl; } HTH, -- Eric Niebler BoostPro Computing http://www.boostpro.com
participants (2)
-
Eric Niebler
-
Manjunath Kudlur