Boost logo

Proto :

Subject: Re: [proto] Adding stuff in proto operator
From: Joel Falcou (joel.falcou_at_[hidden])
Date: 2010-12-29 05:40:27


Error found.

The problem was in the and_impl transform. It uses comma operator to
chain calls to each and_ alternatives.
However, when this is used in a grammar used as a Generator, it enters a
subtle infinite loop as each comma
want to build an expression with the newly generated expression.

I locally modified proto this way in boost/proto/matches.hpp :

template<BOOST_PP_ENUM_PARAMS(N, typename G), typename Expr, typename
State, typename Data>
struct _and_impl<proto::and_<BOOST_PP_ENUM_PARAMS(N, G)>, Expr, State, Data>
      : proto::transform_impl<Expr, State, Data>
{
   #define M0(Z, N,
DATA) \
   
typedef
\
       typename proto::when<proto::_, BOOST_PP_CAT(G,
N)> \
           ::template impl<Expr, State,
Data> \
   BOOST_PP_CAT(Gimpl,
N); \
   /**/
   BOOST_PP_REPEAT(N, M0, ~)

   typedef typename BOOST_PP_CAT(Gimpl, BOOST_PP_DEC(N))::result_type
result_type;

   result_type operator()(
       typename _and_impl::expr_param e
     , typename _and_impl::state_param s
     , typename _and_impl::data_param d
   ) const
   {
    // Fix: jfalcou - 12/29/2010
    // This allow and_ to be used in grammar used as generator
    // by not using comma which caused an infinite loop

   #define M1(Z,N,DATA) \
   BOOST_PP_CAT(Gimpl,N)()(e,s,d);\
   /**/

     // expands to G0()(e,s,d); G1()(e,s,d); ... G{N-1}()(e,s,d);
     BOOST_PP_REPEAT(BOOST_PP_DEC(N),M1,~)
     return BOOST_PP_CAT(Gimpl,BOOST_PP_DEC(N))()(e,s,d);
   }

   #undef M1
   #undef M0
};

instead of using comma, I just generate N-1 application of GimplN and
return the last Gimpl call.

Is this fix acceptable or am I doing something wrong all together ?
If yes, Eric, any objections that I merge this into trunk ?


Proto list run by eric at boostpro.com