Boost logo

Boost Users :

Subject: Re: [Boost-users] [proto] vararg expressions to string
From: Eric Niebler (eric_at_[hidden])
Date: 2010-02-23 02:13:41


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

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