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