$include_dir="/home/hyper-archives/boost-users/include"; include("$include_dir/msg-header.inc") ?>
Subject: Re: [Boost-users] [Proto] Using mpl::count as proto::transform
From: Eric Niebler (eric_at_[hidden])
Date: 2009-01-03 19:45:39
Joel Falcou wrote:
> I have a grammar with 3 kind of terminal : A,B and C.
> I want to have a transform that returns a mpl::int_ which is equal to 
> the number of B terminal that appear
> in expression like :
> 
> A(B,B,C,B,C ..)
> 
> the grammar part for matching this is currently :
> 
> when< function< vargarg<my_grammar> >
>          , mpl::count< _, terminal<B> >()
>          >
First, you want to use mpl::count_if with proto::matches so that you get 
the fuzzy terminal matching. Second, it seems that although proto 
expressions are valid Fusion sequences, they are not valid mpl 
sequences. That's a bug and I'll fix it. The following works for me:
     #include <iostream>
     #include <boost/mpl/count_if.hpp>
     #include <boost/fusion/include/mpl.hpp>
     #include <boost/proto/proto.hpp>
     namespace boost { namespace mpl
     {
         template<typename Tag, typename Args, long Arity>
         struct sequence_tag< proto::expr<Tag, Args, Arity> >
         {
             typedef fusion::fusion_sequence_tag type;
         };
     }}
     namespace mpl = boost::mpl;
     namespace proto = boost::proto;
     namespace fusion = boost::fusion;
     using proto::_;
     struct A {};
     struct B {};
     struct C {};
     struct CountB
       : proto::when<
             proto::function< proto::vararg<_> >
           , mpl::count_if< _, proto::matches<mpl::_, proto::terminal<B> 
 > >()
         >
     {};
     proto::terminal<A>::type a = {{}};
     proto::terminal<B>::type b = {{}};
     proto::terminal<C>::type c = {{}};
     int main()
     {
         std::cout << CountB()( a(b,c,b,a) ) << std::endl;
     }
HTH,
-- Eric Niebler BoostPro Computing http://www.boostpro.com