/*
Copyright (C) 2013 Tom Bachmann
This file is part of FLINT.
FLINT is free software: you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License (LGPL) as published
by the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version. See .
*/
#ifndef CXX_TEST_MYINT_H
#define CXX_TEST_MYINT_H CXX_TEST_MYINT_H
#include
#include
#include "flintxx/expression.h"
namespace flint {
template
class my_expression
: public expression, Operation, Data>
{
public:
my_expression() {};
template
explicit my_expression(const T& t)
: expression,
Operation, Data>(t) {}
template
my_expression& operator=(const T& t)
{
this->set(t);
return *this;
}
protected:
explicit my_expression(const Data& d)
: expression,
Operation, Data>(d) {}
template
friend class flint::expression;
};
struct data
{
int payload;
bool* destroyed;
int extra;
data() : payload(-1), destroyed(0), extra(42) {}
~data()
{
if(destroyed)
*destroyed = true;
}
data(const data& d)
: payload(d.payload), destroyed(0), extra(1) {}
data(int i)
: payload(i), destroyed(0), extra(2) {}
data(char i)
: payload(i), destroyed(0), extra(3) {}
};
typedef my_expression myint;
template
class my_expression2
: public expression, Operation, Data>
{
public:
// cannot have a default constructor
typedef expression,
Operation, Data> base_t;
typedef typename base_t::evaluated_t evaluated_t;
template
explicit my_expression2(const T& t)
: base_t(t) {}
template
explicit my_expression2(T& t)
: base_t(t) {}
template
my_expression2& operator=(const T& t)
{
this->set(t);
return *this;
}
evaluated_t create_temporary() const
{
return evaluated_t(WORD(0));
}
protected:
explicit my_expression2(const Data& d)
: base_t(d) {}
template
friend class flint::expression;
};
struct longref_data;
struct longcref_data;
struct long_data;
typedef my_expression2 mylong;
typedef my_expression2 mylong_ref;
typedef my_expression2 mylong_cref;
namespace traits {
template<> struct can_evaluate_into : mp::true_ { };
}
struct long_data
{
slong payload;
// no default constructor
long_data(slong d) : payload(d) {}
long_data(const myint& m) : payload(m._data().payload) {}
long_data(const mylong_ref&);
long_data(const mylong_cref&);
};
struct longref_data
{
slong& payload;
longref_data(mylong& l) : payload(l._data().payload) {}
};
struct longcref_data
{
const slong& payload;
longcref_data(const mylong& l) : payload(l._data().payload) {}
longcref_data(mylong_ref lr) : payload(lr._data().payload) {}
};
inline long_data::long_data(const mylong_ref& mlr) : payload(mlr._data().payload) {}
inline long_data::long_data(const mylong_cref& mlr) : payload(mlr._data().payload) {}
namespace mylong_traits {
template struct is_source : mp::false_ { };
template struct is_target : mp::false_ { };
template<> struct is_source : mp::true_ { };
template<> struct is_source : mp::true_ { };
template<> struct is_source : mp::true_ { };
template<> struct is_target : mp::true_ { };
template<> struct is_target : mp::true_ { };
}
FLINT_DEFINE_FOURARY(fourary_test)
FLINT_DEFINE_FIVEARY(fiveary_test)
FLINT_DEFINE_SIXARY(sixary_test)
FLINT_DEFINE_SEVENARY(sevenary_test)
namespace rules {
FLINT_DEFINE_FOURARY_EXPR_COND4(fourary_test_op, myint,
traits::is_integer, traits::is_integer, traits::is_integer, traits::is_integer,
to._data().payload = e1 + e2 + e3 + e4)
FLINT_DEFINE_FIVEARY_EXPR_COND5(fiveary_test_op, myint,
traits::is_integer, traits::is_integer, traits::is_integer,
traits::is_integer, traits::is_integer,
to._data().payload = e1 + e2 + e3 + e4 + e5)
FLINT_DEFINE_SIXARY_EXPR_COND6(sixary_test_op, myint,
traits::is_integer, traits::is_integer, traits::is_integer,
traits::is_integer, traits::is_integer, traits::is_integer,
to._data().payload = e1 + e2 + e3 + e4 + e5 + e6)
FLINT_DEFINE_SEVENARY_EXPR_COND7(sevenary_test_op, myint,
traits::is_integer, traits::is_integer, traits::is_integer,
traits::is_integer, traits::is_integer, traits::is_integer,
traits::is_integer,
to._data().payload = e1 + e2 + e3 + e4 + e5 + e6 + e7)
template<>
struct print
{
static void doit(const myint& v, std::ostream& o)
{
o << v._data().payload;
}
};
template<>
struct assignment
{
static void doit(myint& to, const myint& from)
{
to._data().payload = from._data().payload;
to._data().extra = 4;
}
};
template<>
struct assignment
{
static void doit(myint& to, slong from)
{
to._data().payload = from;
to._data().extra = 5;
}
};
template<>
struct to_string
{
static std::string get(const myint& i, int base /* ignored */)
{
std::ostringstream oss;
oss << i;
return oss.str();
}
};
template<>
struct equals
{
static bool get(const myint& i1, const myint& i2)
{
return i1._data().payload == i2._data().payload;
}
};
template<>
struct equals
{
static bool get(const myint& i1, int i2)
{
return i1._data().payload == i2;
}
};
template<>
struct conversion
{
static int get(const myint& from)
{
return from._data().payload;
}
};
template<>
struct swap
{
static void doit(myint& e1, myint& e2)
{
int tmp;
tmp = e1._data().payload;
e1._data().payload = e2._data().payload;
e2._data().payload = tmp;
e1._data().extra = 1234;
e2._data().extra = 1234;
}
};
template<>
struct commutative_binary_expression
{
typedef myint return_t;
static void doit(myint& to, const myint& a1, const myint& a2)
{
to._data().payload = a1._data().payload + a2._data().payload;
}
};
template
struct commutative_binary_expression, operations::plus>::type,
T>
{
typedef myint return_t;
static void doit(myint& to, const myint& a1, T a2)
{
to._data().payload = a1._data().payload + a2;
}
};
template<>
struct commutative_binary_expression
{
typedef myint return_t;
static void doit(myint& to, const myint& a1, const myint& a2)
{
to._data().payload = a1._data().payload * a2._data().payload;
}
};
template<>
struct binary_expression
{
typedef myint return_t;
static void doit(myint& to, const myint& a1, const myint& a2)
{
to._data().payload = a1._data().payload - a2._data().payload;
}
};
template<>
struct binary_expression
{
typedef myint return_t;
static void doit(myint& to, const myint& a1, const myint& a2)
{
to._data().payload = a1._data().payload / a2._data().payload;
}
};
template<>
struct binary_expression
{
typedef myint return_t;
static void doit(myint& to, const myint& a1, const myint& a2)
{
to._data().payload = a1._data().payload % a2._data().payload;
}
};
template<>
struct binary_expression
{
typedef myint return_t;
static void doit(myint& to, const myint& a1, int a2)
{
if (a2 >= 0)
to._data().payload = a1._data().payload << a2;
else
to._data().payload = a1._data().payload >> (-a2);
}
};
template<>
struct unary_expression
{
typedef myint return_t;
static void doit(myint& to, const myint& from)
{
to._data().payload = - from._data().payload;
}
};
/////////////////////////////////////////////////////////////////////////////
// Minimal rules for mylong
/////////////////////////////////////////////////////////////////////////////
template
struct equals, mylong_traits::is_source > >::type>
{
static bool get(const T& i1, const U& i2)
{
return i1._data().payload == i2._data().payload;
}
};
template
struct equals >::type>
{
static bool get(const T& i1, slong i2)
{
return i1._data().payload == i2;
}
};
template
struct commutative_binary_expression,
mylong_traits::is_source >,
operations::plus>::type, U>
{
typedef mylong return_t;
template
static void doit(V& to, const T& a1, const U& a2)
{
to._data().payload = a1._data().payload + a2._data().payload;
}
};
template
struct commutative_binary_expression, myint>::type, operations::plus, U>
{
typedef mylong return_t;
template
static void doit(V& to, const myint& a1, const U& a2)
{
to._data().payload = a1._data().payload + a2._data().payload;
}
};
template
struct assignment, mylong_traits::is_source > >::type>
{
static void doit(T& to, const U& from)
{
to._data().payload = from._data().payload;
}
};
template
struct assignment >::type>
{
static void doit(T& to, slong from)
{
to._data().payload = from;
}
};
template
struct assignment >::type>
{
static void doit(T& to, const myint& from)
{
to._data().payload = from._data().payload;
}
};
FLINT_DEFINE_READ_COND(mylong_traits::is_target,
flint_fscanf(from, "%wd", &to._data().payload))
FLINT_DEFINE_PRINT_COND(mylong_traits::is_source,
flint_fprintf(to, "%wd", from._data().payload))
FLINT_DEFINE_PRINT_PRETTY_COND(mylong_traits::is_source,
flint_fprintf(to, "<%wd>", from._data().payload))
} // rules
} // flint
#endif