gmpxx on a diet
Marc Glisse
marc.glisse at inria.fr
Fri Mar 4 19:15:40 CET 2011
Hello,
this patch removes a few hundred lines of code from gmpxx.h without (I
believe) changing the behaviour at all. (at some point, I should try and
write a testsuite that counts the number of copies and calls to various
functions)
It is possible to remove even more code duplication, but then I might have
to undo it later to add some optimizations, so I stopped at a safe point.
Tested with g++-4.4, clang++-2.9 and sunCC-12.2.
--
Marc Glisse
-------------- next part --------------
*** gmp.8c3dd0608bb7/gmpxx.h 2011-03-04 18:56:08.634945561 +0100
--- /data/repos/gmp/gmpxx.h 2011-03-04 18:55:57.694908073 +0100
***************
*** 1448,1470 ****
typedef mpf_t value_type;
};
- template <class T, class U, class V>
- struct __gmp_resolve_temp
- {
- typedef __gmp_expr<T, T> temp_type;
- };
-
- template <class T>
- struct __gmp_resolve_temp<T, T, T>
- {
- typedef const __gmp_expr<T, T> & temp_type;
- };
-
-
// classes for evaluating unary and binary expressions
template <class T, class Op>
struct __gmp_unary_expr
{
const T &val;
--- 1448,1457 ----
***************
*** 2223,2232 ****
--- 2210,2235 ----
{
expr.eval(f, mpf_get_prec(f));
}
+ /**************** Utility for temporary objects ****************/
+
+ template <class T, class U> struct __gmpxx_coercion
+ {
+ __gmp_expr<T,T> ref;
+ __gmpxx_coercion(U const& x): ref(x) {}
+ __gmpxx_coercion(U const& x, mp_bitcnt_t prec): ref(x,prec) {}
+ };
+ template <class T> struct __gmpxx_coercion<T, __gmp_expr<T,T> >
+ {
+ __gmp_expr<T,T> const& ref; // don't waste a copy
+ __gmpxx_coercion(__gmp_expr<T,T> const& x): ref(x) {}
+ __gmpxx_coercion(__gmp_expr<T,T> const& x, mp_bitcnt_t prec): ref(x) {}
+ };
+
+
/**************** Specializations of __gmp_expr ****************/
/* The eval() method of __gmp_expr<T, U> evaluates the corresponding
expression and assigns the result to its argument, which is either an
mpz_t, mpq_t, or mpf_t as specified by the T argument.
Compound expressions are evaluated recursively (temporaries are created
***************
*** 2290,2617 ****
- one is mp*_class, one is __gmp_expr<T, U>
- one is __gmp_expr<T, U>, one is built-in
- both arguments are __gmp_expr<...> */
- // simple expressions
-
- template <class T, class Op>
- class __gmp_expr
- <T, __gmp_binary_expr<__gmp_expr<T, T>, __gmp_expr<T, T>, Op> >
- {
- private:
- typedef __gmp_expr<T, T> val1_type;
- typedef __gmp_expr<T, T> val2_type;
-
- __gmp_binary_expr<val1_type, val2_type, Op> expr;
- public:
- __gmp_expr(const val1_type &val1, const val2_type &val2)
- : expr(val1, val2) { }
- void eval(typename __gmp_resolve_expr<T>::ptr_type p,
- unsigned long int = 0) const
- { Op::eval(p, expr.val1.__get_mp(), expr.val2.__get_mp()); }
- const val1_type & get_val1() const { return expr.val1; }
- const val2_type & get_val2() const { return expr.val2; }
- unsigned long int get_prec() const
- {
- mp_bitcnt_t prec1 = expr.val1.get_prec(),
- prec2 = expr.val2.get_prec();
- return (prec1 > prec2) ? prec1 : prec2;
- }
- };
-
-
- // simple expressions, T is a built-in numerical type
-
- template <class T, class U, class Op>
- class __gmp_expr<T, __gmp_binary_expr<__gmp_expr<T, T>, U, Op> >
- {
- private:
- typedef __gmp_expr<T, T> val1_type;
- typedef U val2_type;
-
- __gmp_binary_expr<val1_type, val2_type, Op> expr;
- public:
- __gmp_expr(const val1_type &val1, const val2_type &val2)
- : expr(val1, val2) { }
- void eval(typename __gmp_resolve_expr<T>::ptr_type p,
- unsigned long int = 0) const
- { Op::eval(p, expr.val1.__get_mp(), expr.val2); }
- const val1_type & get_val1() const { return expr.val1; }
- const val2_type & get_val2() const { return expr.val2; }
- unsigned long int get_prec() const { return expr.val1.get_prec(); }
- };
-
- template <class T, class U, class Op>
- class __gmp_expr<T, __gmp_binary_expr<U, __gmp_expr<T, T>, Op> >
- {
- private:
- typedef U val1_type;
- typedef __gmp_expr<T, T> val2_type;
-
- __gmp_binary_expr<val1_type, val2_type, Op> expr;
- public:
- __gmp_expr(const val1_type &val1, const val2_type &val2)
- : expr(val1, val2) { }
- void eval(typename __gmp_resolve_expr<T>::ptr_type p,
- unsigned long int = 0) const
- { Op::eval(p, expr.val1, expr.val2.__get_mp()); }
- const val1_type & get_val1() const { return expr.val1; }
- const val2_type & get_val2() const { return expr.val2; }
- unsigned long int get_prec() const { return expr.val2.get_prec(); }
- };
-
-
- // compound expressions, one argument is a subexpression
-
- template <class T, class U, class V, class Op>
- class __gmp_expr
- <T, __gmp_binary_expr<__gmp_expr<T, T>, __gmp_expr<U, V>, Op> >
- {
- private:
- typedef __gmp_expr<T, T> val1_type;
- typedef __gmp_expr<U, V> val2_type;
-
- __gmp_binary_expr<val1_type, val2_type, Op> expr;
- public:
- __gmp_expr(const val1_type &val1, const val2_type &val2)
- : expr(val1, val2) { }
- void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
- {
- __gmp_expr<T, T> temp(expr.val2);
- Op::eval(p, expr.val1.__get_mp(), temp.__get_mp());
- }
- void eval(typename __gmp_resolve_expr<T>::ptr_type p,
- mp_bitcnt_t prec) const
- {
- __gmp_expr<T, T> temp(expr.val2, prec);
- Op::eval(p, expr.val1.__get_mp(), temp.__get_mp());
- }
- const val1_type & get_val1() const { return expr.val1; }
- const val2_type & get_val2() const { return expr.val2; }
- unsigned long int get_prec() const
- {
- mp_bitcnt_t prec1 = expr.val1.get_prec(),
- prec2 = expr.val2.get_prec();
- return (prec1 > prec2) ? prec1 : prec2;
- }
- };
-
- template <class T, class U, class V, class Op>
- class __gmp_expr
- <T, __gmp_binary_expr<__gmp_expr<U, V>, __gmp_expr<T, T>, Op> >
- {
- private:
- typedef __gmp_expr<U, V> val1_type;
- typedef __gmp_expr<T, T> val2_type;
-
- __gmp_binary_expr<val1_type, val2_type, Op> expr;
- public:
- __gmp_expr(const val1_type &val1, const val2_type &val2)
- : expr(val1, val2) { }
- void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
- {
- __gmp_expr<T, T> temp(expr.val1);
- Op::eval(p, temp.__get_mp(), expr.val2.__get_mp());
- }
- void eval(typename __gmp_resolve_expr<T>::ptr_type p,
- mp_bitcnt_t prec) const
- {
- __gmp_expr<T, T> temp(expr.val1, prec);
- Op::eval(p, temp.__get_mp(), expr.val2.__get_mp());
- }
- const val1_type & get_val1() const { return expr.val1; }
- const val2_type & get_val2() const { return expr.val2; }
- unsigned long int get_prec() const
- {
- mp_bitcnt_t prec1 = expr.val1.get_prec(),
- prec2 = expr.val2.get_prec();
- return (prec1 > prec2) ? prec1 : prec2;
- }
- };
-
- template <class T, class U, class Op>
- class __gmp_expr
- <T, __gmp_binary_expr<__gmp_expr<T, T>, __gmp_expr<T, U>, Op> >
- {
- private:
- typedef __gmp_expr<T, T> val1_type;
- typedef __gmp_expr<T, U> val2_type;
-
- __gmp_binary_expr<val1_type, val2_type, Op> expr;
- public:
- __gmp_expr(const val1_type &val1, const val2_type &val2)
- : expr(val1, val2) { }
- void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
- {
- __gmp_expr<T, T> temp(expr.val2);
- Op::eval(p, expr.val1.__get_mp(), temp.__get_mp());
- }
- void eval(typename __gmp_resolve_expr<T>::ptr_type p,
- mp_bitcnt_t prec) const
- {
- __gmp_expr<T, T> temp(expr.val2, prec);
- Op::eval(p, expr.val1.__get_mp(), temp.__get_mp());
- }
- const val1_type & get_val1() const { return expr.val1; }
- const val2_type & get_val2() const { return expr.val2; }
- unsigned long int get_prec() const
- {
- mp_bitcnt_t prec1 = expr.val1.get_prec(),
- prec2 = expr.val2.get_prec();
- return (prec1 > prec2) ? prec1 : prec2;
- }
- };
-
- template <class T, class U, class Op>
- class __gmp_expr
- <T, __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<T, T>, Op> >
- {
- private:
- typedef __gmp_expr<T, U> val1_type;
- typedef __gmp_expr<T, T> val2_type;
-
- __gmp_binary_expr<val1_type, val2_type, Op> expr;
- public:
- __gmp_expr(const val1_type &val1, const val2_type &val2)
- : expr(val1, val2) { }
- void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
- {
- __gmp_expr<T, T> temp(expr.val1);
- Op::eval(p, temp.__get_mp(), expr.val2.__get_mp());
- }
- void eval(typename __gmp_resolve_expr<T>::ptr_type p,
- mp_bitcnt_t prec) const
- {
- __gmp_expr<T, T> temp(expr.val1, prec);
- Op::eval(p, temp.__get_mp(), expr.val2.__get_mp());
- }
- const val1_type & get_val1() const { return expr.val1; }
- const val2_type & get_val2() const { return expr.val2; }
- unsigned long int get_prec() const
- {
- mp_bitcnt_t prec1 = expr.val1.get_prec(),
- prec2 = expr.val2.get_prec();
- return (prec1 > prec2) ? prec1 : prec2;
- }
- };
-
-
// one argument is a subexpression, one is a built-in
! template <class T, class U, class V, class Op>
! class __gmp_expr<T, __gmp_binary_expr<__gmp_expr<T, U>, V, Op> >
{
private:
! typedef __gmp_expr<T, U> val1_type;
! typedef V val2_type;
__gmp_binary_expr<val1_type, val2_type, Op> expr;
public:
__gmp_expr(const val1_type &val1, const val2_type &val2)
: expr(val1, val2) { }
void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
{
! __gmp_expr<T, T> temp(expr.val1);
! Op::eval(p, temp.__get_mp(), expr.val2);
}
void eval(typename __gmp_resolve_expr<T>::ptr_type p,
mp_bitcnt_t prec) const
{
! __gmp_expr<T, T> temp(expr.val1, prec);
! Op::eval(p, temp.__get_mp(), expr.val2);
}
const val1_type & get_val1() const { return expr.val1; }
const val2_type & get_val2() const { return expr.val2; }
unsigned long int get_prec() const { return expr.val1.get_prec(); }
};
! template <class T, class U, class V, class Op>
! class __gmp_expr<T, __gmp_binary_expr<U, __gmp_expr<T, V>, Op> >
{
private:
typedef U val1_type;
! typedef __gmp_expr<T, V> val2_type;
__gmp_binary_expr<val1_type, val2_type, Op> expr;
public:
__gmp_expr(const val1_type &val1, const val2_type &val2)
: expr(val1, val2) { }
void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
{
! __gmp_expr<T, T> temp(expr.val2);
! Op::eval(p, expr.val1, temp.__get_mp());
}
void eval(typename __gmp_resolve_expr<T>::ptr_type p,
mp_bitcnt_t prec) const
{
! __gmp_expr<T, T> temp(expr.val2, prec);
! Op::eval(p, expr.val1, temp.__get_mp());
}
const val1_type & get_val1() const { return expr.val1; }
const val2_type & get_val2() const { return expr.val2; }
unsigned long int get_prec() const { return expr.val2.get_prec(); }
};
// both arguments are subexpressions
! template <class T, class U, class V, class W, class Op>
! class __gmp_expr
! <T, __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<V, W>, Op> >
! {
! private:
! typedef __gmp_expr<T, U> val1_type;
! typedef __gmp_expr<V, W> val2_type;
!
! __gmp_binary_expr<val1_type, val2_type, Op> expr;
! public:
! __gmp_expr(const val1_type &val1, const val2_type &val2)
! : expr(val1, val2) { }
! void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
! {
! __gmp_expr<T, T> temp1(expr.val1), temp2(expr.val2);
! Op::eval(p, temp1.__get_mp(), temp2.__get_mp());
! }
! void eval(typename __gmp_resolve_expr<T>::ptr_type p,
! mp_bitcnt_t prec) const
! {
! __gmp_expr<T, T> temp1(expr.val1, prec), temp2(expr.val2, prec);
! Op::eval(p, temp1.__get_mp(), temp2.__get_mp());
! }
! const val1_type & get_val1() const { return expr.val1; }
! const val2_type & get_val2() const { return expr.val2; }
! unsigned long int get_prec() const
! {
! mp_bitcnt_t prec1 = expr.val1.get_prec(),
! prec2 = expr.val2.get_prec();
! return (prec1 > prec2) ? prec1 : prec2;
! }
! };
!
! template <class T, class U, class V, class W, class Op>
class __gmp_expr
! <T, __gmp_binary_expr<__gmp_expr<U, V>, __gmp_expr<T, W>, Op> >
{
private:
typedef __gmp_expr<U, V> val1_type;
! typedef __gmp_expr<T, W> val2_type;
__gmp_binary_expr<val1_type, val2_type, Op> expr;
public:
__gmp_expr(const val1_type &val1, const val2_type &val2)
: expr(val1, val2) { }
void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
{
! __gmp_expr<T, T> temp1(expr.val1), temp2(expr.val2);
! Op::eval(p, temp1.__get_mp(), temp2.__get_mp());
}
void eval(typename __gmp_resolve_expr<T>::ptr_type p,
mp_bitcnt_t prec) const
{
! __gmp_expr<T, T> temp1(expr.val1, prec), temp2(expr.val2, prec);
! Op::eval(p, temp1.__get_mp(), temp2.__get_mp());
}
const val1_type & get_val1() const { return expr.val1; }
const val2_type & get_val2() const { return expr.val2; }
unsigned long int get_prec() const
{
--- 2293,2385 ----
- one is mp*_class, one is __gmp_expr<T, U>
- one is __gmp_expr<T, U>, one is built-in
- both arguments are __gmp_expr<...> */
// one argument is a subexpression, one is a built-in
! template <class T, class U, class V, class W, class Op>
! class __gmp_expr<T, __gmp_binary_expr<__gmp_expr<U, V>, W, Op> >
{
private:
! typedef __gmp_expr<U, V> val1_type;
! typedef W val2_type;
__gmp_binary_expr<val1_type, val2_type, Op> expr;
public:
__gmp_expr(const val1_type &val1, const val2_type &val2)
: expr(val1, val2) { }
void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
{
! __gmpxx_coercion<T, val1_type> temp(expr.val1);
! Op::eval(p, temp.ref.__get_mp(), expr.val2);
}
void eval(typename __gmp_resolve_expr<T>::ptr_type p,
mp_bitcnt_t prec) const
{
! __gmpxx_coercion<T, val1_type> temp(expr.val1, prec);
! Op::eval(p, temp.ref.__get_mp(), expr.val2);
}
const val1_type & get_val1() const { return expr.val1; }
const val2_type & get_val2() const { return expr.val2; }
unsigned long int get_prec() const { return expr.val1.get_prec(); }
};
! template <class T, class U, class V, class W, class Op>
! class __gmp_expr<T, __gmp_binary_expr<U, __gmp_expr<V, W>, Op> >
{
private:
typedef U val1_type;
! typedef __gmp_expr<V, W> val2_type;
__gmp_binary_expr<val1_type, val2_type, Op> expr;
public:
__gmp_expr(const val1_type &val1, const val2_type &val2)
: expr(val1, val2) { }
void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
{
! __gmpxx_coercion<T, val2_type> temp(expr.val2);
! Op::eval(p, expr.val1, temp.ref.__get_mp());
}
void eval(typename __gmp_resolve_expr<T>::ptr_type p,
mp_bitcnt_t prec) const
{
! __gmpxx_coercion<T, val2_type> temp(expr.val2, prec);
! Op::eval(p, expr.val1, temp.ref.__get_mp());
}
const val1_type & get_val1() const { return expr.val1; }
const val2_type & get_val2() const { return expr.val2; }
unsigned long int get_prec() const { return expr.val2.get_prec(); }
};
// both arguments are subexpressions
! template <class T, class U, class V, class W, class X, class Op>
class __gmp_expr
! <T, __gmp_binary_expr<__gmp_expr<U, V>, __gmp_expr<W, X>, Op> >
{
private:
typedef __gmp_expr<U, V> val1_type;
! typedef __gmp_expr<W, X> val2_type;
__gmp_binary_expr<val1_type, val2_type, Op> expr;
public:
__gmp_expr(const val1_type &val1, const val2_type &val2)
: expr(val1, val2) { }
void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
{
! __gmpxx_coercion<T, val1_type> temp1(expr.val1);
! __gmpxx_coercion<T, val2_type> temp2(expr.val2);
! Op::eval(p, temp1.ref.__get_mp(), temp2.ref.__get_mp());
}
void eval(typename __gmp_resolve_expr<T>::ptr_type p,
mp_bitcnt_t prec) const
{
! __gmpxx_coercion<T, val1_type> temp1(expr.val1, prec);
! __gmpxx_coercion<T, val2_type> temp2(expr.val2, prec);
! Op::eval(p, temp1.ref.__get_mp(), temp2.ref.__get_mp());
}
const val1_type & get_val1() const { return expr.val1; }
const val2_type & get_val2() const { return expr.val2; }
unsigned long int get_prec() const
{
***************
*** 2619,2660 ****
prec2 = expr.val2.get_prec();
return (prec1 > prec2) ? prec1 : prec2;
}
};
- template <class T, class U, class V, class Op>
- class __gmp_expr
- <T, __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<T, V>, Op> >
- {
- private:
- typedef __gmp_expr<T, U> val1_type;
- typedef __gmp_expr<T, V> val2_type;
-
- __gmp_binary_expr<val1_type, val2_type, Op> expr;
- public:
- __gmp_expr(const val1_type &val1, const val2_type &val2)
- : expr(val1, val2) { }
- void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
- {
- __gmp_expr<T, T> temp1(expr.val1), temp2(expr.val2);
- Op::eval(p, temp1.__get_mp(), temp2.__get_mp());
- }
- void eval(typename __gmp_resolve_expr<T>::ptr_type p,
- mp_bitcnt_t prec) const
- {
- __gmp_expr<T, T> temp1(expr.val1, prec), temp2(expr.val2, prec);
- Op::eval(p, temp1.__get_mp(), temp2.__get_mp());
- }
- const val1_type & get_val1() const { return expr.val1; }
- const val2_type & get_val2() const { return expr.val2; }
- unsigned long int get_prec() const
- {
- mp_bitcnt_t prec1 = expr.val1.get_prec(),
- prec2 = expr.val2.get_prec();
- return (prec1 > prec2) ? prec1 : prec2;
- }
- };
/**************** Special cases ****************/
/* Some operations (i.e., add and subtract) with mixed mpz/mpq arguments
--- 2387,2396 ----
***************
*** 2662,2795 ****
Appropriate specializations of __gmp_expr are required. */
#define __GMPZQ_DEFINE_EXPR(eval_fun) \
\
- template <> \
- class __gmp_expr<mpq_t, __gmp_binary_expr<mpz_class, mpq_class, eval_fun> > \
- { \
- private: \
- typedef mpz_class val1_type; \
- typedef mpq_class val2_type; \
- \
- __gmp_binary_expr<val1_type, val2_type, eval_fun> expr; \
- public: \
- __gmp_expr(const val1_type &val1, const val2_type &val2) \
- : expr(val1, val2) { } \
- void eval(mpq_ptr q) const \
- { eval_fun::eval(q, expr.val1.get_mpz_t(), expr.val2.get_mpq_t()); } \
- const val1_type & get_val1() const { return expr.val1; } \
- const val2_type & get_val2() const { return expr.val2; } \
- unsigned long int get_prec() const { return mpf_get_default_prec(); } \
- }; \
- \
- template <> \
- class __gmp_expr<mpq_t, __gmp_binary_expr<mpq_class, mpz_class, eval_fun> > \
- { \
- private: \
- typedef mpq_class val1_type; \
- typedef mpz_class val2_type; \
- \
- __gmp_binary_expr<val1_type, val2_type, eval_fun> expr; \
- public: \
- __gmp_expr(const val1_type &val1, const val2_type &val2) \
- : expr(val1, val2) { } \
- void eval(mpq_ptr q) const \
- { eval_fun::eval(q, expr.val1.get_mpq_t(), expr.val2.get_mpz_t()); } \
- const val1_type & get_val1() const { return expr.val1; } \
- const val2_type & get_val2() const { return expr.val2; } \
- unsigned long int get_prec() const { return mpf_get_default_prec(); } \
- }; \
- \
- template <class T> \
- class __gmp_expr \
- <mpq_t, __gmp_binary_expr<mpz_class, __gmp_expr<mpq_t, T>, eval_fun> > \
- { \
- private: \
- typedef mpz_class val1_type; \
- typedef __gmp_expr<mpq_t, T> val2_type; \
- \
- __gmp_binary_expr<val1_type, val2_type, eval_fun> expr; \
- public: \
- __gmp_expr(const val1_type &val1, const val2_type &val2) \
- : expr(val1, val2) { } \
- void eval(mpq_ptr q) const \
- { \
- mpq_class temp(expr.val2); \
- eval_fun::eval(q, expr.val1.get_mpz_t(), temp.get_mpq_t()); \
- } \
- const val1_type & get_val1() const { return expr.val1; } \
- const val2_type & get_val2() const { return expr.val2; } \
- unsigned long int get_prec() const { return mpf_get_default_prec(); } \
- }; \
- \
- template <class T> \
- class __gmp_expr \
- <mpq_t, __gmp_binary_expr<mpq_class, __gmp_expr<mpz_t, T>, eval_fun> > \
- { \
- private: \
- typedef mpq_class val1_type; \
- typedef __gmp_expr<mpz_t, T> val2_type; \
- \
- __gmp_binary_expr<val1_type, val2_type, eval_fun> expr; \
- public: \
- __gmp_expr(const val1_type &val1, const val2_type &val2) \
- : expr(val1, val2) { } \
- void eval(mpq_ptr q) const \
- { \
- mpz_class temp(expr.val2); \
- eval_fun::eval(q, expr.val1.get_mpq_t(), temp.get_mpz_t()); \
- } \
- const val1_type & get_val1() const { return expr.val1; } \
- const val2_type & get_val2() const { return expr.val2; } \
- unsigned long int get_prec() const { return mpf_get_default_prec(); } \
- }; \
- \
- template <class T> \
- class __gmp_expr \
- <mpq_t, __gmp_binary_expr<__gmp_expr<mpz_t, T>, mpq_class, eval_fun> > \
- { \
- private: \
- typedef __gmp_expr<mpz_t, T> val1_type; \
- typedef mpq_class val2_type; \
- \
- __gmp_binary_expr<val1_type, val2_type, eval_fun> expr; \
- public: \
- __gmp_expr(const val1_type &val1, const val2_type &val2) \
- : expr(val1, val2) { } \
- void eval(mpq_ptr q) const \
- { \
- mpz_class temp(expr.val1); \
- eval_fun::eval(q, temp.get_mpz_t(), expr.val2.get_mpq_t()); \
- } \
- const val1_type & get_val1() const { return expr.val1; } \
- const val2_type & get_val2() const { return expr.val2; } \
- unsigned long int get_prec() const { return mpf_get_default_prec(); } \
- }; \
- \
- template <class T> \
- class __gmp_expr \
- <mpq_t, __gmp_binary_expr<__gmp_expr<mpq_t, T>, mpz_class, eval_fun> > \
- { \
- private: \
- typedef __gmp_expr<mpq_t, T> val1_type; \
- typedef mpz_class val2_type; \
- \
- __gmp_binary_expr<val1_type, val2_type, eval_fun> expr; \
- public: \
- __gmp_expr(const val1_type &val1, const val2_type &val2) \
- : expr(val1, val2) { } \
- void eval(mpq_ptr q) const \
- { \
- mpq_class temp(expr.val1); \
- eval_fun::eval(q, temp.get_mpq_t(), expr.val2.get_mpz_t()); \
- } \
- const val1_type & get_val1() const { return expr.val1; } \
- const val2_type & get_val2() const { return expr.val2; } \
- unsigned long int get_prec() const { return mpf_get_default_prec(); } \
- }; \
- \
template <class T, class U> \
class __gmp_expr<mpq_t, __gmp_binary_expr \
<__gmp_expr<mpz_t, T>, __gmp_expr<mpq_t, U>, eval_fun> > \
{ \
private: \
--- 2398,2407 ----
***************
*** 2800,2811 ****
public: \
__gmp_expr(const val1_type &val1, const val2_type &val2) \
: expr(val1, val2) { } \
void eval(mpq_ptr q) const \
{ \
! mpz_class temp1(expr.val1); \
! mpq_class temp2(expr.val2); \
eval_fun::eval(q, temp1.get_mpz_t(), temp2.get_mpq_t()); \
} \
const val1_type & get_val1() const { return expr.val1; } \
const val2_type & get_val2() const { return expr.val2; } \
unsigned long int get_prec() const { return mpf_get_default_prec(); } \
--- 2412,2423 ----
public: \
__gmp_expr(const val1_type &val1, const val2_type &val2) \
: expr(val1, val2) { } \
void eval(mpq_ptr q) const \
{ \
! mpz_class const& temp1(expr.val1); \
! mpq_class const& temp2(expr.val2); \
eval_fun::eval(q, temp1.get_mpz_t(), temp2.get_mpq_t()); \
} \
const val1_type & get_val1() const { return expr.val1; } \
const val2_type & get_val2() const { return expr.val2; } \
unsigned long int get_prec() const { return mpf_get_default_prec(); } \
***************
*** 2823,2834 ****
public: \
__gmp_expr(const val1_type &val1, const val2_type &val2) \
: expr(val1, val2) { } \
void eval(mpq_ptr q) const \
{ \
! mpq_class temp1(expr.val1); \
! mpz_class temp2(expr.val2); \
eval_fun::eval(q, temp1.get_mpq_t(), temp2.get_mpz_t()); \
} \
const val1_type & get_val1() const { return expr.val1; } \
const val2_type & get_val2() const { return expr.val2; } \
unsigned long int get_prec() const { return mpf_get_default_prec(); } \
--- 2435,2446 ----
public: \
__gmp_expr(const val1_type &val1, const val2_type &val2) \
: expr(val1, val2) { } \
void eval(mpq_ptr q) const \
{ \
! mpq_class const& temp1(expr.val1); \
! mpz_class const& temp2(expr.val2); \
eval_fun::eval(q, temp1.get_mpq_t(), temp2.get_mpz_t()); \
} \
const val1_type & get_val1() const { return expr.val1; } \
const val2_type & get_val2() const { return expr.val2; } \
unsigned long int get_prec() const { return mpf_get_default_prec(); } \
***************
*** 2871,2881 ****
#define __GMP_DEFINE_UNARY_TYPE_FUNCTION(type, fun, eval_fun) \
\
template <class T, class U> \
inline type fun(const __gmp_expr<T, U> &expr) \
{ \
! typename __gmp_resolve_temp<T, T, U>::temp_type temp(expr); \
return eval_fun::eval(temp.__get_mp()); \
}
// non-member binary operators and functions
--- 2483,2493 ----
#define __GMP_DEFINE_UNARY_TYPE_FUNCTION(type, fun, eval_fun) \
\
template <class T, class U> \
inline type fun(const __gmp_expr<T, U> &expr) \
{ \
! __gmp_expr<T, T> const& temp(expr); \
return eval_fun::eval(temp.__get_mp()); \
}
// non-member binary operators and functions
***************
*** 2959,2987 ****
template <class T, class U, class V, class W> \
inline type fun(const __gmp_expr<T, U> &expr1, \
const __gmp_expr<V, W> &expr2) \
{ \
typedef typename __gmp_resolve_expr<T, V>::value_type eval_type; \
! typename __gmp_resolve_temp<eval_type, T, U>::temp_type temp1(expr1); \
! typename __gmp_resolve_temp<eval_type, V, W>::temp_type temp2(expr2); \
return eval_fun::eval(temp1.__get_mp(), temp2.__get_mp()); \
}
#define __GMPNN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, \
type2, bigtype) \
\
template <class T, class U> \
inline type fun(const __gmp_expr<T, U> &expr, type2 t) \
{ \
! typename __gmp_resolve_temp<T, T, U>::temp_type temp(expr); \
return eval_fun::eval(temp.__get_mp(), static_cast<bigtype>(t)); \
} \
\
template <class T, class U> \
inline type fun(type2 t, const __gmp_expr<T, U> &expr) \
{ \
! typename __gmp_resolve_temp<T, T, U>::temp_type temp(expr); \
return eval_fun::eval(static_cast<bigtype>(t), temp.__get_mp()); \
}
#define __GMPNS_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, type2) \
__GMPNN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, \
--- 2571,2599 ----
template <class T, class U, class V, class W> \
inline type fun(const __gmp_expr<T, U> &expr1, \
const __gmp_expr<V, W> &expr2) \
{ \
typedef typename __gmp_resolve_expr<T, V>::value_type eval_type; \
! __gmp_expr<eval_type, eval_type> const& temp1(expr1); \
! __gmp_expr<eval_type, eval_type> const& temp2(expr2); \
return eval_fun::eval(temp1.__get_mp(), temp2.__get_mp()); \
}
#define __GMPNN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, \
type2, bigtype) \
\
template <class T, class U> \
inline type fun(const __gmp_expr<T, U> &expr, type2 t) \
{ \
! __gmp_expr<T, T> const& temp(expr); \
return eval_fun::eval(temp.__get_mp(), static_cast<bigtype>(t)); \
} \
\
template <class T, class U> \
inline type fun(type2 t, const __gmp_expr<T, U> &expr) \
{ \
! __gmp_expr<T, T> const& temp(expr); \
return eval_fun::eval(static_cast<bigtype>(t), temp.__get_mp()); \
}
#define __GMPNS_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, type2) \
__GMPNN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, \
More information about the gmp-discuss
mailing list