Boost logo

Boost :

From: Maurizio Vitale (mav_at_[hidden])
Date: 2007-05-03 14:37:20


Eric Niebler <eric_at_[hidden]> writes:

> Maurizio Vitale wrote:
>> Still not working here. I tried 3.4 and 4.1.2 on X86_64 and 4.0.1 (with Apple mods) on Mac OS X (32 bit Intel).
>> They all fail.
>> I've also synched up the entire boost in case something outside of proto changed.
>> I'll let you know if I discover something.
>
> Send me a complete .cpp that reproduces the problem. Note that I only
> have x86 here, so I can't test on X86_64 or OSX.

So between the two of us we have an healthy mix of machines. The reason I tried Mac OS is not much because I'm interested in
it for development, rather it happens to be the only 32 bit machine I have. There was oveload ambiguity between signed and unsigned int,
so size was probably not the reason, but still it was a cheap test.

Please find attached a small piece of code which has problems. It
is basically what I sent before , preprocessed for ARITY==8 and with a few
other things that didn't contribute to the error removed.

With GCC 4.1.2 on X86_64 (but it is the same everywhere I tried), I get the following:

-*- mode: compilation; default-directory: "~/dev/proto_pdl/" -*-
Compilation started at Thu May 3 14:28:41

g++ -I. -ope1 pe1.cpp
pe1.cpp: In function ‘int main(int, char**)’:
pe1.cpp:101: error: ambiguous overload for ‘operator*’ in ‘5 * i4’
pe1.cpp:101: note: candidates are: operator*(int, int) <built-in>
pe1.cpp:101: note: operator*(int, unsigned int) <built-in>
pe1.cpp:103: error: ambiguous overload for ‘operator/’ in ‘i4 / i4’
pe1.cpp:103: note: candidates are: operator/(int, int) <built-in>
pe1.cpp:103: note: operator/(int, unsigned int) <built-in>
pe1.cpp:103: note: operator/(unsigned int, int) <built-in>
pe1.cpp:103: note: operator/(unsigned int, unsigned int) <built-in>
pe1.cpp:104: error: ambiguous overload for ‘operator/’ in ‘i4 / i4’
pe1.cpp:104: note: candidates are: operator/(int, int) <built-in>
pe1.cpp:104: note: operator/(int, unsigned int) <built-in>
pe1.cpp:104: note: operator/(unsigned int, int) <built-in>
pe1.cpp:104: note: operator/(unsigned int, unsigned int) <built-in>

Compilation exited abnormally with code 1 at Thu May 3 14:28:42

If I either:
   - reduce the arguments to the template number<...> down to 6, or
   - declare my_domain as struct my_domain : proto::domain<> {}; [no grammar]
then everything is ok.

>From past experience this is an indication that expressions don't match the grammar and that,
further, the reason for this is number<_,_,_,_,_,_,_,_>.

Hope this helps. In the mean time I'll cut the number of arguments to number<...>. That's
good regardless.

Best regards,

        Maurizio

Here's the file:

#include <iostream>

#define BOOST_PROTO_MAX_ARITY 8
#define BOOST_MPL_LIMIT_METAFUNCTION_ARITY 8 // GCC bug workaround, needs to be at least BOOST_PROTO_MAX_ARITY

#include <boost/xpressive/proto/proto.hpp>
#include <boost/xpressive/proto/context.hpp>
#include <boost/xpressive/proto/extends.hpp>
#include <boost/xpressive/proto/transform/arg.hpp>
#include <boost/xpressive/proto/transform/construct.hpp>

namespace proto=boost::proto;
namespace mpl=boost::mpl;
using proto::_;

struct my_domain : proto::domain<struct my_grammar> {};
//struct my_domain : proto::domain<> {};

template<typename> struct my_context;

template <typename Expr>
struct my_expr : proto::extends<Expr, my_expr<Expr>, my_domain> {
  typedef proto::extends<Expr, my_expr<Expr>, my_domain> base_type;

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

  using base_type::operator =;

  operator int () const {
    return static_cast<int>(proto::eval(*this, my_context<Expr> ()));
  }

  operator unsigned int () const {
    return static_cast<unsigned int>(proto::eval(*this, my_context<Expr> ()));
  }
};

template<typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H>
struct number {
  unsigned int m_data;
};

struct my_grammar : proto::or_ <
  proto::terminal< number<_,_,_,_,_,_,_,_> > ,
  proto::terminal<int>,
  proto::terminal<unsigned int>,
  proto::unary_expr<proto::_, my_grammar> ,
  proto::binary_expr<proto::_, my_grammar, my_grammar>
>
{};

namespace boost { namespace proto {
  template<typename Expr>
  struct generate<my_domain, Expr> {
    typedef my_expr<Expr> type;
      
    static type make (Expr const& expr) {
      return type (expr);
    }
  };
} } // end namespace boost::proto

template<typename Expr>
struct my_context : proto::callable_context<const my_context<Expr> > {
  typedef unsigned int result_type;

  template<typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H>
  unsigned int operator () (proto::tag::terminal, number<A,B,C,D,E,F,G,H> n) const { return n.m_data; }
};

template<int N>
struct my_int : my_expr<typename proto::terminal< number<mpl::int_<0>,mpl::int_<0>, mpl::int_<0>, mpl::int_<0>, mpl::int_<0>, mpl::int_<0>, mpl::int_<0>, mpl::int_<0> > >::type>
{
  typedef number<mpl::int_<0>,mpl::int_<0>, mpl::int_<0>, mpl::int_<0>, mpl::int_<0>, mpl::int_<0>, mpl::int_<0>, mpl::int_<0> > number_type;
  typedef my_expr<typename proto::terminal<number_type>::type> expr_type;

  my_int () {}
  my_int (int i) : expr_type (expr_type::type::make (i)) {}

  template<typename Expr>
  my_int& operator = (const my_expr<Expr>& e) {
    proto::arg (*this).m_data = static_cast<int>(proto::eval(e, my_context<Expr> ()));
    return *this;
  }

  template<typename T>
  my_int& operator = (T value) {
    proto::arg (*this).m_data = value;
    return *this;
  }
};

int main (int,char**) {
  my_int<6> i4(-22);

  int i;
  unsigned int j;

  i4 = 5;
  i4 = 5*i4;

  i = i4/i4+4;
  j = i4/i4;
}


/// Local Variables:
/// mode:c++
/// comment-column:80
/// fill-column:160
/// compilation-read-command:nil
/// compile-command:"g++ -I. -ope1 pe1.cpp"
/// End:


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk