
Here a smallish example. Ok for ARITY==2 and 6. Fails with ARITY==8 (I suspect anything above 6) Best regards, Maurizio #include <iostream> #define ARITY 2 #if ARITY==2 #define NUMBER number<_,_> #define NUMBER_TPL_DECL template<typename A, typename B> #define NUMBER_TPL_INST number<A,B> #define NUMBER_TPL_INST1 number<mpl::int_<0>,mpl::int_<0> > #elif ARITY==6 #define BOOST_PROTO_MAX_ARITY 6 #define NUMBER number<_,_,_,_,_,_> #define NUMBER_TPL_DECL template<typename A, typename B, typename C, typename D, typename E, typename F> #define NUMBER_TPL_INST number<A,B,C,D,E,F> #define NUMBER_TPL_INST1 number<mpl::int_<0>, mpl::int_<0>, mpl::int_<0>, mpl::int_<0>, mpl::int_<0>, mpl::int_<0> > #else #define BOOST_PROTO_MAX_ARITY 8 #define NUMBER number<_,_,_,_,_,_,_,_> #define NUMBER_TPL_DECL template<typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H> #define NUMBER_TPL_INST number<A,B,C,D,E,F,G,H> #define NUMBER_TPL_INST1 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> > #endif #include <boost/xpressive/proto/proto.hpp> #include <boost/xpressive/proto/context.hpp> #include <boost/xpressive/proto/extends.hpp> #include <boost/xpressive/proto/debug.hpp> #include <boost/xpressive/proto/transform/arg.hpp> #include <boost/xpressive/proto/transform/construct.hpp> //#include <boost/xpressive/proto/transform/fold_to_list.hpp> #include <boost/typeof/typeof.hpp> #include <boost/typeof/std/ostream.hpp> #include <boost/mpl/integral_c.hpp> #include <boost/mpl/contains.hpp> #include <boost/mpl/vector.hpp> #include <boost/test/unit_test.hpp> namespace proto=boost::proto; namespace mpl=boost::mpl; struct my_domain : proto::domain<struct my_grammar> {}; 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> ())); } }; NUMBER_TPL_DECL struct number; NUMBER_TPL_DECL std::ostream& operator << (std::ostream& os, const NUMBER_TPL_INST o); NUMBER_TPL_DECL struct number { friend std::ostream& operator << <> (std::ostream& os, const NUMBER_TPL_INST o); unsigned int m_data; }; NUMBER_TPL_DECL std::ostream& operator << (std::ostream& os, const NUMBER_TPL_INST n) { os << "~U~" << n.m_data << "~"; return os; } using proto::_; 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; NUMBER_TPL_DECL unsigned int operator () (proto::tag::terminal, NUMBER_TPL_INST n) const { return n.m_data; } }; template<int N> struct my_int : my_expr<typename proto::terminal< NUMBER_TPL_INST1 >::type> { typedef NUMBER_TPL_INST1 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; } friend std::ostream& operator << (std::ostream& os, const my_int n) { os << "my_int<" << proto::arg(n).m_data << ">"; return os; } }; #include <boost/test/included/unit_test_framework.hpp> using namespace boost::unit_test; template<typename Expr> void test (const Expr& expr) { std::cout << "Expression:\n"; display_expr (expr); if (proto::matches<Expr, my_grammar>::value) std::cout << "matches my grammar\n\n"; else std::cout << "doesn't matches my grammar\n\n"; } void misc_test () { my_int<6> i4(-22); int i; unsigned int j; i4 = 5; i4 = 5*i4; i = i4/i4+4; j = i4/i4; display_expr (i4/i4+4); std::cout << "my_expr, -22/7 =" << i4 << "\n"; // std::cout << "my_expr, -22/7 =" << i4*i4 << "\n"; // ambiguous std::cout << "my_expr, -22/7 [assigned to int]=" << i << "\n"; std::cout << "my_expr, -22/7 [assigned to unsigned int]=" << j << "\n"; } test_suite* init_unit_test_suite (int, char**) { test_suite* test= BOOST_TEST_SUITE( "boost::proto sandbox" ); test->add (BOOST_TEST_CASE (&misc_test)); return test; } /// Local Variables: /// mode:c++ /// comment-column:80 /// fill-column:160 /// compilation-read-command:nil /// compile-command:"g++ -I. -ope1 pe1.cpp" /// End: