Hi all,
When writing a simple proto program to deal with fraction expressions (just an exercise to get accustomed with proto library) we run into a compiler error that we are not able to fix.

The aim of the exercise is to write a grammar to:
1) Remove all calls to a given function (named "Sim") in an expression: 'Sim(Sim(Sim(a)))' is transformed into 'a'. This is a simple variation of the "remove-unary-plus" as found in the manual, and it works fine; 2) Remove all consecutive calls to Sim but one, so expressions like 'Sim(Sim(Sim(a)))' will turn out be 'Sim(a)'. This does not work with gcc (4.3.2 and 4.3.4) and icc (11.1), but works fine with Visual Studio (2008 and 2010). Boost 1.44 and 1.43, Windows and Linux.

The error gcc gives is:

minimalproto.cc: In function ‘int main()’:

minimalproto.cc:73: error: no matching function for call to ‘eval(boost::proto::exprns_::expr<boost::proto::tag::function, boost::proto::argsns_::list2<const simexpr<boost::proto::exprns_::expr<boost::proto::tag::terminal, boost::proto::argsns_::term<simplifyfct>, 0l> >&, const frac_calculator<boost::proto::exprns_::expr<boost::proto::tag::terminal, boost::proto::argsns_::term<const frac&>, 0l> >&>, 2l>, frac_context&)’

....boost-1.43/include/boost/proto/eval.hpp:89: note: candidates are: typename boost::proto::result_of::eval<Expr, Context>::type boost::proto::eval(Expr&, Context&) [with Expr = boost::proto::exprns_::expr<boost::proto::tag::function, boost::proto::argsns_::list2<const simexpr<boost::proto::exprns_::expr<boost::proto::tag::terminal, boost::proto::argsns_::term<simplifyfct>, 0l> >&, const frac_calculator<boost::proto::exprns_::expr<boost::proto::tag::terminal, boost::proto::argsns_::term<const frac&>, 0l> >&>, 2l>, Context = frac_context]

....boost-1.43/include/boost/proto/eval.hpp:98: note: typename boost::proto::result_of::eval<Expr, Context>::type boost::proto::eval(Expr&, const Context&) [with Expr = boost::proto::exprns_::expr<boost::proto::tag::function, boost::proto::argsns_::list2<const simexpr<boost::proto::exprns_::expr<boost::proto::tag::terminal, boost::proto::argsns_::term<simplifyfct>, 0l> >&, const frac_calculator<boost::proto::exprns_::expr<boost::proto::tag::terminal, boost::proto::argsns_::term<const frac&>, 0l> >&>, 2l>, Context = frac_context]

Somebody knows what's going on?
Any insight will be highly appreciated.
Cheers,
Mauro.

#include <boost/proto/proto.hpp>
namespace proto = boost::proto;
namespace mpl = boost::mpl;

struct frac {};

struct simplifyfct
{
  typedef frac result_type;
  frac const & operator()(frac const & f) const { return f;}
};

template <typename Expr>
struct frac_calculator;

struct frac_domain
  : proto::domain<proto::generator<frac_calculator> >
{};

template <typename EXPR>
struct simexpr 
{
  BOOST_PROTO_BASIC_EXTENDS(EXPR, simexpr, frac_domain)
  BOOST_PROTO_EXTENDS_FUNCTION()
};

simexpr<proto::terminal<simplifyfct>::type> const  sim = {{}};

struct frac_context : proto::callable_context<frac_context> {};

template<typename Expr>
struct frac_calculator
  : proto::extends<Expr, frac_calculator<Expr>, frac_domain>
{
  typedef proto::extends<Expr, frac_calculator<Expr>, frac_domain> base_type;

  frac_calculator(Expr const &expr = Expr())
    : base_type(expr)
  {}
};

/* The following grammar works */
struct RemoveAllSim
  : proto::or_<
  proto::when<
    proto::function<proto::terminal<simplifyfct>, RemoveAllSim>
    , RemoveAllSim(proto::_right)
    >
  , proto::terminal<frac>
  >
{};

/* The following grammar does not work */
struct RemoveSim
  : proto::or_<
  proto::when<
    proto::function<proto::terminal<simplifyfct>, 
proto::function<proto::terminal<simplifyfct>, proto::_> >
    , RemoveSim(proto::_right)
    >
  , proto::function<proto::terminal<simplifyfct>, proto::_>
  , proto::terminal<proto::_>
  >
{};

int main () {
  frac a, b;
  frac_context C;

#define TESTEXPR (sim(sim(sim(sim(a)))))

  frac c = proto::eval(TESTEXPR, C);                // THIS WORKS!
  c = proto::eval( RemoveAllSim()( TESTEXPR ) , C); // THIS WORKS!
  c = proto::eval( RemoveSim()( TESTEXPR ) , C);    // THIS DOES NOT WORK!

  return 0;
}
_______________________________________________
proto mailing list
proto@lists.boost.org
http://lists.boost.org/mailman/listinfo.cgi/proto

Reply via email to