|
Boost : |
From: Maurizio Vitale (mav_at_[hidden])
Date: 2007-05-02 19:16:43
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:
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk