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 mailing list
[email protected]
http://lists.boost.org/mailman/listinfo.cgi/proto

Reply via email to