
Eric Niebler <eric@boost-consulting.com> 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: