Boost logo

Boost Users :

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

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