
Larry Evans <cppljevans@cox-internet.com> writes:
struct xmpl_context { explicit xmpl_context(unsigned& a_indent) : indent(a_indent) { }
template<typename Expr, long Arity = Expr::arity::value> struct eval {
typedef void result_type; result_type operator()(Expr &expr, xmpl_context &ctx) const { typedef proto::tagof<Expr>::type tag_type; const char*tag_name=std::typeid(tag_type).name() std::cout<<std::setw(indent) <<""<<tag_name<<".get_instance=" <<expr.get_instance()<<"\n"; indent+=2; for(long ichild=0; ichild<Arity; ++ichild) { proto::eval(proto::arg_c<Expr,ichild>(expr), *this); } indent-=2; } };
private: unsigned& indent;
};
I noticed in boost/xpressive/proto/fusion.hpp there's children templates, but they don't look like they'd help. How do I do what's implied by the above for loop?
It seems to me you're duplicating what display_expr does (in debug.hpp), but if the question is more general and you need to do something else you can look at proto::transform::fold (or fold_to_list if you need more persistence). calc3.cpp shows how to use fold from the ::apply side, struct CalculatorGrammar : proto::or_< // placeholders have a non-zero arity ... placeholder_arity< proto::terminal< arg<_> > > // Any other terminals have arity 0 ... , proto::trans::always< proto::terminal<_>, mpl::int_<0> > // For any non-terminals, find the arity of the children and // take the maximum. This is recursive. , proto::trans::fold< // This matches any non-terminal for which the children // are themselves calculator expressions. proto::nary_expr<_, proto::vararg< max_arity< CalculatorGrammar > > > > > {}; I've never used it myself, but I presume that if max_arity had a ::call member (which in the example hasn't) then it would be called at run-time when CalculatorGrammar::call(,,) is evaluated and the state would be the result of calling max_arity::call on the previous element in the list of arguments. Eric will surely correct any false information I might be inadvertently spreading... Regards, Maurizio