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
#include
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
>,
// 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