$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
From: Maurizio Vitale (mav_at_[hidden])
Date: 2007-06-01 16:34:11
Larry Evans <cppljevans_at_[hidden]> 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