(root)/
gmp-6.3.0/
gmpxx.h
       1  /* gmpxx.h -- C++ class wrapper for GMP types.  -*- C++ -*-
       2  
       3  Copyright 2001-2003, 2006, 2008, 2011-2015, 2018 Free Software
       4  Foundation, Inc.
       5  
       6  This file is part of the GNU MP Library.
       7  
       8  The GNU MP Library is free software; you can redistribute it and/or modify
       9  it under the terms of either:
      10  
      11    * the GNU Lesser General Public License as published by the Free
      12      Software Foundation; either version 3 of the License, or (at your
      13      option) any later version.
      14  
      15  or
      16  
      17    * the GNU General Public License as published by the Free Software
      18      Foundation; either version 2 of the License, or (at your option) any
      19      later version.
      20  
      21  or both in parallel, as here.
      22  
      23  The GNU MP Library is distributed in the hope that it will be useful, but
      24  WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
      25  or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      26  for more details.
      27  
      28  You should have received copies of the GNU General Public License and the
      29  GNU Lesser General Public License along with the GNU MP Library.  If not,
      30  see https://www.gnu.org/licenses/.  */
      31  
      32  #ifndef __GMP_PLUSPLUS__
      33  #define __GMP_PLUSPLUS__
      34  
      35  #include <iosfwd>
      36  
      37  #include <cstring>  /* for strlen */
      38  #include <limits>  /* numeric_limits */
      39  #include <utility>
      40  #include <algorithm>  /* swap */
      41  #include <string>
      42  #include <stdexcept>
      43  #include <cfloat>
      44  #include <gmp.h>
      45  
      46  // wrapper for gcc's __builtin_constant_p
      47  // __builtin_constant_p has been in gcc since forever,
      48  // but g++-3.4 miscompiles it.
      49  #if __GMP_GNUC_PREREQ(4, 2)
      50  #define __GMPXX_CONSTANT(X) __builtin_constant_p(X)
      51  #else
      52  #define __GMPXX_CONSTANT(X) false
      53  #endif
      54  #define __GMPXX_CONSTANT_TRUE(X) (__GMPXX_CONSTANT(X) && (X))
      55  
      56  // Use C++11 features
      57  #ifndef __GMPXX_USE_CXX11
      58  #if __cplusplus >= 201103L
      59  #define __GMPXX_USE_CXX11 1
      60  #else
      61  #define __GMPXX_USE_CXX11 0
      62  #endif
      63  #endif
      64  
      65  #if __GMPXX_USE_CXX11
      66  #define __GMPXX_NOEXCEPT noexcept
      67  #include <type_traits> // for common_type
      68  #else
      69  #define __GMPXX_NOEXCEPT
      70  #endif
      71  
      72  // Max allocations for plain types when converted to GMP types
      73  #if GMP_NAIL_BITS != 0 && ! defined _LONG_LONG_LIMB
      74  #define __GMPZ_ULI_LIMBS 2
      75  #else
      76  #define __GMPZ_ULI_LIMBS 1
      77  #endif
      78  
      79  #define __GMPXX_BITS_TO_LIMBS(n)  (((n) + (GMP_NUMB_BITS - 1)) / GMP_NUMB_BITS)
      80  #define __GMPZ_DBL_LIMBS __GMPXX_BITS_TO_LIMBS(DBL_MAX_EXP)+1
      81  #define __GMPQ_NUM_DBL_LIMBS __GMPZ_DBL_LIMBS
      82  #define __GMPQ_DEN_DBL_LIMBS __GMPXX_BITS_TO_LIMBS(DBL_MANT_DIG+1-DBL_MIN_EXP)+1
      83  // The final +1s are a security margin. The current implementation of
      84  // mpq_set_d seems to need it for the denominator.
      85  
      86  inline void __mpz_set_ui_safe(mpz_ptr p, unsigned long l)
      87  {
      88    p->_mp_size = (l != 0);
      89    p->_mp_d[0] = l & GMP_NUMB_MASK;
      90  #if __GMPZ_ULI_LIMBS > 1
      91    l >>= GMP_NUMB_BITS;
      92    p->_mp_d[1] = l;
      93    p->_mp_size += (l != 0);
      94  #endif
      95  }
      96  
      97  inline void __mpz_set_si_safe(mpz_ptr p, long l)
      98  {
      99    if(l < 0)
     100    {
     101      __mpz_set_ui_safe(p, -static_cast<unsigned long>(l));
     102      mpz_neg(p, p);
     103    }
     104    else
     105      __mpz_set_ui_safe(p, l);
     106      // Note: we know the high bit of l is 0 so we could do slightly better
     107  }
     108  
     109  // Fake temporary variables
     110  #define __GMPXX_TMPZ_UI							\
     111    mpz_t temp;								\
     112    mp_limb_t limbs[__GMPZ_ULI_LIMBS];					\
     113    temp->_mp_d = limbs;							\
     114    __mpz_set_ui_safe (temp, l)
     115  #define __GMPXX_TMPZ_SI							\
     116    mpz_t temp;								\
     117    mp_limb_t limbs[__GMPZ_ULI_LIMBS];					\
     118    temp->_mp_d = limbs;							\
     119    __mpz_set_si_safe (temp, l)
     120  #define __GMPXX_TMPZ_D							\
     121    mpz_t temp;								\
     122    mp_limb_t limbs[__GMPZ_DBL_LIMBS];					\
     123    temp->_mp_d = limbs;							\
     124    temp->_mp_alloc = __GMPZ_DBL_LIMBS;					\
     125    mpz_set_d (temp, d)
     126  
     127  #define __GMPXX_TMPQ_UI							\
     128    mpq_t temp;								\
     129    mp_limb_t limbs[__GMPZ_ULI_LIMBS+1];					\
     130    mpq_numref(temp)->_mp_d = limbs;					\
     131    __mpz_set_ui_safe (mpq_numref(temp), l);				\
     132    mpq_denref(temp)->_mp_d = limbs + __GMPZ_ULI_LIMBS;			\
     133    mpq_denref(temp)->_mp_size = 1;					\
     134    mpq_denref(temp)->_mp_d[0] = 1
     135  #define __GMPXX_TMPQ_SI							\
     136    mpq_t temp;								\
     137    mp_limb_t limbs[__GMPZ_ULI_LIMBS+1];					\
     138    mpq_numref(temp)->_mp_d = limbs;					\
     139    __mpz_set_si_safe (mpq_numref(temp), l);				\
     140    mpq_denref(temp)->_mp_d = limbs + __GMPZ_ULI_LIMBS;			\
     141    mpq_denref(temp)->_mp_size = 1;					\
     142    mpq_denref(temp)->_mp_d[0] = 1
     143  #define __GMPXX_TMPQ_D							\
     144    mpq_t temp;								\
     145    mp_limb_t limbs[__GMPQ_NUM_DBL_LIMBS + __GMPQ_DEN_DBL_LIMBS];		\
     146    mpq_numref(temp)->_mp_d = limbs;					\
     147    mpq_numref(temp)->_mp_alloc = __GMPQ_NUM_DBL_LIMBS;			\
     148    mpq_denref(temp)->_mp_d = limbs + __GMPQ_NUM_DBL_LIMBS;		\
     149    mpq_denref(temp)->_mp_alloc = __GMPQ_DEN_DBL_LIMBS;			\
     150    mpq_set_d (temp, d)
     151  
     152  inline unsigned long __gmpxx_abs_ui (signed long l)
     153  {
     154    return l >= 0 ? static_cast<unsigned long>(l)
     155  	  : -static_cast<unsigned long>(l);
     156  }
     157  
     158  /**************** Function objects ****************/
     159  /* Any evaluation of a __gmp_expr ends up calling one of these functions
     160     all intermediate functions being inline, the evaluation should optimize
     161     to a direct call to the relevant function, thus yielding no overhead
     162     over the C interface. */
     163  
     164  struct __gmp_unary_plus
     165  {
     166    static void eval(mpz_ptr z, mpz_srcptr w) { mpz_set(z, w); }
     167    static void eval(mpq_ptr q, mpq_srcptr r) { mpq_set(q, r); }
     168    static void eval(mpf_ptr f, mpf_srcptr g) { mpf_set(f, g); }
     169  };
     170  
     171  struct __gmp_unary_minus
     172  {
     173    static void eval(mpz_ptr z, mpz_srcptr w) { mpz_neg(z, w); }
     174    static void eval(mpq_ptr q, mpq_srcptr r) { mpq_neg(q, r); }
     175    static void eval(mpf_ptr f, mpf_srcptr g) { mpf_neg(f, g); }
     176  };
     177  
     178  struct __gmp_unary_com
     179  {
     180    static void eval(mpz_ptr z, mpz_srcptr w) { mpz_com(z, w); }
     181  };
     182  
     183  struct __gmp_binary_plus
     184  {
     185    static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v)
     186    { mpz_add(z, w, v); }
     187  
     188    static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l)
     189    {
     190      // Ideally, those checks should happen earlier so that the tree
     191      // generated for a+0+b would just be sum(a,b).
     192      if (__GMPXX_CONSTANT(l) && l == 0)
     193      {
     194        if (z != w) mpz_set(z, w);
     195      }
     196      else
     197        mpz_add_ui(z, w, l);
     198    }
     199    static void eval(mpz_ptr z, unsigned long int l, mpz_srcptr w)
     200    { eval(z, w, l); }
     201    static void eval(mpz_ptr z, mpz_srcptr w, signed long int l)
     202    {
     203      if (l >= 0)
     204        eval(z, w, static_cast<unsigned long>(l));
     205      else
     206        mpz_sub_ui(z, w, -static_cast<unsigned long>(l));
     207    }
     208    static void eval(mpz_ptr z, signed long int l, mpz_srcptr w)
     209    { eval(z, w, l); }
     210    static void eval(mpz_ptr z, mpz_srcptr w, double d)
     211    {  __GMPXX_TMPZ_D;    mpz_add (z, w, temp); }
     212    static void eval(mpz_ptr z, double d, mpz_srcptr w)
     213    { eval(z, w, d); }
     214  
     215    static void eval(mpq_ptr q, mpq_srcptr r, mpq_srcptr s)
     216    { mpq_add(q, r, s); }
     217  
     218    static void eval(mpq_ptr q, mpq_srcptr r, unsigned long int l)
     219    {
     220      if (__GMPXX_CONSTANT(l) && l == 0)
     221      {
     222        if (q != r) mpq_set(q, r);
     223      }
     224      else if (__GMPXX_CONSTANT(l) && l == 1)
     225      {
     226        mpz_add (mpq_numref(q), mpq_numref(r), mpq_denref(r));
     227        if (q != r) mpz_set(mpq_denref(q), mpq_denref(r));
     228      }
     229      else
     230      {
     231        if (q == r)
     232          mpz_addmul_ui(mpq_numref(q), mpq_denref(q), l);
     233        else
     234        {
     235          mpz_mul_ui(mpq_numref(q), mpq_denref(r), l);
     236          mpz_add(mpq_numref(q), mpq_numref(q), mpq_numref(r));
     237          mpz_set(mpq_denref(q), mpq_denref(r));
     238        }
     239      }
     240    }
     241    static void eval(mpq_ptr q, unsigned long int l, mpq_srcptr r)
     242    { eval(q, r, l); }
     243    static inline void eval(mpq_ptr q, mpq_srcptr r, signed long int l);
     244    // defined after __gmp_binary_minus
     245    static void eval(mpq_ptr q, signed long int l, mpq_srcptr r)
     246    { eval(q, r, l); }
     247    static void eval(mpq_ptr q, mpq_srcptr r, double d)
     248    {  __GMPXX_TMPQ_D;    mpq_add (q, r, temp); }
     249    static void eval(mpq_ptr q, double d, mpq_srcptr r)
     250    { eval(q, r, d); }
     251  
     252    static void eval(mpq_ptr q, mpq_srcptr r, mpz_srcptr z)
     253    {
     254      if (q == r)
     255        mpz_addmul(mpq_numref(q), mpq_denref(q), z);
     256      else
     257      {
     258        mpz_mul(mpq_numref(q), mpq_denref(r), z);
     259        mpz_add(mpq_numref(q), mpq_numref(q), mpq_numref(r));
     260        mpz_set(mpq_denref(q), mpq_denref(r));
     261      }
     262    }
     263    static void eval(mpq_ptr q, mpz_srcptr z, mpq_srcptr r)
     264    { eval(q, r, z); }
     265  
     266    static void eval(mpf_ptr f, mpf_srcptr g, mpf_srcptr h)
     267    { mpf_add(f, g, h); }
     268  
     269    static void eval(mpf_ptr f, mpf_srcptr g, unsigned long int l)
     270    { mpf_add_ui(f, g, l); }
     271    static void eval(mpf_ptr f, unsigned long int l, mpf_srcptr g)
     272    { mpf_add_ui(f, g, l); }
     273    static void eval(mpf_ptr f, mpf_srcptr g, signed long int l)
     274    {
     275      if (l >= 0)
     276        mpf_add_ui(f, g, l);
     277      else
     278        mpf_sub_ui(f, g, -static_cast<unsigned long>(l));
     279    }
     280    static void eval(mpf_ptr f, signed long int l, mpf_srcptr g)
     281    { eval(f, g, l); }
     282    static void eval(mpf_ptr f, mpf_srcptr g, double d)
     283    {
     284      mpf_t temp;
     285      mpf_init2(temp, 8*sizeof(double));
     286      mpf_set_d(temp, d);
     287      mpf_add(f, g, temp);
     288      mpf_clear(temp);
     289    }
     290    static void eval(mpf_ptr f, double d, mpf_srcptr g)
     291    { eval(f, g, d); }
     292  };
     293  
     294  struct __gmp_binary_minus
     295  {
     296    static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v)
     297    { mpz_sub(z, w, v); }
     298  
     299    static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l)
     300    {
     301      if (__GMPXX_CONSTANT(l) && l == 0)
     302      {
     303        if (z != w) mpz_set(z, w);
     304      }
     305      else
     306        mpz_sub_ui(z, w, l);
     307    }
     308    static void eval(mpz_ptr z, unsigned long int l, mpz_srcptr w)
     309    {
     310      if (__GMPXX_CONSTANT(l) && l == 0)
     311      {
     312        mpz_neg(z, w);
     313      }
     314      else
     315        mpz_ui_sub(z, l, w);
     316    }
     317    static void eval(mpz_ptr z, mpz_srcptr w, signed long int l)
     318    {
     319      if (l >= 0)
     320        eval(z, w, static_cast<unsigned long>(l));
     321      else
     322        mpz_add_ui(z, w, -static_cast<unsigned long>(l));
     323    }
     324    static void eval(mpz_ptr z, signed long int l, mpz_srcptr w)
     325    {
     326      if (l >= 0)
     327        eval(z, static_cast<unsigned long>(l), w);
     328      else
     329        {
     330          mpz_add_ui(z, w, -static_cast<unsigned long>(l));
     331          mpz_neg(z, z);
     332        }
     333    }
     334    static void eval(mpz_ptr z, mpz_srcptr w, double d)
     335    {  __GMPXX_TMPZ_D;    mpz_sub (z, w, temp); }
     336    static void eval(mpz_ptr z, double d, mpz_srcptr w)
     337    {  __GMPXX_TMPZ_D;    mpz_sub (z, temp, w); }
     338  
     339    static void eval(mpq_ptr q, mpq_srcptr r, mpq_srcptr s)
     340    { mpq_sub(q, r, s); }
     341  
     342    static void eval(mpq_ptr q, mpq_srcptr r, unsigned long int l)
     343    {
     344      if (__GMPXX_CONSTANT(l) && l == 0)
     345      {
     346        if (q != r) mpq_set(q, r);
     347      }
     348      else if (__GMPXX_CONSTANT(l) && l == 1)
     349      {
     350        mpz_sub (mpq_numref(q), mpq_numref(r), mpq_denref(r));
     351        if (q != r) mpz_set(mpq_denref(q), mpq_denref(r));
     352      }
     353      else
     354      {
     355        if (q == r)
     356          mpz_submul_ui(mpq_numref(q), mpq_denref(q), l);
     357        else
     358        {
     359          mpz_mul_ui(mpq_numref(q), mpq_denref(r), l);
     360          mpz_sub(mpq_numref(q), mpq_numref(r), mpq_numref(q));
     361          mpz_set(mpq_denref(q), mpq_denref(r));
     362        }
     363      }
     364    }
     365    static void eval(mpq_ptr q, unsigned long int l, mpq_srcptr r)
     366    { eval(q, r, l); mpq_neg(q, q); }
     367    static void eval(mpq_ptr q, mpq_srcptr r, signed long int l)
     368    {
     369      if (l >= 0)
     370        eval(q, r, static_cast<unsigned long>(l));
     371      else
     372        __gmp_binary_plus::eval(q, r, -static_cast<unsigned long>(l));
     373    }
     374    static void eval(mpq_ptr q, signed long int l, mpq_srcptr r)
     375    { eval(q, r, l); mpq_neg(q, q); }
     376    static void eval(mpq_ptr q, mpq_srcptr r, double d)
     377    {  __GMPXX_TMPQ_D;    mpq_sub (q, r, temp); }
     378    static void eval(mpq_ptr q, double d, mpq_srcptr r)
     379    {  __GMPXX_TMPQ_D;    mpq_sub (q, temp, r); }
     380  
     381    static void eval(mpq_ptr q, mpq_srcptr r, mpz_srcptr z)
     382    {
     383      if (q == r)
     384        mpz_submul(mpq_numref(q), mpq_denref(q), z);
     385      else
     386      {
     387        mpz_mul(mpq_numref(q), mpq_denref(r), z);
     388        mpz_sub(mpq_numref(q), mpq_numref(r), mpq_numref(q));
     389        mpz_set(mpq_denref(q), mpq_denref(r));
     390      }
     391    }
     392    static void eval(mpq_ptr q, mpz_srcptr z, mpq_srcptr r)
     393    { eval(q, r, z); mpq_neg(q, q); }
     394  
     395    static void eval(mpf_ptr f, mpf_srcptr g, mpf_srcptr h)
     396    { mpf_sub(f, g, h); }
     397  
     398    static void eval(mpf_ptr f, mpf_srcptr g, unsigned long int l)
     399    { mpf_sub_ui(f, g, l); }
     400    static void eval(mpf_ptr f, unsigned long int l, mpf_srcptr g)
     401    { mpf_ui_sub(f, l, g); }
     402    static void eval(mpf_ptr f, mpf_srcptr g, signed long int l)
     403    {
     404      if (l >= 0)
     405        mpf_sub_ui(f, g, l);
     406      else
     407        mpf_add_ui(f, g, -static_cast<unsigned long>(l));
     408    }
     409    static void eval(mpf_ptr f, signed long int l, mpf_srcptr g)
     410    {
     411      if (l >= 0)
     412        mpf_sub_ui(f, g, l);
     413      else
     414        mpf_add_ui(f, g, -static_cast<unsigned long>(l));
     415      mpf_neg(f, f);
     416    }
     417    static void eval(mpf_ptr f, mpf_srcptr g, double d)
     418    {
     419      mpf_t temp;
     420      mpf_init2(temp, 8*sizeof(double));
     421      mpf_set_d(temp, d);
     422      mpf_sub(f, g, temp);
     423      mpf_clear(temp);
     424    }
     425    static void eval(mpf_ptr f, double d, mpf_srcptr g)
     426    {
     427      mpf_t temp;
     428      mpf_init2(temp, 8*sizeof(double));
     429      mpf_set_d(temp, d);
     430      mpf_sub(f, temp, g);
     431      mpf_clear(temp);
     432    }
     433  };
     434  
     435  // defined here so it can reference __gmp_binary_minus
     436  inline void
     437  __gmp_binary_plus::eval(mpq_ptr q, mpq_srcptr r, signed long int l)
     438  {
     439    if (l >= 0)
     440      eval(q, r, static_cast<unsigned long>(l));
     441    else
     442      __gmp_binary_minus::eval(q, r, -static_cast<unsigned long>(l));
     443  }
     444  
     445  struct __gmp_binary_lshift
     446  {
     447    static void eval(mpz_ptr z, mpz_srcptr w, mp_bitcnt_t l)
     448    {
     449      if (__GMPXX_CONSTANT(l) && (l == 0))
     450      {
     451        if (z != w) mpz_set(z, w);
     452      }
     453      else
     454        mpz_mul_2exp(z, w, l);
     455    }
     456    static void eval(mpq_ptr q, mpq_srcptr r, mp_bitcnt_t l)
     457    {
     458      if (__GMPXX_CONSTANT(l) && (l == 0))
     459      {
     460        if (q != r) mpq_set(q, r);
     461      }
     462      else
     463        mpq_mul_2exp(q, r, l);
     464    }
     465    static void eval(mpf_ptr f, mpf_srcptr g, mp_bitcnt_t l)
     466    { mpf_mul_2exp(f, g, l); }
     467  };
     468  
     469  struct __gmp_binary_rshift
     470  {
     471    static void eval(mpz_ptr z, mpz_srcptr w, mp_bitcnt_t l)
     472    {
     473      if (__GMPXX_CONSTANT(l) && (l == 0))
     474      {
     475        if (z != w) mpz_set(z, w);
     476      }
     477      else
     478        mpz_fdiv_q_2exp(z, w, l);
     479    }
     480    static void eval(mpq_ptr q, mpq_srcptr r, mp_bitcnt_t l)
     481    {
     482      if (__GMPXX_CONSTANT(l) && (l == 0))
     483      {
     484        if (q != r) mpq_set(q, r);
     485      }
     486      else
     487        mpq_div_2exp(q, r, l);
     488    }
     489    static void eval(mpf_ptr f, mpf_srcptr g, mp_bitcnt_t l)
     490    { mpf_div_2exp(f, g, l); }
     491  };
     492  
     493  struct __gmp_binary_multiplies
     494  {
     495    static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v)
     496    { mpz_mul(z, w, v); }
     497  
     498    static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l)
     499    {
     500  // gcc-3.3 doesn't have __builtin_ctzl. Don't bother optimizing for old gcc.
     501  #if __GMP_GNUC_PREREQ(3, 4)
     502      if (__GMPXX_CONSTANT(l) && (l & (l-1)) == 0)
     503      {
     504        if (l == 0)
     505        {
     506          z->_mp_size = 0;
     507        }
     508        else
     509        {
     510          __gmp_binary_lshift::eval(z, w, __builtin_ctzl(l));
     511        }
     512      }
     513      else
     514  #endif
     515        mpz_mul_ui(z, w, l);
     516    }
     517    static void eval(mpz_ptr z, unsigned long int l, mpz_srcptr w)
     518    { eval(z, w, l); }
     519    static void eval(mpz_ptr z, mpz_srcptr w, signed long int l)
     520    {
     521      if (__GMPXX_CONSTANT_TRUE(l >= 0))
     522        eval(z, w, static_cast<unsigned long>(l));
     523      else if (__GMPXX_CONSTANT_TRUE(l <= 0))
     524        {
     525          eval(z, w, -static_cast<unsigned long>(l));
     526  	mpz_neg(z, z);
     527        }
     528      else
     529        mpz_mul_si (z, w, l);
     530    }
     531    static void eval(mpz_ptr z, signed long int l, mpz_srcptr w)
     532    { eval(z, w, l); }
     533    static void eval(mpz_ptr z, mpz_srcptr w, double d)
     534    {  __GMPXX_TMPZ_D;    mpz_mul (z, w, temp); }
     535    static void eval(mpz_ptr z, double d, mpz_srcptr w)
     536    { eval(z, w, d); }
     537  
     538    static void eval(mpq_ptr q, mpq_srcptr r, mpq_srcptr s)
     539    { mpq_mul(q, r, s); }
     540  
     541    static void eval(mpq_ptr q, mpq_srcptr r, unsigned long int l)
     542    {
     543  #if __GMP_GNUC_PREREQ(3, 4)
     544      if (__GMPXX_CONSTANT(l) && (l & (l-1)) == 0)
     545      {
     546        if (l == 0)
     547        {
     548  	mpq_set_ui(q, 0, 1);
     549        }
     550        else
     551        {
     552          __gmp_binary_lshift::eval(q, r, __builtin_ctzl(l));
     553        }
     554      }
     555      else
     556  #endif
     557      {
     558        __GMPXX_TMPQ_UI;
     559        mpq_mul (q, r, temp);
     560      }
     561    }
     562    static void eval(mpq_ptr q, unsigned long int l, mpq_srcptr r)
     563    { eval(q, r, l); }
     564    static void eval(mpq_ptr q, mpq_srcptr r, signed long int l)
     565    {
     566      if (__GMPXX_CONSTANT_TRUE(l >= 0))
     567        eval(q, r, static_cast<unsigned long>(l));
     568      else if (__GMPXX_CONSTANT_TRUE(l <= 0))
     569        {
     570          eval(q, r, -static_cast<unsigned long>(l));
     571  	mpq_neg(q, q);
     572        }
     573      else
     574        {
     575  	__GMPXX_TMPQ_SI;
     576  	mpq_mul (q, r, temp);
     577        }
     578    }
     579    static void eval(mpq_ptr q, signed long int l, mpq_srcptr r)
     580    { eval(q, r, l); }
     581    static void eval(mpq_ptr q, mpq_srcptr r, double d)
     582    {  __GMPXX_TMPQ_D;    mpq_mul (q, r, temp); }
     583    static void eval(mpq_ptr q, double d, mpq_srcptr r)
     584    { eval(q, r, d); }
     585  
     586    static void eval(mpf_ptr f, mpf_srcptr g, mpf_srcptr h)
     587    { mpf_mul(f, g, h); }
     588  
     589    static void eval(mpf_ptr f, mpf_srcptr g, unsigned long int l)
     590    { mpf_mul_ui(f, g, l); }
     591    static void eval(mpf_ptr f, unsigned long int l, mpf_srcptr g)
     592    { mpf_mul_ui(f, g, l); }
     593    static void eval(mpf_ptr f, mpf_srcptr g, signed long int l)
     594    {
     595      if (l >= 0)
     596        mpf_mul_ui(f, g, l);
     597      else
     598        {
     599  	mpf_mul_ui(f, g, -static_cast<unsigned long>(l));
     600  	mpf_neg(f, f);
     601        }
     602    }
     603    static void eval(mpf_ptr f, signed long int l, mpf_srcptr g)
     604    { eval(f, g, l); }
     605    static void eval(mpf_ptr f, mpf_srcptr g, double d)
     606    {
     607      mpf_t temp;
     608      mpf_init2(temp, 8*sizeof(double));
     609      mpf_set_d(temp, d);
     610      mpf_mul(f, g, temp);
     611      mpf_clear(temp);
     612    }
     613    static void eval(mpf_ptr f, double d, mpf_srcptr g)
     614    { eval(f, g, d); }
     615  };
     616  
     617  struct __gmp_binary_divides
     618  {
     619    static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v)
     620    { mpz_tdiv_q(z, w, v); }
     621  
     622    static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l)
     623    {
     624  #if __GMP_GNUC_PREREQ(3, 4)
     625      // Don't optimize division by 0...
     626      if (__GMPXX_CONSTANT(l) && (l & (l-1)) == 0 && l != 0)
     627      {
     628        if (l == 1)
     629        {
     630          if (z != w) mpz_set(z, w);
     631        }
     632        else
     633          mpz_tdiv_q_2exp(z, w, __builtin_ctzl(l));
     634          // warning: do not use rshift (fdiv)
     635      }
     636      else
     637  #endif
     638        mpz_tdiv_q_ui(z, w, l);
     639    }
     640    static void eval(mpz_ptr z, unsigned long int l, mpz_srcptr w)
     641    {
     642      if (mpz_sgn(w) >= 0)
     643        {
     644  	if (mpz_fits_ulong_p(w))
     645  	  mpz_set_ui(z, l / mpz_get_ui(w));
     646  	else
     647  	  mpz_set_ui(z, 0);
     648        }
     649      else
     650        {
     651  	mpz_neg(z, w);
     652  	if (mpz_fits_ulong_p(z))
     653  	  {
     654  	    mpz_set_ui(z, l / mpz_get_ui(z));
     655  	    mpz_neg(z, z);
     656  	  }
     657  	else
     658  	  mpz_set_ui(z, 0);
     659        }
     660    }
     661    static void eval(mpz_ptr z, mpz_srcptr w, signed long int l)
     662    {
     663      if (l >= 0)
     664        eval(z, w, static_cast<unsigned long>(l));
     665      else
     666        {
     667  	eval(z, w, -static_cast<unsigned long>(l));
     668  	mpz_neg(z, z);
     669        }
     670    }
     671    static void eval(mpz_ptr z, signed long int l, mpz_srcptr w)
     672    {
     673      if (mpz_fits_slong_p(w))
     674        mpz_set_si(z, l / mpz_get_si(w));
     675      else
     676        {
     677          /* if w is bigger than a long then the quotient must be zero, unless
     678             l==LONG_MIN and w==-LONG_MIN in which case the quotient is -1 */
     679          mpz_set_si (z, (mpz_cmpabs_ui (w, __gmpxx_abs_ui(l)) == 0 ? -1 : 0));
     680        }
     681    }
     682    static void eval(mpz_ptr z, mpz_srcptr w, double d)
     683    {  __GMPXX_TMPZ_D;    mpz_tdiv_q (z, w, temp); }
     684    static void eval(mpz_ptr z, double d, mpz_srcptr w)
     685    {  __GMPXX_TMPZ_D;    mpz_tdiv_q (z, temp, w); }
     686  
     687    static void eval(mpq_ptr q, mpq_srcptr r, mpq_srcptr s)
     688    { mpq_div(q, r, s); }
     689  
     690    static void eval(mpq_ptr q, mpq_srcptr r, unsigned long int l)
     691    {
     692  #if __GMP_GNUC_PREREQ(3, 4)
     693      if (__GMPXX_CONSTANT(l) && (l & (l-1)) == 0 && l != 0)
     694        __gmp_binary_rshift::eval(q, r, __builtin_ctzl(l));
     695      else
     696  #endif
     697      {
     698        __GMPXX_TMPQ_UI;
     699        mpq_div (q, r, temp);
     700      }
     701    }
     702    static void eval(mpq_ptr q, unsigned long int l, mpq_srcptr r)
     703    {
     704      if (__GMPXX_CONSTANT_TRUE(l == 0))
     705        mpq_set_ui(q, 0, 1);
     706      else if (__GMPXX_CONSTANT_TRUE(l == 1))
     707        mpq_inv(q, r);
     708      else
     709        {
     710  	__GMPXX_TMPQ_UI;
     711  	mpq_div (q, temp, r);
     712        }
     713    }
     714    static void eval(mpq_ptr q, mpq_srcptr r, signed long int l)
     715    {
     716      if (__GMPXX_CONSTANT_TRUE(l >= 0))
     717        eval(q, r, static_cast<unsigned long>(l));
     718      else if (__GMPXX_CONSTANT_TRUE(l <= 0))
     719        {
     720          eval(q, r, -static_cast<unsigned long>(l));
     721  	mpq_neg(q, q);
     722        }
     723      else
     724        {
     725  	__GMPXX_TMPQ_SI;
     726  	mpq_div (q, r, temp);
     727        }
     728    }
     729    static void eval(mpq_ptr q, signed long int l, mpq_srcptr r)
     730    {
     731      if (__GMPXX_CONSTANT_TRUE(l == 0))
     732        mpq_set_ui(q, 0, 1);
     733      else if (__GMPXX_CONSTANT_TRUE(l == 1))
     734        mpq_inv(q, r);
     735      else if (__GMPXX_CONSTANT_TRUE(l == -1))
     736        {
     737  	mpq_inv(q, r);
     738  	mpq_neg(q, q);
     739        }
     740      else
     741        {
     742  	__GMPXX_TMPQ_SI;
     743  	mpq_div (q, temp, r);
     744        }
     745    }
     746    static void eval(mpq_ptr q, mpq_srcptr r, double d)
     747    {  __GMPXX_TMPQ_D;    mpq_div (q, r, temp); }
     748    static void eval(mpq_ptr q, double d, mpq_srcptr r)
     749    {  __GMPXX_TMPQ_D;    mpq_div (q, temp, r); }
     750  
     751    static void eval(mpf_ptr f, mpf_srcptr g, mpf_srcptr h)
     752    { mpf_div(f, g, h); }
     753  
     754    static void eval(mpf_ptr f, mpf_srcptr g, unsigned long int l)
     755    { mpf_div_ui(f, g, l); }
     756    static void eval(mpf_ptr f, unsigned long int l, mpf_srcptr g)
     757    { mpf_ui_div(f, l, g); }
     758    static void eval(mpf_ptr f, mpf_srcptr g, signed long int l)
     759    {
     760      if (l >= 0)
     761        mpf_div_ui(f, g, l);
     762      else
     763        {
     764  	mpf_div_ui(f, g, -static_cast<unsigned long>(l));
     765  	mpf_neg(f, f);
     766        }
     767    }
     768    static void eval(mpf_ptr f, signed long int l, mpf_srcptr g)
     769    {
     770      if (l >= 0)
     771        mpf_ui_div(f, l, g);
     772      else
     773        {
     774  	mpf_ui_div(f, -static_cast<unsigned long>(l), g);
     775  	mpf_neg(f, f);
     776        }
     777    }
     778    static void eval(mpf_ptr f, mpf_srcptr g, double d)
     779    {
     780      mpf_t temp;
     781      mpf_init2(temp, 8*sizeof(double));
     782      mpf_set_d(temp, d);
     783      mpf_div(f, g, temp);
     784      mpf_clear(temp);
     785    }
     786    static void eval(mpf_ptr f, double d, mpf_srcptr g)
     787    {
     788      mpf_t temp;
     789      mpf_init2(temp, 8*sizeof(double));
     790      mpf_set_d(temp, d);
     791      mpf_div(f, temp, g);
     792      mpf_clear(temp);
     793    }
     794  };
     795  
     796  struct __gmp_binary_modulus
     797  {
     798    static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v)
     799    { mpz_tdiv_r(z, w, v); }
     800  
     801    static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l)
     802    { mpz_tdiv_r_ui(z, w, l); }
     803    static void eval(mpz_ptr z, unsigned long int l, mpz_srcptr w)
     804    {
     805      if (mpz_sgn(w) >= 0)
     806        {
     807  	if (mpz_fits_ulong_p(w))
     808  	  mpz_set_ui(z, l % mpz_get_ui(w));
     809  	else
     810  	  mpz_set_ui(z, l);
     811        }
     812      else
     813        {
     814  	mpz_neg(z, w);
     815  	if (mpz_fits_ulong_p(z))
     816  	  mpz_set_ui(z, l % mpz_get_ui(z));
     817  	else
     818  	  mpz_set_ui(z, l);
     819        }
     820    }
     821    static void eval(mpz_ptr z, mpz_srcptr w, signed long int l)
     822    {
     823      mpz_tdiv_r_ui (z, w, __gmpxx_abs_ui(l));
     824    }
     825    static void eval(mpz_ptr z, signed long int l, mpz_srcptr w)
     826    {
     827      if (mpz_fits_slong_p(w))
     828        mpz_set_si(z, l % mpz_get_si(w));
     829      else
     830        {
     831          /* if w is bigger than a long then the remainder is l unchanged,
     832             unless l==LONG_MIN and w==-LONG_MIN in which case it's 0 */
     833          mpz_set_si (z, mpz_cmpabs_ui (w, __gmpxx_abs_ui(l)) == 0 ? 0 : l);
     834        }
     835    }
     836    static void eval(mpz_ptr z, mpz_srcptr w, double d)
     837    {  __GMPXX_TMPZ_D;    mpz_tdiv_r (z, w, temp); }
     838    static void eval(mpz_ptr z, double d, mpz_srcptr w)
     839    {  __GMPXX_TMPZ_D;    mpz_tdiv_r (z, temp, w); }
     840  };
     841  
     842  struct __gmp_binary_and
     843  {
     844    static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v)
     845    { mpz_and(z, w, v); }
     846  
     847    static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l)
     848    {  __GMPXX_TMPZ_UI;   mpz_and (z, w, temp);  }
     849    static void eval(mpz_ptr z, unsigned long int l, mpz_srcptr w)
     850    { eval(z, w, l);  }
     851    static void eval(mpz_ptr z, mpz_srcptr w, signed long int l)
     852    {  __GMPXX_TMPZ_SI;   mpz_and (z, w, temp);  }
     853    static void eval(mpz_ptr z, signed long int l, mpz_srcptr w)
     854    { eval(z, w, l);  }
     855    static void eval(mpz_ptr z, mpz_srcptr w, double d)
     856    {  __GMPXX_TMPZ_D;    mpz_and (z, w, temp); }
     857    static void eval(mpz_ptr z, double d, mpz_srcptr w)
     858    { eval(z, w, d);  }
     859  };
     860  
     861  struct __gmp_binary_ior
     862  {
     863    static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v)
     864    { mpz_ior(z, w, v); }
     865    static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l)
     866    {  __GMPXX_TMPZ_UI;   mpz_ior (z, w, temp);  }
     867    static void eval(mpz_ptr z, unsigned long int l, mpz_srcptr w)
     868    { eval(z, w, l);  }
     869    static void eval(mpz_ptr z, mpz_srcptr w, signed long int l)
     870    {  __GMPXX_TMPZ_SI;   mpz_ior (z, w, temp);  }
     871    static void eval(mpz_ptr z, signed long int l, mpz_srcptr w)
     872    { eval(z, w, l);  }
     873    static void eval(mpz_ptr z, mpz_srcptr w, double d)
     874    {  __GMPXX_TMPZ_D;    mpz_ior (z, w, temp); }
     875    static void eval(mpz_ptr z, double d, mpz_srcptr w)
     876    { eval(z, w, d);  }
     877  };
     878  
     879  struct __gmp_binary_xor
     880  {
     881    static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v)
     882    { mpz_xor(z, w, v); }
     883    static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l)
     884    {  __GMPXX_TMPZ_UI;   mpz_xor (z, w, temp);  }
     885    static void eval(mpz_ptr z, unsigned long int l, mpz_srcptr w)
     886    { eval(z, w, l);  }
     887    static void eval(mpz_ptr z, mpz_srcptr w, signed long int l)
     888    {  __GMPXX_TMPZ_SI;   mpz_xor (z, w, temp);  }
     889    static void eval(mpz_ptr z, signed long int l, mpz_srcptr w)
     890    { eval(z, w, l);  }
     891    static void eval(mpz_ptr z, mpz_srcptr w, double d)
     892    {  __GMPXX_TMPZ_D;    mpz_xor (z, w, temp); }
     893    static void eval(mpz_ptr z, double d, mpz_srcptr w)
     894    { eval(z, w, d);  }
     895  };
     896  
     897  struct __gmp_cmp_function
     898  {
     899    static int eval(mpz_srcptr z, mpz_srcptr w) { return mpz_cmp(z, w); }
     900  
     901    static int eval(mpz_srcptr z, unsigned long int l)
     902    { return mpz_cmp_ui(z, l); }
     903    static int eval(unsigned long int l, mpz_srcptr z)
     904    { return -mpz_cmp_ui(z, l); }
     905    static int eval(mpz_srcptr z, signed long int l)
     906    { return mpz_cmp_si(z, l); }
     907    static int eval(signed long int l, mpz_srcptr z)
     908    { return -mpz_cmp_si(z, l); }
     909    static int eval(mpz_srcptr z, double d)
     910    { return mpz_cmp_d(z, d); }
     911    static int eval(double d, mpz_srcptr z)
     912    { return -mpz_cmp_d(z, d); }
     913  
     914    static int eval(mpq_srcptr q, mpq_srcptr r) { return mpq_cmp(q, r); }
     915  
     916    static int eval(mpq_srcptr q, unsigned long int l)
     917    { return mpq_cmp_ui(q, l, 1); }
     918    static int eval(unsigned long int l, mpq_srcptr q)
     919    { return -mpq_cmp_ui(q, l, 1); }
     920    static int eval(mpq_srcptr q, signed long int l)
     921    { return mpq_cmp_si(q, l, 1); }
     922    static int eval(signed long int l, mpq_srcptr q)
     923    { return -mpq_cmp_si(q, l, 1); }
     924    static int eval(mpq_srcptr q, double d)
     925    {  __GMPXX_TMPQ_D;    return mpq_cmp (q, temp); }
     926    static int eval(double d, mpq_srcptr q)
     927    {  __GMPXX_TMPQ_D;    return mpq_cmp (temp, q); }
     928    static int eval(mpq_srcptr q, mpz_srcptr z)
     929    { return mpq_cmp_z(q, z); }
     930    static int eval(mpz_srcptr z, mpq_srcptr q)
     931    { return -mpq_cmp_z(q, z); }
     932  
     933    static int eval(mpf_srcptr f, mpf_srcptr g) { return mpf_cmp(f, g); }
     934  
     935    static int eval(mpf_srcptr f, unsigned long int l)
     936    { return mpf_cmp_ui(f, l); }
     937    static int eval(unsigned long int l, mpf_srcptr f)
     938    { return -mpf_cmp_ui(f, l); }
     939    static int eval(mpf_srcptr f, signed long int l)
     940    { return mpf_cmp_si(f, l); }
     941    static int eval(signed long int l, mpf_srcptr f)
     942    { return -mpf_cmp_si(f, l); }
     943    static int eval(mpf_srcptr f, double d)
     944    { return mpf_cmp_d(f, d); }
     945    static int eval(double d, mpf_srcptr f)
     946    { return -mpf_cmp_d(f, d); }
     947    static int eval(mpf_srcptr f, mpz_srcptr z)
     948    { return mpf_cmp_z(f, z); }
     949    static int eval(mpz_srcptr z, mpf_srcptr f)
     950    { return -mpf_cmp_z(f, z); }
     951    static int eval(mpf_srcptr f, mpq_srcptr q)
     952    {
     953      mpf_t qf;
     954      mpf_init(qf); /* Should we use the precision of f?  */
     955      mpf_set_q(qf, q);
     956      int ret = eval(f, qf);
     957      mpf_clear(qf);
     958      return ret;
     959    }
     960    static int eval(mpq_srcptr q, mpf_srcptr f)
     961    { return -eval(f, q); }
     962  };
     963  
     964  struct __gmp_binary_equal
     965  {
     966    static bool eval(mpz_srcptr z, mpz_srcptr w) { return mpz_cmp(z, w) == 0; }
     967  
     968    static bool eval(mpz_srcptr z, unsigned long int l)
     969    { return mpz_cmp_ui(z, l) == 0; }
     970    static bool eval(unsigned long int l, mpz_srcptr z)
     971    { return eval(z, l); }
     972    static bool eval(mpz_srcptr z, signed long int l)
     973    { return mpz_cmp_si(z, l) == 0; }
     974    static bool eval(signed long int l, mpz_srcptr z)
     975    { return eval(z, l); }
     976    static bool eval(mpz_srcptr z, double d)
     977    { return mpz_cmp_d(z, d) == 0; }
     978    static bool eval(double d, mpz_srcptr z)
     979    { return eval(z, d); }
     980  
     981    static bool eval(mpq_srcptr q, mpq_srcptr r)
     982    { return mpq_equal(q, r) != 0; }
     983  
     984    static bool eval(mpq_srcptr q, unsigned long int l)
     985    { return ((__GMPXX_CONSTANT(l) && l == 0) ||
     986  	    mpz_cmp_ui(mpq_denref(q), 1) == 0) &&
     987        mpz_cmp_ui(mpq_numref(q), l) == 0; }
     988    static bool eval(unsigned long int l, mpq_srcptr q)
     989    { return eval(q, l); }
     990    static bool eval(mpq_srcptr q, signed long int l)
     991    { return ((__GMPXX_CONSTANT(l) && l == 0) ||
     992  	    mpz_cmp_ui(mpq_denref(q), 1) == 0) &&
     993        mpz_cmp_si(mpq_numref(q), l) == 0; }
     994    static bool eval(signed long int l, mpq_srcptr q)
     995    { return eval(q, l); }
     996    static bool eval(mpq_srcptr q, double d)
     997    {  __GMPXX_TMPQ_D;    return mpq_equal (q, temp) != 0; }
     998    static bool eval(double d, mpq_srcptr q)
     999    { return eval(q, d); }
    1000    static bool eval(mpq_srcptr q, mpz_srcptr z)
    1001    { return mpz_cmp_ui(mpq_denref(q), 1) == 0 && mpz_cmp(mpq_numref(q), z) == 0; }
    1002    static bool eval(mpz_srcptr z, mpq_srcptr q)
    1003    { return eval(q, z); }
    1004  
    1005    static bool eval(mpf_srcptr f, mpf_srcptr g) { return mpf_cmp(f, g) == 0; }
    1006  
    1007    static bool eval(mpf_srcptr f, unsigned long int l)
    1008    { return mpf_cmp_ui(f, l) == 0; }
    1009    static bool eval(unsigned long int l, mpf_srcptr f)
    1010    { return eval(f, l); }
    1011    static bool eval(mpf_srcptr f, signed long int l)
    1012    { return mpf_cmp_si(f, l) == 0; }
    1013    static bool eval(signed long int l, mpf_srcptr f)
    1014    { return eval(f, l); }
    1015    static bool eval(mpf_srcptr f, double d)
    1016    { return mpf_cmp_d(f, d) == 0; }
    1017    static bool eval(double d, mpf_srcptr f)
    1018    { return eval(f, d); }
    1019    static bool eval(mpf_srcptr f, mpz_srcptr z)
    1020    { return mpf_cmp_z(f, z) == 0; }
    1021    static bool eval(mpz_srcptr z, mpf_srcptr f)
    1022    { return eval(f, z); }
    1023    static bool eval(mpf_srcptr f, mpq_srcptr q)
    1024    { return __gmp_cmp_function::eval(f, q) == 0; }
    1025    static bool eval(mpq_srcptr q, mpf_srcptr f)
    1026    { return eval(f, q); }
    1027  };
    1028  
    1029  struct __gmp_binary_less
    1030  {
    1031    static bool eval(mpz_srcptr z, mpz_srcptr w) { return mpz_cmp(z, w) < 0; }
    1032  
    1033    static bool eval(mpz_srcptr z, unsigned long int l)
    1034    { return mpz_cmp_ui(z, l) < 0; }
    1035    static bool eval(unsigned long int l, mpz_srcptr z)
    1036    { return mpz_cmp_ui(z, l) > 0; }
    1037    static bool eval(mpz_srcptr z, signed long int l)
    1038    { return mpz_cmp_si(z, l) < 0; }
    1039    static bool eval(signed long int l, mpz_srcptr z)
    1040    { return mpz_cmp_si(z, l) > 0; }
    1041    static bool eval(mpz_srcptr z, double d)
    1042    { return mpz_cmp_d(z, d) < 0; }
    1043    static bool eval(double d, mpz_srcptr z)
    1044    { return mpz_cmp_d(z, d) > 0; }
    1045  
    1046    static bool eval(mpq_srcptr q, mpq_srcptr r) { return mpq_cmp(q, r) < 0; }
    1047  
    1048    static bool eval(mpq_srcptr q, unsigned long int l)
    1049    { return mpq_cmp_ui(q, l, 1) < 0; }
    1050    static bool eval(unsigned long int l, mpq_srcptr q)
    1051    { return mpq_cmp_ui(q, l, 1) > 0; }
    1052    static bool eval(mpq_srcptr q, signed long int l)
    1053    { return mpq_cmp_si(q, l, 1) < 0; }
    1054    static bool eval(signed long int l, mpq_srcptr q)
    1055    { return mpq_cmp_si(q, l, 1) > 0; }
    1056    static bool eval(mpq_srcptr q, double d)
    1057    {  __GMPXX_TMPQ_D;    return mpq_cmp (q, temp) < 0; }
    1058    static bool eval(double d, mpq_srcptr q)
    1059    {  __GMPXX_TMPQ_D;    return mpq_cmp (temp, q) < 0; }
    1060    static bool eval(mpq_srcptr q, mpz_srcptr z)
    1061    { return mpq_cmp_z(q, z) < 0; }
    1062    static bool eval(mpz_srcptr z, mpq_srcptr q)
    1063    { return mpq_cmp_z(q, z) > 0; }
    1064  
    1065    static bool eval(mpf_srcptr f, mpf_srcptr g) { return mpf_cmp(f, g) < 0; }
    1066  
    1067    static bool eval(mpf_srcptr f, unsigned long int l)
    1068    { return mpf_cmp_ui(f, l) < 0; }
    1069    static bool eval(unsigned long int l, mpf_srcptr f)
    1070    { return mpf_cmp_ui(f, l) > 0; }
    1071    static bool eval(mpf_srcptr f, signed long int l)
    1072    { return mpf_cmp_si(f, l) < 0; }
    1073    static bool eval(signed long int l, mpf_srcptr f)
    1074    { return mpf_cmp_si(f, l) > 0; }
    1075    static bool eval(mpf_srcptr f, double d)
    1076    { return mpf_cmp_d(f, d) < 0; }
    1077    static bool eval(double d, mpf_srcptr f)
    1078    { return mpf_cmp_d(f, d) > 0; }
    1079    static bool eval(mpf_srcptr f, mpz_srcptr z)
    1080    { return mpf_cmp_z(f, z) < 0; }
    1081    static bool eval(mpz_srcptr z, mpf_srcptr f)
    1082    { return mpf_cmp_z(f, z) > 0; }
    1083    static bool eval(mpf_srcptr f, mpq_srcptr q)
    1084    { return __gmp_cmp_function::eval(f, q) < 0; }
    1085    static bool eval(mpq_srcptr q, mpf_srcptr f)
    1086    { return __gmp_cmp_function::eval(q, f) < 0; }
    1087  };
    1088  
    1089  struct __gmp_binary_greater
    1090  {
    1091    template <class T, class U>
    1092    static inline bool eval(T t, U u) { return __gmp_binary_less::eval(u, t); }
    1093  };
    1094  
    1095  struct __gmp_unary_increment
    1096  {
    1097    static void eval(mpz_ptr z) { mpz_add_ui(z, z, 1); }
    1098    static void eval(mpq_ptr q)
    1099    { mpz_add(mpq_numref(q), mpq_numref(q), mpq_denref(q)); }
    1100    static void eval(mpf_ptr f) { mpf_add_ui(f, f, 1); }
    1101  };
    1102  
    1103  struct __gmp_unary_decrement
    1104  {
    1105    static void eval(mpz_ptr z) { mpz_sub_ui(z, z, 1); }
    1106    static void eval(mpq_ptr q)
    1107    { mpz_sub(mpq_numref(q), mpq_numref(q), mpq_denref(q)); }
    1108    static void eval(mpf_ptr f) { mpf_sub_ui(f, f, 1); }
    1109  };
    1110  
    1111  struct __gmp_abs_function
    1112  {
    1113    static void eval(mpz_ptr z, mpz_srcptr w) { mpz_abs(z, w); }
    1114    static void eval(mpq_ptr q, mpq_srcptr r) { mpq_abs(q, r); }
    1115    static void eval(mpf_ptr f, mpf_srcptr g) { mpf_abs(f, g); }
    1116  };
    1117  
    1118  struct __gmp_trunc_function
    1119  {
    1120    static void eval(mpf_ptr f, mpf_srcptr g) { mpf_trunc(f, g); }
    1121  };
    1122  
    1123  struct __gmp_floor_function
    1124  {
    1125    static void eval(mpf_ptr f, mpf_srcptr g) { mpf_floor(f, g); }
    1126  };
    1127  
    1128  struct __gmp_ceil_function
    1129  {
    1130    static void eval(mpf_ptr f, mpf_srcptr g) { mpf_ceil(f, g); }
    1131  };
    1132  
    1133  struct __gmp_sqrt_function
    1134  {
    1135    static void eval(mpz_ptr z, mpz_srcptr w) { mpz_sqrt(z, w); }
    1136    static void eval(mpf_ptr f, mpf_srcptr g) { mpf_sqrt(f, g); }
    1137  };
    1138  
    1139  struct __gmp_hypot_function
    1140  {
    1141    static void eval(mpf_ptr f, mpf_srcptr g, mpf_srcptr h)
    1142    {
    1143      mpf_t temp;
    1144      mpf_init2(temp, mpf_get_prec(f));
    1145      mpf_mul(temp, g, g);
    1146      mpf_mul(f, h, h);
    1147      mpf_add(f, f, temp);
    1148      mpf_sqrt(f, f);
    1149      mpf_clear(temp);
    1150    }
    1151  
    1152    static void eval(mpf_ptr f, mpf_srcptr g, unsigned long int l)
    1153    {
    1154      mpf_t temp;
    1155      mpf_init2(temp, mpf_get_prec(f));
    1156      mpf_mul(temp, g, g);
    1157      mpf_set_ui(f, l);
    1158      mpf_mul_ui(f, f, l);
    1159      mpf_add(f, f, temp);
    1160      mpf_clear(temp);
    1161      mpf_sqrt(f, f);
    1162    }
    1163    static void eval(mpf_ptr f, unsigned long int l, mpf_srcptr g)
    1164    { eval(f, g, l); }
    1165    static void eval(mpf_ptr f, mpf_srcptr g, signed long int l)
    1166    { eval(f, g, __gmpxx_abs_ui(l)); }
    1167    static void eval(mpf_ptr f, signed long int l, mpf_srcptr g)
    1168    { eval(f, g, l); }
    1169    static void eval(mpf_ptr f, mpf_srcptr g, double d)
    1170    {
    1171      mpf_t temp;
    1172      mpf_init2(temp, mpf_get_prec(f));
    1173      mpf_mul(temp, g, g);
    1174      mpf_set_d(f, d);
    1175      mpf_mul(f, f, f);
    1176      mpf_add(f, f, temp);
    1177      mpf_sqrt(f, f);
    1178      mpf_clear(temp);
    1179    }
    1180    static void eval(mpf_ptr f, double d, mpf_srcptr g)
    1181    { eval(f, g, d); }
    1182  };
    1183  
    1184  struct __gmp_sgn_function
    1185  {
    1186    static int eval(mpz_srcptr z) { return mpz_sgn(z); }
    1187    static int eval(mpq_srcptr q) { return mpq_sgn(q); }
    1188    static int eval(mpf_srcptr f) { return mpf_sgn(f); }
    1189  };
    1190  
    1191  struct __gmp_gcd_function
    1192  {
    1193    static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v)
    1194    { mpz_gcd(z, w, v); }
    1195    static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l)
    1196    { mpz_gcd_ui(z, w, l); }
    1197    static void eval(mpz_ptr z, unsigned long int l, mpz_srcptr w)
    1198    { eval(z, w, l); }
    1199    static void eval(mpz_ptr z, mpz_srcptr w, signed long int l)
    1200    { eval(z, w, __gmpxx_abs_ui(l)); }
    1201    static void eval(mpz_ptr z, signed long int l, mpz_srcptr w)
    1202    { eval(z, w, l); }
    1203    static void eval(mpz_ptr z, mpz_srcptr w, double d)
    1204    {  __GMPXX_TMPZ_D;    mpz_gcd (z, w, temp); }
    1205    static void eval(mpz_ptr z, double d, mpz_srcptr w)
    1206    { eval(z, w, d); }
    1207  };
    1208  
    1209  struct __gmp_lcm_function
    1210  {
    1211    static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v)
    1212    { mpz_lcm(z, w, v); }
    1213    static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l)
    1214    { mpz_lcm_ui(z, w, l); }
    1215    static void eval(mpz_ptr z, unsigned long int l, mpz_srcptr w)
    1216    { eval(z, w, l); }
    1217    static void eval(mpz_ptr z, mpz_srcptr w, signed long int l)
    1218    { eval(z, w, __gmpxx_abs_ui(l)); }
    1219    static void eval(mpz_ptr z, signed long int l, mpz_srcptr w)
    1220    { eval(z, w, l); }
    1221    static void eval(mpz_ptr z, mpz_srcptr w, double d)
    1222    {  __GMPXX_TMPZ_D;    mpz_lcm (z, w, temp); }
    1223    static void eval(mpz_ptr z, double d, mpz_srcptr w)
    1224    { eval(z, w, d); }
    1225  };
    1226  
    1227  struct __gmp_rand_function
    1228  {
    1229    static void eval(mpz_ptr z, gmp_randstate_t s, mp_bitcnt_t l)
    1230    { mpz_urandomb(z, s, l); }
    1231    static void eval(mpz_ptr z, gmp_randstate_t s, mpz_srcptr w)
    1232    { mpz_urandomm(z, s, w); }
    1233    static void eval(mpf_ptr f, gmp_randstate_t s, mp_bitcnt_t prec)
    1234    { mpf_urandomb(f, s, prec); }
    1235  };
    1236  
    1237  struct __gmp_fac_function
    1238  {
    1239    static void eval(mpz_ptr z, unsigned long l) { mpz_fac_ui(z, l); }
    1240    static void eval(mpz_ptr z, signed long l)
    1241    {
    1242      if (l < 0)
    1243        throw std::domain_error ("factorial(negative)");
    1244      eval(z, static_cast<unsigned long>(l));
    1245    }
    1246    static void eval(mpz_ptr z, mpz_srcptr w)
    1247    {
    1248      if (!mpz_fits_ulong_p(w))
    1249        {
    1250  	if (mpz_sgn(w) < 0)
    1251  	  throw std::domain_error ("factorial(negative)");
    1252  	else
    1253  	  throw std::bad_alloc(); // or std::overflow_error ("factorial")?
    1254        }
    1255      eval(z, mpz_get_ui(w));
    1256    }
    1257    static void eval(mpz_ptr z, double d)
    1258    {  __GMPXX_TMPZ_D;    eval (z, temp); }
    1259  };
    1260  
    1261  struct __gmp_primorial_function
    1262  {
    1263    static void eval(mpz_ptr z, unsigned long l) { mpz_primorial_ui(z, l); }
    1264    static void eval(mpz_ptr z, signed long l)
    1265    {
    1266      if (l < 0)
    1267        throw std::domain_error ("primorial(negative)");
    1268      eval(z, static_cast<unsigned long>(l));
    1269    }
    1270    static void eval(mpz_ptr z, mpz_srcptr w)
    1271    {
    1272      if (!mpz_fits_ulong_p(w))
    1273        {
    1274  	if (mpz_sgn(w) < 0)
    1275  	  throw std::domain_error ("primorial(negative)");
    1276  	else
    1277  	  throw std::bad_alloc(); // or std::overflow_error ("primorial")?
    1278        }
    1279      eval(z, mpz_get_ui(w));
    1280    }
    1281    static void eval(mpz_ptr z, double d)
    1282    {  __GMPXX_TMPZ_D;    eval (z, temp); }
    1283  };
    1284  
    1285  struct __gmp_fib_function
    1286  {
    1287    static void eval(mpz_ptr z, unsigned long l) { mpz_fib_ui(z, l); }
    1288    static void eval(mpz_ptr z, signed long l)
    1289    {
    1290      if (l < 0)
    1291        {
    1292  	eval(z, -static_cast<unsigned long>(l));
    1293  	if ((l & 1) == 0)
    1294  	  mpz_neg(z, z);
    1295        }
    1296      else
    1297        eval(z, static_cast<unsigned long>(l));
    1298    }
    1299    static void eval(mpz_ptr z, mpz_srcptr w)
    1300    {
    1301      if (!mpz_fits_slong_p(w))
    1302        throw std::bad_alloc(); // or std::overflow_error ("fibonacci")?
    1303      eval(z, mpz_get_si(w));
    1304    }
    1305    static void eval(mpz_ptr z, double d)
    1306    {  __GMPXX_TMPZ_D;    eval (z, temp); }
    1307  };
    1308  
    1309  
    1310  /**************** Auxiliary classes ****************/
    1311  
    1312  /* this is much the same as gmp_allocated_string in gmp-impl.h
    1313     since gmp-impl.h is not publicly available, I redefine it here
    1314     I use a different name to avoid possible clashes */
    1315  
    1316  extern "C" {
    1317    typedef void (*__gmp_freefunc_t) (void *, size_t);
    1318  }
    1319  struct __gmp_alloc_cstring
    1320  {
    1321    char *str;
    1322    __gmp_alloc_cstring(char *s) { str = s; }
    1323    ~__gmp_alloc_cstring()
    1324    {
    1325      __gmp_freefunc_t freefunc;
    1326      mp_get_memory_functions (NULL, NULL, &freefunc);
    1327      (*freefunc) (str, std::strlen(str)+1);
    1328    }
    1329  };
    1330  
    1331  
    1332  // general expression template class
    1333  template <class T, class U>
    1334  class __gmp_expr;
    1335  
    1336  
    1337  // templates for resolving expression types
    1338  template <class T>
    1339  struct __gmp_resolve_ref
    1340  {
    1341    typedef T ref_type;
    1342  };
    1343  
    1344  template <class T, class U>
    1345  struct __gmp_resolve_ref<__gmp_expr<T, U> >
    1346  {
    1347    typedef const __gmp_expr<T, U> & ref_type;
    1348  };
    1349  
    1350  
    1351  template <class T, class U = T>
    1352  struct __gmp_resolve_expr;
    1353  
    1354  template <>
    1355  struct __gmp_resolve_expr<mpz_t>
    1356  {
    1357    typedef mpz_t value_type;
    1358    typedef mpz_ptr ptr_type;
    1359    typedef mpz_srcptr srcptr_type;
    1360  };
    1361  
    1362  template <>
    1363  struct __gmp_resolve_expr<mpq_t>
    1364  {
    1365    typedef mpq_t value_type;
    1366    typedef mpq_ptr ptr_type;
    1367    typedef mpq_srcptr srcptr_type;
    1368  };
    1369  
    1370  template <>
    1371  struct __gmp_resolve_expr<mpf_t>
    1372  {
    1373    typedef mpf_t value_type;
    1374    typedef mpf_ptr ptr_type;
    1375    typedef mpf_srcptr srcptr_type;
    1376  };
    1377  
    1378  template <>
    1379  struct __gmp_resolve_expr<mpz_t, mpq_t>
    1380  {
    1381    typedef mpq_t value_type;
    1382  };
    1383  
    1384  template <>
    1385  struct __gmp_resolve_expr<mpq_t, mpz_t>
    1386  {
    1387    typedef mpq_t value_type;
    1388  };
    1389  
    1390  template <>
    1391  struct __gmp_resolve_expr<mpz_t, mpf_t>
    1392  {
    1393    typedef mpf_t value_type;
    1394  };
    1395  
    1396  template <>
    1397  struct __gmp_resolve_expr<mpf_t, mpz_t>
    1398  {
    1399    typedef mpf_t value_type;
    1400  };
    1401  
    1402  template <>
    1403  struct __gmp_resolve_expr<mpq_t, mpf_t>
    1404  {
    1405    typedef mpf_t value_type;
    1406  };
    1407  
    1408  template <>
    1409  struct __gmp_resolve_expr<mpf_t, mpq_t>
    1410  {
    1411    typedef mpf_t value_type;
    1412  };
    1413  
    1414  #if __GMPXX_USE_CXX11
    1415  namespace std {
    1416    template <class T, class U, class V, class W>
    1417    struct common_type <__gmp_expr<T, U>, __gmp_expr<V, W> >
    1418    {
    1419    private:
    1420      typedef typename __gmp_resolve_expr<T, V>::value_type X;
    1421    public:
    1422      typedef __gmp_expr<X, X> type;
    1423    };
    1424  
    1425    template <class T, class U>
    1426    struct common_type <__gmp_expr<T, U> >
    1427    {
    1428      typedef __gmp_expr<T, T> type;
    1429    };
    1430  
    1431  #define __GMPXX_DECLARE_COMMON_TYPE(typ)	\
    1432    template <class T, class U>			\
    1433    struct common_type <__gmp_expr<T, U>, typ >	\
    1434    {						\
    1435      typedef __gmp_expr<T, T> type;		\
    1436    };						\
    1437  						\
    1438    template <class T, class U>			\
    1439    struct common_type <typ, __gmp_expr<T, U> >	\
    1440    {						\
    1441      typedef __gmp_expr<T, T> type;		\
    1442    }
    1443  
    1444    __GMPXX_DECLARE_COMMON_TYPE(signed char);
    1445    __GMPXX_DECLARE_COMMON_TYPE(unsigned char);
    1446    __GMPXX_DECLARE_COMMON_TYPE(signed int);
    1447    __GMPXX_DECLARE_COMMON_TYPE(unsigned int);
    1448    __GMPXX_DECLARE_COMMON_TYPE(signed short int);
    1449    __GMPXX_DECLARE_COMMON_TYPE(unsigned short int);
    1450    __GMPXX_DECLARE_COMMON_TYPE(signed long int);
    1451    __GMPXX_DECLARE_COMMON_TYPE(unsigned long int);
    1452    __GMPXX_DECLARE_COMMON_TYPE(float);
    1453    __GMPXX_DECLARE_COMMON_TYPE(double);
    1454  #undef __GMPXX_DECLARE_COMMON_TYPE
    1455  }
    1456  #endif
    1457  
    1458  // classes for evaluating unary and binary expressions
    1459  template <class T, class Op>
    1460  struct __gmp_unary_expr
    1461  {
    1462    typename __gmp_resolve_ref<T>::ref_type val;
    1463  
    1464    __gmp_unary_expr(const T &v) : val(v) { }
    1465  private:
    1466    __gmp_unary_expr();
    1467  };
    1468  
    1469  template <class T, class U, class Op>
    1470  struct __gmp_binary_expr
    1471  {
    1472    typename __gmp_resolve_ref<T>::ref_type val1;
    1473    typename __gmp_resolve_ref<U>::ref_type val2;
    1474  
    1475    __gmp_binary_expr(const T &v1, const U &v2) : val1(v1), val2(v2) { }
    1476  private:
    1477    __gmp_binary_expr();
    1478  };
    1479  
    1480  
    1481  
    1482  /**************** Macros for in-class declarations ****************/
    1483  /* This is just repetitive code that is easier to maintain if it's written
    1484     only once */
    1485  
    1486  #define __GMPP_DECLARE_COMPOUND_OPERATOR(fun)                         \
    1487    template <class T, class U>                                         \
    1488    __gmp_expr<value_type, value_type> & fun(const __gmp_expr<T, U> &);
    1489  
    1490  #define __GMPN_DECLARE_COMPOUND_OPERATOR(fun) \
    1491    __gmp_expr & fun(signed char);              \
    1492    __gmp_expr & fun(unsigned char);            \
    1493    __gmp_expr & fun(signed int);               \
    1494    __gmp_expr & fun(unsigned int);             \
    1495    __gmp_expr & fun(signed short int);         \
    1496    __gmp_expr & fun(unsigned short int);       \
    1497    __gmp_expr & fun(signed long int);          \
    1498    __gmp_expr & fun(unsigned long int);        \
    1499    __gmp_expr & fun(float);                    \
    1500    __gmp_expr & fun(double);                   \
    1501    /* __gmp_expr & fun(long double); */
    1502  
    1503  #define __GMP_DECLARE_COMPOUND_OPERATOR(fun) \
    1504  __GMPP_DECLARE_COMPOUND_OPERATOR(fun)        \
    1505  __GMPN_DECLARE_COMPOUND_OPERATOR(fun)
    1506  
    1507  #define __GMP_DECLARE_COMPOUND_OPERATOR_UI(fun) \
    1508    __gmp_expr & fun(mp_bitcnt_t);
    1509  
    1510  #define __GMP_DECLARE_INCREMENT_OPERATOR(fun) \
    1511    inline __gmp_expr & fun();                  \
    1512    inline __gmp_expr fun(int);
    1513  
    1514  #define __GMPXX_DEFINE_ARITHMETIC_CONSTRUCTORS		\
    1515    __gmp_expr(signed char c) { init_si(c); }		\
    1516    __gmp_expr(unsigned char c) { init_ui(c); }		\
    1517    __gmp_expr(signed int i) { init_si(i); }		\
    1518    __gmp_expr(unsigned int i) { init_ui(i); }		\
    1519    __gmp_expr(signed short int s) { init_si(s); }	\
    1520    __gmp_expr(unsigned short int s) { init_ui(s); }	\
    1521    __gmp_expr(signed long int l) { init_si(l); }		\
    1522    __gmp_expr(unsigned long int l) { init_ui(l); }	\
    1523    __gmp_expr(float f) { init_d(f); }			\
    1524    __gmp_expr(double d) { init_d(d); }
    1525  
    1526  #define __GMPXX_DEFINE_ARITHMETIC_ASSIGNMENTS		\
    1527    __gmp_expr & operator=(signed char c) { assign_si(c); return *this; } \
    1528    __gmp_expr & operator=(unsigned char c) { assign_ui(c); return *this; } \
    1529    __gmp_expr & operator=(signed int i) { assign_si(i); return *this; } \
    1530    __gmp_expr & operator=(unsigned int i) { assign_ui(i); return *this; } \
    1531    __gmp_expr & operator=(signed short int s) { assign_si(s); return *this; } \
    1532    __gmp_expr & operator=(unsigned short int s) { assign_ui(s); return *this; } \
    1533    __gmp_expr & operator=(signed long int l) { assign_si(l); return *this; } \
    1534    __gmp_expr & operator=(unsigned long int l) { assign_ui(l); return *this; } \
    1535    __gmp_expr & operator=(float f) { assign_d(f); return *this; } \
    1536    __gmp_expr & operator=(double d) { assign_d(d); return *this; }
    1537  
    1538  #define __GMPP_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun)                 \
    1539  template <class U>                                                           \
    1540  static __gmp_expr<T, __gmp_unary_expr<__gmp_expr<T, U>, eval_fun> >          \
    1541  fun(const __gmp_expr<T, U> &expr);
    1542  
    1543  #define __GMPNN_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, type, bigtype) \
    1544  static inline __gmp_expr<T, __gmp_unary_expr<bigtype, eval_fun> >            \
    1545  fun(type expr);
    1546  
    1547  #define __GMPNS_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, type)  \
    1548  __GMPNN_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, type, signed long)
    1549  #define __GMPNU_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, type)  \
    1550  __GMPNN_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, type, unsigned long)
    1551  #define __GMPND_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, type)  \
    1552  __GMPNN_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, type, double)
    1553  
    1554  #define __GMPN_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun)                 \
    1555  __GMPNS_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, signed char)           \
    1556  __GMPNU_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, unsigned char)         \
    1557  __GMPNS_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, signed int)            \
    1558  __GMPNU_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, unsigned int)          \
    1559  __GMPNS_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, signed short int)      \
    1560  __GMPNU_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, unsigned short int)    \
    1561  __GMPNS_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, signed long int)       \
    1562  __GMPNU_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, unsigned long int)     \
    1563  __GMPND_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, float)                 \
    1564  __GMPND_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, double)
    1565  
    1566  #define __GMP_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun)                  \
    1567  __GMPP_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun)                         \
    1568  __GMPN_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun)
    1569  
    1570  /**************** mpz_class -- wrapper for mpz_t ****************/
    1571  
    1572  template <>
    1573  class __gmp_expr<mpz_t, mpz_t>
    1574  {
    1575  private:
    1576    typedef mpz_t value_type;
    1577    value_type mp;
    1578  
    1579    // Helper functions used for all arithmetic types
    1580    void assign_ui(unsigned long l)
    1581    {
    1582      if (__GMPXX_CONSTANT_TRUE(l == 0))
    1583        __get_mp()->_mp_size = 0;
    1584      else
    1585        mpz_set_ui(mp, l);
    1586    }
    1587    void assign_si(signed long l)
    1588    {
    1589      if (__GMPXX_CONSTANT_TRUE(l >= 0))
    1590        assign_ui(l);
    1591      else if (__GMPXX_CONSTANT_TRUE(l <= 0))
    1592        {
    1593  	assign_ui(-static_cast<unsigned long>(l));
    1594  	mpz_neg(mp, mp);
    1595        }
    1596      else
    1597        mpz_set_si(mp, l);
    1598    }
    1599    void assign_d (double d)
    1600    {
    1601      mpz_set_d (mp, d);
    1602    }
    1603  
    1604    void init_ui(unsigned long l)
    1605    {
    1606      if (__GMPXX_CONSTANT_TRUE(l == 0))
    1607        mpz_init(mp);
    1608      else
    1609        mpz_init_set_ui(mp, l);
    1610    }
    1611    void init_si(signed long l)
    1612    {
    1613      if (__GMPXX_CONSTANT_TRUE(l >= 0))
    1614        init_ui(l);
    1615      else if (__GMPXX_CONSTANT_TRUE(l <= 0))
    1616        {
    1617  	init_ui(-static_cast<unsigned long>(l));
    1618  	mpz_neg(mp, mp);
    1619        }
    1620      else
    1621        mpz_init_set_si(mp, l);
    1622    }
    1623    void init_d (double d)
    1624    {
    1625      mpz_init_set_d (mp, d);
    1626    }
    1627  
    1628  public:
    1629    mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); }
    1630  
    1631    // constructors and destructor
    1632    __gmp_expr() __GMPXX_NOEXCEPT { mpz_init(mp); }
    1633  
    1634    __gmp_expr(const __gmp_expr &z) { mpz_init_set(mp, z.mp); }
    1635  #if __GMPXX_USE_CXX11
    1636    __gmp_expr(__gmp_expr &&z) noexcept
    1637    { *__get_mp() = *z.__get_mp(); mpz_init(z.mp); }
    1638  #endif
    1639    template <class T>
    1640    __gmp_expr(const __gmp_expr<mpz_t, T> &expr)
    1641    { mpz_init(mp); __gmp_set_expr(mp, expr); }
    1642    template <class T, class U>
    1643    explicit __gmp_expr(const __gmp_expr<T, U> &expr)
    1644    { mpz_init(mp); __gmp_set_expr(mp, expr); }
    1645  
    1646    __GMPXX_DEFINE_ARITHMETIC_CONSTRUCTORS
    1647  
    1648    explicit __gmp_expr(const char *s, int base = 0)
    1649    {
    1650      if (mpz_init_set_str (mp, s, base) != 0)
    1651        {
    1652          mpz_clear (mp);
    1653          throw std::invalid_argument ("mpz_set_str");
    1654        }
    1655    }
    1656    explicit __gmp_expr(const std::string &s, int base = 0)
    1657    {
    1658      if (mpz_init_set_str(mp, s.c_str(), base) != 0)
    1659        {
    1660          mpz_clear (mp);
    1661          throw std::invalid_argument ("mpz_set_str");
    1662        }
    1663    }
    1664  
    1665    explicit __gmp_expr(mpz_srcptr z) { mpz_init_set(mp, z); }
    1666  
    1667    ~__gmp_expr() { mpz_clear(mp); }
    1668  
    1669    void swap(__gmp_expr& z) __GMPXX_NOEXCEPT
    1670    { std::swap(*__get_mp(), *z.__get_mp()); }
    1671  
    1672    // assignment operators
    1673    __gmp_expr & operator=(const __gmp_expr &z)
    1674    { mpz_set(mp, z.mp); return *this; }
    1675  #if __GMPXX_USE_CXX11
    1676    __gmp_expr & operator=(__gmp_expr &&z) noexcept
    1677    { swap(z); return *this; }
    1678  #endif
    1679    template <class T, class U>
    1680    __gmp_expr<value_type, value_type> & operator=(const __gmp_expr<T, U> &expr)
    1681    { __gmp_set_expr(mp, expr); return *this; }
    1682  
    1683    __GMPXX_DEFINE_ARITHMETIC_ASSIGNMENTS
    1684  
    1685    __gmp_expr & operator=(const char *s)
    1686    {
    1687      if (mpz_set_str (mp, s, 0) != 0)
    1688        throw std::invalid_argument ("mpz_set_str");
    1689      return *this;
    1690    }
    1691    __gmp_expr & operator=(const std::string &s)
    1692    {
    1693      if (mpz_set_str(mp, s.c_str(), 0) != 0)
    1694        throw std::invalid_argument ("mpz_set_str");
    1695      return *this;
    1696    }
    1697  
    1698    // string input/output functions
    1699    int set_str(const char *s, int base)
    1700    { return mpz_set_str(mp, s, base); }
    1701    int set_str(const std::string &s, int base)
    1702    { return mpz_set_str(mp, s.c_str(), base); }
    1703    std::string get_str(int base = 10) const
    1704    {
    1705      __gmp_alloc_cstring temp(mpz_get_str(0, base, mp));
    1706      return std::string(temp.str);
    1707    }
    1708  
    1709    // conversion functions
    1710    mpz_srcptr __get_mp() const { return mp; }
    1711    mpz_ptr __get_mp() { return mp; }
    1712    mpz_srcptr get_mpz_t() const { return mp; }
    1713    mpz_ptr get_mpz_t() { return mp; }
    1714  
    1715    signed long int get_si() const { return mpz_get_si(mp); }
    1716    unsigned long int get_ui() const { return mpz_get_ui(mp); }
    1717    double get_d() const { return mpz_get_d(mp); }
    1718  
    1719    // bool fits_schar_p() const { return mpz_fits_schar_p(mp); }
    1720    // bool fits_uchar_p() const { return mpz_fits_uchar_p(mp); }
    1721    bool fits_sint_p() const { return mpz_fits_sint_p(mp); }
    1722    bool fits_uint_p() const { return mpz_fits_uint_p(mp); }
    1723    bool fits_sshort_p() const { return mpz_fits_sshort_p(mp); }
    1724    bool fits_ushort_p() const { return mpz_fits_ushort_p(mp); }
    1725    bool fits_slong_p() const { return mpz_fits_slong_p(mp); }
    1726    bool fits_ulong_p() const { return mpz_fits_ulong_p(mp); }
    1727    // bool fits_float_p() const { return mpz_fits_float_p(mp); }
    1728    // bool fits_double_p() const { return mpz_fits_double_p(mp); }
    1729    // bool fits_ldouble_p() const { return mpz_fits_ldouble_p(mp); }
    1730  
    1731  #if __GMPXX_USE_CXX11
    1732    explicit operator bool() const { return __get_mp()->_mp_size != 0; }
    1733  #endif
    1734  
    1735    // member operators
    1736    __GMP_DECLARE_COMPOUND_OPERATOR(operator+=)
    1737    __GMP_DECLARE_COMPOUND_OPERATOR(operator-=)
    1738    __GMP_DECLARE_COMPOUND_OPERATOR(operator*=)
    1739    __GMP_DECLARE_COMPOUND_OPERATOR(operator/=)
    1740    __GMP_DECLARE_COMPOUND_OPERATOR(operator%=)
    1741  
    1742    __GMP_DECLARE_COMPOUND_OPERATOR(operator&=)
    1743    __GMP_DECLARE_COMPOUND_OPERATOR(operator|=)
    1744    __GMP_DECLARE_COMPOUND_OPERATOR(operator^=)
    1745  
    1746    __GMP_DECLARE_COMPOUND_OPERATOR_UI(operator<<=)
    1747    __GMP_DECLARE_COMPOUND_OPERATOR_UI(operator>>=)
    1748  
    1749    __GMP_DECLARE_INCREMENT_OPERATOR(operator++)
    1750    __GMP_DECLARE_INCREMENT_OPERATOR(operator--)
    1751  
    1752    __GMP_DECLARE_UNARY_STATIC_MEMFUN(mpz_t, factorial, __gmp_fac_function)
    1753    __GMP_DECLARE_UNARY_STATIC_MEMFUN(mpz_t, primorial, __gmp_primorial_function)
    1754    __GMP_DECLARE_UNARY_STATIC_MEMFUN(mpz_t, fibonacci, __gmp_fib_function)
    1755  };
    1756  
    1757  typedef __gmp_expr<mpz_t, mpz_t> mpz_class;
    1758  
    1759  
    1760  /**************** mpq_class -- wrapper for mpq_t ****************/
    1761  
    1762  template <>
    1763  class __gmp_expr<mpq_t, mpq_t>
    1764  {
    1765  private:
    1766    typedef mpq_t value_type;
    1767    value_type mp;
    1768  
    1769    // Helper functions used for all arithmetic types
    1770    void assign_ui(unsigned long l) { mpq_set_ui(mp, l, 1); }
    1771    void assign_si(signed long l)
    1772    {
    1773      if (__GMPXX_CONSTANT_TRUE(l >= 0))
    1774        assign_ui(l);
    1775      else
    1776        mpq_set_si(mp, l, 1);
    1777    }
    1778    void assign_d (double d)        { mpq_set_d (mp, d); }
    1779  
    1780    void init_ui(unsigned long l)	{ mpq_init(mp); get_num() = l; }
    1781    void init_si(signed long l)	{ mpq_init(mp); get_num() = l; }
    1782    void init_d (double d)	{ mpq_init(mp); assign_d (d); }
    1783  
    1784  public:
    1785    mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); }
    1786    void canonicalize() { mpq_canonicalize(mp); }
    1787  
    1788    // constructors and destructor
    1789    __gmp_expr() { mpq_init(mp); }
    1790  
    1791    __gmp_expr(const __gmp_expr &q)
    1792    {
    1793      mpz_init_set(mpq_numref(mp), mpq_numref(q.mp));
    1794      mpz_init_set(mpq_denref(mp), mpq_denref(q.mp));
    1795    }
    1796  #if __GMPXX_USE_CXX11
    1797    __gmp_expr(__gmp_expr &&q)
    1798    { *mp = *q.mp; mpq_init(q.mp); }
    1799    __gmp_expr(mpz_class &&z)
    1800    {
    1801      *mpq_numref(mp) = *z.get_mpz_t();
    1802      mpz_init_set_ui(mpq_denref(mp), 1);
    1803      mpz_init(z.get_mpz_t());
    1804    }
    1805  #endif
    1806    template <class T>
    1807    __gmp_expr(const __gmp_expr<mpz_t, T> &expr)
    1808    { mpq_init(mp); __gmp_set_expr(mp, expr); }
    1809    template <class T>
    1810    __gmp_expr(const __gmp_expr<mpq_t, T> &expr)
    1811    { mpq_init(mp); __gmp_set_expr(mp, expr); }
    1812    template <class T, class U>
    1813    explicit __gmp_expr(const __gmp_expr<T, U> &expr)
    1814    { mpq_init(mp); __gmp_set_expr(mp, expr); }
    1815  
    1816    __GMPXX_DEFINE_ARITHMETIC_CONSTRUCTORS
    1817  
    1818    explicit __gmp_expr(const char *s, int base = 0)
    1819    {
    1820      mpq_init (mp);
    1821      // If s is the literal 0, we meant to call another constructor.
    1822      // If s just happens to evaluate to 0, we would crash, so whatever.
    1823      if (s == 0)
    1824        {
    1825  	// Don't turn mpq_class(0,0) into 0
    1826  	mpz_set_si(mpq_denref(mp), base);
    1827        }
    1828      else if (mpq_set_str(mp, s, base) != 0)
    1829        {
    1830          mpq_clear (mp);
    1831          throw std::invalid_argument ("mpq_set_str");
    1832        }
    1833    }
    1834    explicit __gmp_expr(const std::string &s, int base = 0)
    1835    {
    1836      mpq_init(mp);
    1837      if (mpq_set_str (mp, s.c_str(), base) != 0)
    1838        {
    1839          mpq_clear (mp);
    1840          throw std::invalid_argument ("mpq_set_str");
    1841        }
    1842    }
    1843    explicit __gmp_expr(mpq_srcptr q)
    1844    {
    1845      mpz_init_set(mpq_numref(mp), mpq_numref(q));
    1846      mpz_init_set(mpq_denref(mp), mpq_denref(q));
    1847    }
    1848  
    1849    __gmp_expr(const mpz_class &num, const mpz_class &den)
    1850    {
    1851      mpz_init_set(mpq_numref(mp), num.get_mpz_t());
    1852      mpz_init_set(mpq_denref(mp), den.get_mpz_t());
    1853    }
    1854  
    1855    ~__gmp_expr() { mpq_clear(mp); }
    1856  
    1857    void swap(__gmp_expr& q) __GMPXX_NOEXCEPT { std::swap(*mp, *q.mp); }
    1858  
    1859    // assignment operators
    1860    __gmp_expr & operator=(const __gmp_expr &q)
    1861    { mpq_set(mp, q.mp); return *this; }
    1862  #if __GMPXX_USE_CXX11
    1863    __gmp_expr & operator=(__gmp_expr &&q) noexcept
    1864    { swap(q); return *this; }
    1865    __gmp_expr & operator=(mpz_class &&z) noexcept
    1866    { get_num() = std::move(z); get_den() = 1u; return *this; }
    1867  #endif
    1868    template <class T, class U>
    1869    __gmp_expr<value_type, value_type> & operator=(const __gmp_expr<T, U> &expr)
    1870    { __gmp_set_expr(mp, expr); return *this; }
    1871  
    1872    __GMPXX_DEFINE_ARITHMETIC_ASSIGNMENTS
    1873  
    1874    __gmp_expr & operator=(const char *s)
    1875    {
    1876      if (mpq_set_str (mp, s, 0) != 0)
    1877        throw std::invalid_argument ("mpq_set_str");
    1878      return *this;
    1879    }
    1880    __gmp_expr & operator=(const std::string &s)
    1881    {
    1882      if (mpq_set_str(mp, s.c_str(), 0) != 0)
    1883        throw std::invalid_argument ("mpq_set_str");
    1884      return *this;
    1885    }
    1886  
    1887    // string input/output functions
    1888    int set_str(const char *s, int base)
    1889    { return mpq_set_str(mp, s, base); }
    1890    int set_str(const std::string &s, int base)
    1891    { return mpq_set_str(mp, s.c_str(), base); }
    1892    std::string get_str(int base = 10) const
    1893    {
    1894      __gmp_alloc_cstring temp(mpq_get_str(0, base, mp));
    1895      return std::string(temp.str);
    1896    }
    1897  
    1898    // conversion functions
    1899  
    1900    // casting a reference to an mpz_t to mpz_class & is a dirty hack.
    1901    // It kind of works because the internal representation of mpz_class is
    1902    // exactly an mpz_t, but compilers are allowed to assume that mpq_class
    1903    // and mpz_class do not alias... In mpz_class, we avoid using mp directly,
    1904    // to reduce the risks of such problematic optimizations.
    1905    const mpz_class & get_num() const
    1906    { return reinterpret_cast<const mpz_class &>(*mpq_numref(mp)); }
    1907    mpz_class & get_num()
    1908    { return reinterpret_cast<mpz_class &>(*mpq_numref(mp)); }
    1909    const mpz_class & get_den() const
    1910    { return reinterpret_cast<const mpz_class &>(*mpq_denref(mp)); }
    1911    mpz_class & get_den()
    1912    { return reinterpret_cast<mpz_class &>(*mpq_denref(mp)); }
    1913  
    1914    mpq_srcptr __get_mp() const { return mp; }
    1915    mpq_ptr __get_mp() { return mp; }
    1916    mpq_srcptr get_mpq_t() const { return mp; }
    1917    mpq_ptr get_mpq_t() { return mp; }
    1918  
    1919    mpz_srcptr get_num_mpz_t() const { return mpq_numref(mp); }
    1920    mpz_ptr get_num_mpz_t() { return mpq_numref(mp); }
    1921    mpz_srcptr get_den_mpz_t() const { return mpq_denref(mp); }
    1922    mpz_ptr get_den_mpz_t() { return mpq_denref(mp); }
    1923  
    1924    double get_d() const { return mpq_get_d(mp); }
    1925  
    1926  #if __GMPXX_USE_CXX11
    1927    explicit operator bool() const { return mpq_numref(mp)->_mp_size != 0; }
    1928  #endif
    1929  
    1930    // compound assignments
    1931    __GMP_DECLARE_COMPOUND_OPERATOR(operator+=)
    1932    __GMP_DECLARE_COMPOUND_OPERATOR(operator-=)
    1933    __GMP_DECLARE_COMPOUND_OPERATOR(operator*=)
    1934    __GMP_DECLARE_COMPOUND_OPERATOR(operator/=)
    1935  
    1936    __GMP_DECLARE_COMPOUND_OPERATOR_UI(operator<<=)
    1937    __GMP_DECLARE_COMPOUND_OPERATOR_UI(operator>>=)
    1938  
    1939    __GMP_DECLARE_INCREMENT_OPERATOR(operator++)
    1940    __GMP_DECLARE_INCREMENT_OPERATOR(operator--)
    1941  };
    1942  
    1943  typedef __gmp_expr<mpq_t, mpq_t> mpq_class;
    1944  
    1945  
    1946  /**************** mpf_class -- wrapper for mpf_t ****************/
    1947  
    1948  template <>
    1949  class __gmp_expr<mpf_t, mpf_t>
    1950  {
    1951  private:
    1952    typedef mpf_t value_type;
    1953    value_type mp;
    1954  
    1955    // Helper functions used for all arithmetic types
    1956    void assign_ui(unsigned long l) { mpf_set_ui(mp, l); }
    1957    void assign_si(signed long l)
    1958    {
    1959      if (__GMPXX_CONSTANT_TRUE(l >= 0))
    1960        assign_ui(l);
    1961      else
    1962        mpf_set_si(mp, l);
    1963    }
    1964    void assign_d (double d)        { mpf_set_d (mp, d); }
    1965  
    1966    void init_ui(unsigned long l)
    1967    {
    1968      if (__GMPXX_CONSTANT_TRUE(l == 0))
    1969        mpf_init(mp);
    1970      else
    1971        mpf_init_set_ui(mp, l);
    1972    }
    1973    void init_si(signed long l)
    1974    {
    1975      if (__GMPXX_CONSTANT_TRUE(l >= 0))
    1976        init_ui(l);
    1977      else
    1978        mpf_init_set_si(mp, l);
    1979    }
    1980    void init_d (double d)	{ mpf_init_set_d (mp, d); }
    1981  
    1982  public:
    1983    mp_bitcnt_t get_prec() const { return mpf_get_prec(mp); }
    1984  
    1985    void set_prec(mp_bitcnt_t prec) { mpf_set_prec(mp, prec); }
    1986    void set_prec_raw(mp_bitcnt_t prec) { mpf_set_prec_raw(mp, prec); }
    1987  
    1988    // constructors and destructor
    1989    __gmp_expr() { mpf_init(mp); }
    1990  
    1991    __gmp_expr(const __gmp_expr &f)
    1992    { mpf_init2(mp, f.get_prec()); mpf_set(mp, f.mp); }
    1993  #if __GMPXX_USE_CXX11
    1994    __gmp_expr(__gmp_expr &&f)
    1995    { *mp = *f.mp; mpf_init2(f.mp, get_prec()); }
    1996  #endif
    1997    __gmp_expr(const __gmp_expr &f, mp_bitcnt_t prec)
    1998    { mpf_init2(mp, prec); mpf_set(mp, f.mp); }
    1999    template <class T, class U>
    2000    __gmp_expr(const __gmp_expr<T, U> &expr)
    2001    { mpf_init2(mp, expr.get_prec()); __gmp_set_expr(mp, expr); }
    2002    template <class T, class U>
    2003    __gmp_expr(const __gmp_expr<T, U> &expr, mp_bitcnt_t prec)
    2004    { mpf_init2(mp, prec); __gmp_set_expr(mp, expr); }
    2005  
    2006    __GMPXX_DEFINE_ARITHMETIC_CONSTRUCTORS
    2007  
    2008    __gmp_expr(signed char c, mp_bitcnt_t prec)
    2009    { mpf_init2(mp, prec); mpf_set_si(mp, c); }
    2010    __gmp_expr(unsigned char c, mp_bitcnt_t prec)
    2011    { mpf_init2(mp, prec); mpf_set_ui(mp, c); }
    2012  
    2013    __gmp_expr(signed int i, mp_bitcnt_t prec)
    2014    { mpf_init2(mp, prec); mpf_set_si(mp, i); }
    2015    __gmp_expr(unsigned int i, mp_bitcnt_t prec)
    2016    { mpf_init2(mp, prec); mpf_set_ui(mp, i); }
    2017  
    2018    __gmp_expr(signed short int s, mp_bitcnt_t prec)
    2019    { mpf_init2(mp, prec); mpf_set_si(mp, s); }
    2020    __gmp_expr(unsigned short int s, mp_bitcnt_t prec)
    2021    { mpf_init2(mp, prec); mpf_set_ui(mp, s); }
    2022  
    2023    __gmp_expr(signed long int l, mp_bitcnt_t prec)
    2024    { mpf_init2(mp, prec); mpf_set_si(mp, l); }
    2025    __gmp_expr(unsigned long int l, mp_bitcnt_t prec)
    2026    { mpf_init2(mp, prec); mpf_set_ui(mp, l); }
    2027  
    2028    __gmp_expr(float f, mp_bitcnt_t prec)
    2029    { mpf_init2(mp, prec); mpf_set_d(mp, f); }
    2030    __gmp_expr(double d, mp_bitcnt_t prec)
    2031    { mpf_init2(mp, prec); mpf_set_d(mp, d); }
    2032    // __gmp_expr(long double ld) { mpf_init_set_d(mp, ld); }
    2033    // __gmp_expr(long double ld, mp_bitcnt_t prec)
    2034    // { mpf_init2(mp, prec); mpf_set_d(mp, ld); }
    2035  
    2036    explicit __gmp_expr(const char *s)
    2037    {
    2038      if (mpf_init_set_str (mp, s, 0) != 0)
    2039        {
    2040          mpf_clear (mp);
    2041          throw std::invalid_argument ("mpf_set_str");
    2042        }
    2043    }
    2044    __gmp_expr(const char *s, mp_bitcnt_t prec, int base = 0)
    2045    {
    2046      mpf_init2(mp, prec);
    2047      if (mpf_set_str(mp, s, base) != 0)
    2048        {
    2049          mpf_clear (mp);
    2050          throw std::invalid_argument ("mpf_set_str");
    2051        }
    2052    }
    2053    explicit __gmp_expr(const std::string &s)
    2054    {
    2055      if (mpf_init_set_str(mp, s.c_str(), 0) != 0)
    2056        {
    2057          mpf_clear (mp);
    2058          throw std::invalid_argument ("mpf_set_str");
    2059        }
    2060    }
    2061    __gmp_expr(const std::string &s, mp_bitcnt_t prec, int base = 0)
    2062    {
    2063      mpf_init2(mp, prec);
    2064      if (mpf_set_str(mp, s.c_str(), base) != 0)
    2065        {
    2066          mpf_clear (mp);
    2067          throw std::invalid_argument ("mpf_set_str");
    2068        }
    2069    }
    2070  
    2071    explicit __gmp_expr(mpf_srcptr f)
    2072    { mpf_init2(mp, mpf_get_prec(f)); mpf_set(mp, f); }
    2073    __gmp_expr(mpf_srcptr f, mp_bitcnt_t prec)
    2074    { mpf_init2(mp, prec); mpf_set(mp, f); }
    2075  
    2076    ~__gmp_expr() { mpf_clear(mp); }
    2077  
    2078    void swap(__gmp_expr& f) __GMPXX_NOEXCEPT { std::swap(*mp, *f.mp); }
    2079  
    2080    // assignment operators
    2081    __gmp_expr & operator=(const __gmp_expr &f)
    2082    { mpf_set(mp, f.mp); return *this; }
    2083  #if __GMPXX_USE_CXX11
    2084    __gmp_expr & operator=(__gmp_expr &&f) noexcept
    2085    { swap(f); return *this; }
    2086  #endif
    2087    template <class T, class U>
    2088    __gmp_expr<value_type, value_type> & operator=(const __gmp_expr<T, U> &expr)
    2089    { __gmp_set_expr(mp, expr); return *this; }
    2090  
    2091    __GMPXX_DEFINE_ARITHMETIC_ASSIGNMENTS
    2092  
    2093    __gmp_expr & operator=(const char *s)
    2094    {
    2095      if (mpf_set_str (mp, s, 0) != 0)
    2096        throw std::invalid_argument ("mpf_set_str");
    2097      return *this;
    2098    }
    2099    __gmp_expr & operator=(const std::string &s)
    2100    {
    2101      if (mpf_set_str(mp, s.c_str(), 0) != 0)
    2102        throw std::invalid_argument ("mpf_set_str");
    2103      return *this;
    2104    }
    2105  
    2106    // string input/output functions
    2107    int set_str(const char *s, int base)
    2108    { return mpf_set_str(mp, s, base); }
    2109    int set_str(const std::string &s, int base)
    2110    { return mpf_set_str(mp, s.c_str(), base); }
    2111    std::string get_str(mp_exp_t &expo, int base = 10, size_t size = 0) const
    2112    {
    2113      __gmp_alloc_cstring temp(mpf_get_str(0, &expo, base, size, mp));
    2114      return std::string(temp.str);
    2115    }
    2116  
    2117    // conversion functions
    2118    mpf_srcptr __get_mp() const { return mp; }
    2119    mpf_ptr __get_mp() { return mp; }
    2120    mpf_srcptr get_mpf_t() const { return mp; }
    2121    mpf_ptr get_mpf_t() { return mp; }
    2122  
    2123    signed long int get_si() const { return mpf_get_si(mp); }
    2124    unsigned long int get_ui() const { return mpf_get_ui(mp); }
    2125    double get_d() const { return mpf_get_d(mp); }
    2126  
    2127    // bool fits_schar_p() const { return mpf_fits_schar_p(mp); }
    2128    // bool fits_uchar_p() const { return mpf_fits_uchar_p(mp); }
    2129    bool fits_sint_p() const { return mpf_fits_sint_p(mp); }
    2130    bool fits_uint_p() const { return mpf_fits_uint_p(mp); }
    2131    bool fits_sshort_p() const { return mpf_fits_sshort_p(mp); }
    2132    bool fits_ushort_p() const { return mpf_fits_ushort_p(mp); }
    2133    bool fits_slong_p() const { return mpf_fits_slong_p(mp); }
    2134    bool fits_ulong_p() const { return mpf_fits_ulong_p(mp); }
    2135    // bool fits_float_p() const { return mpf_fits_float_p(mp); }
    2136    // bool fits_double_p() const { return mpf_fits_double_p(mp); }
    2137    // bool fits_ldouble_p() const { return mpf_fits_ldouble_p(mp); }
    2138  
    2139  #if __GMPXX_USE_CXX11
    2140    explicit operator bool() const { return mpf_sgn(mp) != 0; }
    2141  #endif
    2142  
    2143    // compound assignments
    2144    __GMP_DECLARE_COMPOUND_OPERATOR(operator+=)
    2145    __GMP_DECLARE_COMPOUND_OPERATOR(operator-=)
    2146    __GMP_DECLARE_COMPOUND_OPERATOR(operator*=)
    2147    __GMP_DECLARE_COMPOUND_OPERATOR(operator/=)
    2148  
    2149    __GMP_DECLARE_COMPOUND_OPERATOR_UI(operator<<=)
    2150    __GMP_DECLARE_COMPOUND_OPERATOR_UI(operator>>=)
    2151  
    2152    __GMP_DECLARE_INCREMENT_OPERATOR(operator++)
    2153    __GMP_DECLARE_INCREMENT_OPERATOR(operator--)
    2154  };
    2155  
    2156  typedef __gmp_expr<mpf_t, mpf_t> mpf_class;
    2157  
    2158  
    2159  
    2160  /**************** User-defined literals ****************/
    2161  
    2162  #if __GMPXX_USE_CXX11
    2163  inline mpz_class operator"" _mpz(const char* s)
    2164  {
    2165    return mpz_class(s);
    2166  }
    2167  
    2168  inline mpq_class operator"" _mpq(const char* s)
    2169  {
    2170    mpq_class q;
    2171    q.get_num() = s;
    2172    return q;
    2173  }
    2174  
    2175  inline mpf_class operator"" _mpf(const char* s)
    2176  {
    2177    return mpf_class(s);
    2178  }
    2179  #endif
    2180  
    2181  /**************** I/O operators ****************/
    2182  
    2183  // these should (and will) be provided separately
    2184  
    2185  template <class T, class U>
    2186  inline std::ostream & operator<<
    2187  (std::ostream &o, const __gmp_expr<T, U> &expr)
    2188  {
    2189    __gmp_expr<T, T> const& temp(expr);
    2190    return o << temp.__get_mp();
    2191  }
    2192  
    2193  template <class T>
    2194  inline std::istream & operator>>(std::istream &i, __gmp_expr<T, T> &expr)
    2195  {
    2196    return i >> expr.__get_mp();
    2197  }
    2198  
    2199  /*
    2200  // you might want to uncomment this
    2201  inline std::istream & operator>>(std::istream &i, mpq_class &q)
    2202  {
    2203    i >> q.get_mpq_t();
    2204    q.canonicalize();
    2205    return i;
    2206  }
    2207  */
    2208  
    2209  
    2210  /**************** Functions for type conversion ****************/
    2211  
    2212  inline void __gmp_set_expr(mpz_ptr z, const mpz_class &w)
    2213  {
    2214    mpz_set(z, w.get_mpz_t());
    2215  }
    2216  
    2217  template <class T>
    2218  inline void __gmp_set_expr(mpz_ptr z, const __gmp_expr<mpz_t, T> &expr)
    2219  {
    2220    expr.eval(z);
    2221  }
    2222  
    2223  template <class T>
    2224  inline void __gmp_set_expr(mpz_ptr z, const __gmp_expr<mpq_t, T> &expr)
    2225  {
    2226    mpq_class const& temp(expr);
    2227    mpz_set_q(z, temp.get_mpq_t());
    2228  }
    2229  
    2230  template <class T>
    2231  inline void __gmp_set_expr(mpz_ptr z, const __gmp_expr<mpf_t, T> &expr)
    2232  {
    2233    mpf_class const& temp(expr);
    2234    mpz_set_f(z, temp.get_mpf_t());
    2235  }
    2236  
    2237  inline void __gmp_set_expr(mpq_ptr q, const mpz_class &z)
    2238  {
    2239    mpq_set_z(q, z.get_mpz_t());
    2240  }
    2241  
    2242  template <class T>
    2243  inline void __gmp_set_expr(mpq_ptr q, const __gmp_expr<mpz_t, T> &expr)
    2244  {
    2245    __gmp_set_expr(mpq_numref(q), expr);
    2246    mpz_set_ui(mpq_denref(q), 1);
    2247  }
    2248  
    2249  inline void __gmp_set_expr(mpq_ptr q, const mpq_class &r)
    2250  {
    2251    mpq_set(q, r.get_mpq_t());
    2252  }
    2253  
    2254  template <class T>
    2255  inline void __gmp_set_expr(mpq_ptr q, const __gmp_expr<mpq_t, T> &expr)
    2256  {
    2257    expr.eval(q);
    2258  }
    2259  
    2260  template <class T>
    2261  inline void __gmp_set_expr(mpq_ptr q, const __gmp_expr<mpf_t, T> &expr)
    2262  {
    2263    mpf_class const& temp(expr);
    2264    mpq_set_f(q, temp.get_mpf_t());
    2265  }
    2266  
    2267  template <class T>
    2268  inline void __gmp_set_expr(mpf_ptr f, const __gmp_expr<mpz_t, T> &expr)
    2269  {
    2270    mpz_class const& temp(expr);
    2271    mpf_set_z(f, temp.get_mpz_t());
    2272  }
    2273  
    2274  template <class T>
    2275  inline void __gmp_set_expr(mpf_ptr f, const __gmp_expr<mpq_t, T> &expr)
    2276  {
    2277    mpq_class const& temp(expr);
    2278    mpf_set_q(f, temp.get_mpq_t());
    2279  }
    2280  
    2281  inline void __gmp_set_expr(mpf_ptr f, const mpf_class &g)
    2282  {
    2283    mpf_set(f, g.get_mpf_t());
    2284  }
    2285  
    2286  template <class T>
    2287  inline void __gmp_set_expr(mpf_ptr f, const __gmp_expr<mpf_t, T> &expr)
    2288  {
    2289    expr.eval(f);
    2290  }
    2291  
    2292  
    2293  /* Temporary objects */
    2294  
    2295  template <class T>
    2296  class __gmp_temp
    2297  {
    2298    __gmp_expr<T, T> val;
    2299    public:
    2300    template<class U, class V>
    2301    __gmp_temp(U const& u, V) : val (u) {}
    2302    typename __gmp_resolve_expr<T>::srcptr_type
    2303    __get_mp() const { return val.__get_mp(); }
    2304  };
    2305  
    2306  template <>
    2307  class __gmp_temp <mpf_t>
    2308  {
    2309    mpf_class val;
    2310    public:
    2311    template<class U>
    2312    __gmp_temp(U const& u, mpf_ptr res) : val (u, mpf_get_prec(res)) {}
    2313    mpf_srcptr __get_mp() const { return val.__get_mp(); }
    2314  };
    2315  
    2316  /**************** Specializations of __gmp_expr ****************/
    2317  /* The eval() method of __gmp_expr<T, U> evaluates the corresponding
    2318     expression and assigns the result to its argument, which is either an
    2319     mpz_t, mpq_t, or mpf_t as specified by the T argument.
    2320     Compound expressions are evaluated recursively (temporaries are created
    2321     to hold intermediate values), while for simple expressions the eval()
    2322     method of the appropriate function object (available as the Op argument
    2323     of either __gmp_unary_expr<T, Op> or __gmp_binary_expr<T, U, Op>) is
    2324     called. */
    2325  
    2326  
    2327  /**************** Unary expressions ****************/
    2328  /* cases:
    2329     - simple:   argument is mp*_class, that is, __gmp_expr<T, T>
    2330     - compound: argument is __gmp_expr<T, U> (with U not equal to T) */
    2331  
    2332  
    2333  // simple expressions
    2334  
    2335  template <class T, class Op>
    2336  class __gmp_expr<T, __gmp_unary_expr<__gmp_expr<T, T>, Op> >
    2337  {
    2338  private:
    2339    typedef __gmp_expr<T, T> val_type;
    2340  
    2341    __gmp_unary_expr<val_type, Op> expr;
    2342  public:
    2343    explicit __gmp_expr(const val_type &val) : expr(val) { }
    2344    void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
    2345    { Op::eval(p, expr.val.__get_mp()); }
    2346    const val_type & get_val() const { return expr.val; }
    2347    mp_bitcnt_t get_prec() const { return expr.val.get_prec(); }
    2348  };
    2349  
    2350  
    2351  // simple expressions, U is a built-in numerical type
    2352  
    2353  template <class T, class U, class Op>
    2354  class __gmp_expr<T, __gmp_unary_expr<U, Op> >
    2355  {
    2356  private:
    2357    typedef U val_type;
    2358  
    2359    __gmp_unary_expr<val_type, Op> expr;
    2360  public:
    2361    explicit __gmp_expr(const val_type &val) : expr(val) { }
    2362    void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
    2363    { Op::eval(p, expr.val); }
    2364    const val_type & get_val() const { return expr.val; }
    2365    mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); }
    2366  };
    2367  
    2368  
    2369  // compound expressions
    2370  
    2371  template <class T, class U, class Op>
    2372  class __gmp_expr<T, __gmp_unary_expr<__gmp_expr<T, U>, Op> >
    2373  {
    2374  private:
    2375    typedef __gmp_expr<T, U> val_type;
    2376  
    2377    __gmp_unary_expr<val_type, Op> expr;
    2378  public:
    2379    explicit __gmp_expr(const val_type &val) : expr(val) { }
    2380    void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
    2381    { expr.val.eval(p); Op::eval(p, p); }
    2382    const val_type & get_val() const { return expr.val; }
    2383    mp_bitcnt_t get_prec() const { return expr.val.get_prec(); }
    2384  };
    2385  
    2386  
    2387  /**************** Binary expressions ****************/
    2388  /* simple:
    2389     - arguments are both mp*_class
    2390     - one argument is mp*_class, one is a built-in type
    2391     compound:
    2392     - one is mp*_class, one is __gmp_expr<T, U>
    2393     - one is __gmp_expr<T, U>, one is built-in
    2394     - both arguments are __gmp_expr<...> */
    2395  
    2396  
    2397  // simple expressions
    2398  
    2399  template <class T, class Op>
    2400  class __gmp_expr
    2401  <T, __gmp_binary_expr<__gmp_expr<T, T>, __gmp_expr<T, T>, Op> >
    2402  {
    2403  private:
    2404    typedef __gmp_expr<T, T> val1_type;
    2405    typedef __gmp_expr<T, T> val2_type;
    2406  
    2407    __gmp_binary_expr<val1_type, val2_type, Op> expr;
    2408  public:
    2409    __gmp_expr(const val1_type &val1, const val2_type &val2)
    2410      : expr(val1, val2) { }
    2411    void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
    2412    { Op::eval(p, expr.val1.__get_mp(), expr.val2.__get_mp()); }
    2413    const val1_type & get_val1() const { return expr.val1; }
    2414    const val2_type & get_val2() const { return expr.val2; }
    2415    mp_bitcnt_t get_prec() const
    2416    {
    2417      mp_bitcnt_t prec1 = expr.val1.get_prec(),
    2418        prec2 = expr.val2.get_prec();
    2419      return (prec1 > prec2) ? prec1 : prec2;
    2420    }
    2421  };
    2422  
    2423  
    2424  // simple expressions, U is a built-in numerical type
    2425  
    2426  template <class T, class U, class Op>
    2427  class __gmp_expr<T, __gmp_binary_expr<__gmp_expr<T, T>, U, Op> >
    2428  {
    2429  private:
    2430    typedef __gmp_expr<T, T> val1_type;
    2431    typedef U val2_type;
    2432  
    2433    __gmp_binary_expr<val1_type, val2_type, Op> expr;
    2434  public:
    2435    __gmp_expr(const val1_type &val1, const val2_type &val2)
    2436      : expr(val1, val2) { }
    2437    void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
    2438    { Op::eval(p, expr.val1.__get_mp(), expr.val2); }
    2439    const val1_type & get_val1() const { return expr.val1; }
    2440    const val2_type & get_val2() const { return expr.val2; }
    2441    mp_bitcnt_t get_prec() const { return expr.val1.get_prec(); }
    2442  };
    2443  
    2444  template <class T, class U, class Op>
    2445  class __gmp_expr<T, __gmp_binary_expr<U, __gmp_expr<T, T>, Op> >
    2446  {
    2447  private:
    2448    typedef U val1_type;
    2449    typedef __gmp_expr<T, T> val2_type;
    2450  
    2451    __gmp_binary_expr<val1_type, val2_type, Op> expr;
    2452  public:
    2453    __gmp_expr(const val1_type &val1, const val2_type &val2)
    2454      : expr(val1, val2) { }
    2455    void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
    2456    { Op::eval(p, expr.val1, expr.val2.__get_mp()); }
    2457    const val1_type & get_val1() const { return expr.val1; }
    2458    const val2_type & get_val2() const { return expr.val2; }
    2459    mp_bitcnt_t get_prec() const { return expr.val2.get_prec(); }
    2460  };
    2461  
    2462  
    2463  // compound expressions, one argument is a subexpression
    2464  
    2465  template <class T, class U, class V, class Op>
    2466  class __gmp_expr
    2467  <T, __gmp_binary_expr<__gmp_expr<T, T>, __gmp_expr<U, V>, Op> >
    2468  {
    2469  private:
    2470    typedef __gmp_expr<T, T> val1_type;
    2471    typedef __gmp_expr<U, V> val2_type;
    2472  
    2473    __gmp_binary_expr<val1_type, val2_type, Op> expr;
    2474  public:
    2475    __gmp_expr(const val1_type &val1, const val2_type &val2)
    2476      : expr(val1, val2) { }
    2477    void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
    2478    {
    2479      if(p != expr.val1.__get_mp())
    2480      {
    2481        __gmp_set_expr(p, expr.val2);
    2482        Op::eval(p, expr.val1.__get_mp(), p);
    2483      }
    2484      else
    2485      {
    2486        __gmp_temp<T> temp(expr.val2, p);
    2487        Op::eval(p, expr.val1.__get_mp(), temp.__get_mp());
    2488      }
    2489    }
    2490    const val1_type & get_val1() const { return expr.val1; }
    2491    const val2_type & get_val2() const { return expr.val2; }
    2492    mp_bitcnt_t get_prec() const
    2493    {
    2494      mp_bitcnt_t prec1 = expr.val1.get_prec(),
    2495        prec2 = expr.val2.get_prec();
    2496      return (prec1 > prec2) ? prec1 : prec2;
    2497    }
    2498  };
    2499  
    2500  template <class T, class U, class V, class Op>
    2501  class __gmp_expr
    2502  <T, __gmp_binary_expr<__gmp_expr<U, V>, __gmp_expr<T, T>, Op> >
    2503  {
    2504  private:
    2505    typedef __gmp_expr<U, V> val1_type;
    2506    typedef __gmp_expr<T, T> val2_type;
    2507  
    2508    __gmp_binary_expr<val1_type, val2_type, Op> expr;
    2509  public:
    2510    __gmp_expr(const val1_type &val1, const val2_type &val2)
    2511      : expr(val1, val2) { }
    2512    void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
    2513    {
    2514      if(p != expr.val2.__get_mp())
    2515      {
    2516        __gmp_set_expr(p, expr.val1);
    2517        Op::eval(p, p, expr.val2.__get_mp());
    2518      }
    2519      else
    2520      {
    2521        __gmp_temp<T> temp(expr.val1, p);
    2522        Op::eval(p, temp.__get_mp(), expr.val2.__get_mp());
    2523      }
    2524    }
    2525    const val1_type & get_val1() const { return expr.val1; }
    2526    const val2_type & get_val2() const { return expr.val2; }
    2527    mp_bitcnt_t get_prec() const
    2528    {
    2529      mp_bitcnt_t prec1 = expr.val1.get_prec(),
    2530        prec2 = expr.val2.get_prec();
    2531      return (prec1 > prec2) ? prec1 : prec2;
    2532    }
    2533  };
    2534  
    2535  template <class T, class U, class Op>
    2536  class __gmp_expr
    2537  <T, __gmp_binary_expr<__gmp_expr<T, T>, __gmp_expr<T, U>, Op> >
    2538  {
    2539  private:
    2540    typedef __gmp_expr<T, T> val1_type;
    2541    typedef __gmp_expr<T, U> val2_type;
    2542  
    2543    __gmp_binary_expr<val1_type, val2_type, Op> expr;
    2544  public:
    2545    __gmp_expr(const val1_type &val1, const val2_type &val2)
    2546      : expr(val1, val2) { }
    2547    void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
    2548    {
    2549      if(p != expr.val1.__get_mp())
    2550      {
    2551        __gmp_set_expr(p, expr.val2);
    2552        Op::eval(p, expr.val1.__get_mp(), p);
    2553      }
    2554      else
    2555      {
    2556        __gmp_temp<T> temp(expr.val2, p);
    2557        Op::eval(p, expr.val1.__get_mp(), temp.__get_mp());
    2558      }
    2559    }
    2560    const val1_type & get_val1() const { return expr.val1; }
    2561    const val2_type & get_val2() const { return expr.val2; }
    2562    mp_bitcnt_t get_prec() const
    2563    {
    2564      mp_bitcnt_t prec1 = expr.val1.get_prec(),
    2565        prec2 = expr.val2.get_prec();
    2566      return (prec1 > prec2) ? prec1 : prec2;
    2567    }
    2568  };
    2569  
    2570  template <class T, class U, class Op>
    2571  class __gmp_expr
    2572  <T, __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<T, T>, Op> >
    2573  {
    2574  private:
    2575    typedef __gmp_expr<T, U> val1_type;
    2576    typedef __gmp_expr<T, T> val2_type;
    2577  
    2578    __gmp_binary_expr<val1_type, val2_type, Op> expr;
    2579  public:
    2580    __gmp_expr(const val1_type &val1, const val2_type &val2)
    2581      : expr(val1, val2) { }
    2582    void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
    2583    {
    2584      if(p != expr.val2.__get_mp())
    2585      {
    2586        __gmp_set_expr(p, expr.val1);
    2587        Op::eval(p, p, expr.val2.__get_mp());
    2588      }
    2589      else
    2590      {
    2591        __gmp_temp<T> temp(expr.val1, p);
    2592        Op::eval(p, temp.__get_mp(), expr.val2.__get_mp());
    2593      }
    2594    }
    2595    const val1_type & get_val1() const { return expr.val1; }
    2596    const val2_type & get_val2() const { return expr.val2; }
    2597    mp_bitcnt_t get_prec() const
    2598    {
    2599      mp_bitcnt_t prec1 = expr.val1.get_prec(),
    2600        prec2 = expr.val2.get_prec();
    2601      return (prec1 > prec2) ? prec1 : prec2;
    2602    }
    2603  };
    2604  
    2605  
    2606  // one argument is a subexpression, one is a built-in
    2607  
    2608  template <class T, class U, class V, class Op>
    2609  class __gmp_expr<T, __gmp_binary_expr<__gmp_expr<T, U>, V, Op> >
    2610  {
    2611  private:
    2612    typedef __gmp_expr<T, U> val1_type;
    2613    typedef V val2_type;
    2614  
    2615    __gmp_binary_expr<val1_type, val2_type, Op> expr;
    2616  public:
    2617    __gmp_expr(const val1_type &val1, const val2_type &val2)
    2618      : expr(val1, val2) { }
    2619    void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
    2620    {
    2621      expr.val1.eval(p);
    2622      Op::eval(p, p, expr.val2);
    2623    }
    2624    const val1_type & get_val1() const { return expr.val1; }
    2625    const val2_type & get_val2() const { return expr.val2; }
    2626    mp_bitcnt_t get_prec() const { return expr.val1.get_prec(); }
    2627  };
    2628  
    2629  template <class T, class U, class V, class Op>
    2630  class __gmp_expr<T, __gmp_binary_expr<U, __gmp_expr<T, V>, Op> >
    2631  {
    2632  private:
    2633    typedef U val1_type;
    2634    typedef __gmp_expr<T, V> val2_type;
    2635  
    2636    __gmp_binary_expr<val1_type, val2_type, Op> expr;
    2637  public:
    2638    __gmp_expr(const val1_type &val1, const val2_type &val2)
    2639      : expr(val1, val2) { }
    2640    void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
    2641    {
    2642      expr.val2.eval(p);
    2643      Op::eval(p, expr.val1, p);
    2644    }
    2645    const val1_type & get_val1() const { return expr.val1; }
    2646    const val2_type & get_val2() const { return expr.val2; }
    2647    mp_bitcnt_t get_prec() const { return expr.val2.get_prec(); }
    2648  };
    2649  
    2650  
    2651  // both arguments are subexpressions
    2652  
    2653  template <class T, class U, class V, class W, class Op>
    2654  class __gmp_expr
    2655  <T, __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<V, W>, Op> >
    2656  {
    2657  private:
    2658    typedef __gmp_expr<T, U> val1_type;
    2659    typedef __gmp_expr<V, W> val2_type;
    2660  
    2661    __gmp_binary_expr<val1_type, val2_type, Op> expr;
    2662  public:
    2663    __gmp_expr(const val1_type &val1, const val2_type &val2)
    2664      : expr(val1, val2) { }
    2665    void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
    2666    {
    2667      __gmp_temp<T> temp2(expr.val2, p);
    2668      expr.val1.eval(p);
    2669      Op::eval(p, p, temp2.__get_mp());
    2670    }
    2671    const val1_type & get_val1() const { return expr.val1; }
    2672    const val2_type & get_val2() const { return expr.val2; }
    2673    mp_bitcnt_t get_prec() const
    2674    {
    2675      mp_bitcnt_t prec1 = expr.val1.get_prec(),
    2676        prec2 = expr.val2.get_prec();
    2677      return (prec1 > prec2) ? prec1 : prec2;
    2678    }
    2679  };
    2680  
    2681  template <class T, class U, class V, class W, class Op>
    2682  class __gmp_expr
    2683  <T, __gmp_binary_expr<__gmp_expr<U, V>, __gmp_expr<T, W>, Op> >
    2684  {
    2685  private:
    2686    typedef __gmp_expr<U, V> val1_type;
    2687    typedef __gmp_expr<T, W> val2_type;
    2688  
    2689    __gmp_binary_expr<val1_type, val2_type, Op> expr;
    2690  public:
    2691    __gmp_expr(const val1_type &val1, const val2_type &val2)
    2692      : expr(val1, val2) { }
    2693    void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
    2694    {
    2695      __gmp_temp<T> temp1(expr.val1, p);
    2696      expr.val2.eval(p);
    2697      Op::eval(p, temp1.__get_mp(), p);
    2698    }
    2699    const val1_type & get_val1() const { return expr.val1; }
    2700    const val2_type & get_val2() const { return expr.val2; }
    2701    mp_bitcnt_t get_prec() const
    2702    {
    2703      mp_bitcnt_t prec1 = expr.val1.get_prec(),
    2704        prec2 = expr.val2.get_prec();
    2705      return (prec1 > prec2) ? prec1 : prec2;
    2706    }
    2707  };
    2708  
    2709  template <class T, class U, class V, class Op>
    2710  class __gmp_expr
    2711  <T, __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<T, V>, Op> >
    2712  {
    2713  private:
    2714    typedef __gmp_expr<T, U> val1_type;
    2715    typedef __gmp_expr<T, V> val2_type;
    2716  
    2717    __gmp_binary_expr<val1_type, val2_type, Op> expr;
    2718  public:
    2719    __gmp_expr(const val1_type &val1, const val2_type &val2)
    2720      : expr(val1, val2) { }
    2721    void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
    2722    {
    2723      __gmp_temp<T> temp2(expr.val2, p);
    2724      expr.val1.eval(p);
    2725      Op::eval(p, p, temp2.__get_mp());
    2726    }
    2727    const val1_type & get_val1() const { return expr.val1; }
    2728    const val2_type & get_val2() const { return expr.val2; }
    2729    mp_bitcnt_t get_prec() const
    2730    {
    2731      mp_bitcnt_t prec1 = expr.val1.get_prec(),
    2732        prec2 = expr.val2.get_prec();
    2733      return (prec1 > prec2) ? prec1 : prec2;
    2734    }
    2735  };
    2736  
    2737  
    2738  /**************** Special cases ****************/
    2739  
    2740  /* Some operations (i.e., add and subtract) with mixed mpz/mpq arguments
    2741     can be done directly without first converting the mpz to mpq.
    2742     Appropriate specializations of __gmp_expr are required. */
    2743  
    2744  
    2745  #define __GMPZQ_DEFINE_EXPR(eval_fun)                                       \
    2746                                                                              \
    2747  template <>                                                                 \
    2748  class __gmp_expr<mpq_t, __gmp_binary_expr<mpz_class, mpq_class, eval_fun> > \
    2749  {                                                                           \
    2750  private:                                                                    \
    2751    typedef mpz_class val1_type;                                              \
    2752    typedef mpq_class val2_type;                                              \
    2753                                                                              \
    2754    __gmp_binary_expr<val1_type, val2_type, eval_fun> expr;                   \
    2755  public:                                                                     \
    2756    __gmp_expr(const val1_type &val1, const val2_type &val2)                  \
    2757      : expr(val1, val2) { }                                                  \
    2758    void eval(mpq_ptr q) const                                                \
    2759    { eval_fun::eval(q, expr.val1.get_mpz_t(), expr.val2.get_mpq_t()); }      \
    2760    const val1_type & get_val1() const { return expr.val1; }                  \
    2761    const val2_type & get_val2() const { return expr.val2; }                  \
    2762    mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); }           \
    2763  };                                                                          \
    2764                                                                              \
    2765  template <>                                                                 \
    2766  class __gmp_expr<mpq_t, __gmp_binary_expr<mpq_class, mpz_class, eval_fun> > \
    2767  {                                                                           \
    2768  private:                                                                    \
    2769    typedef mpq_class val1_type;                                              \
    2770    typedef mpz_class val2_type;                                              \
    2771                                                                              \
    2772    __gmp_binary_expr<val1_type, val2_type, eval_fun> expr;                   \
    2773  public:                                                                     \
    2774    __gmp_expr(const val1_type &val1, const val2_type &val2)                  \
    2775      : expr(val1, val2) { }                                                  \
    2776    void eval(mpq_ptr q) const                                                \
    2777    { eval_fun::eval(q, expr.val1.get_mpq_t(), expr.val2.get_mpz_t()); }      \
    2778    const val1_type & get_val1() const { return expr.val1; }                  \
    2779    const val2_type & get_val2() const { return expr.val2; }                  \
    2780    mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); }           \
    2781  };                                                                          \
    2782                                                                              \
    2783  template <class T>                                                          \
    2784  class __gmp_expr                                                            \
    2785  <mpq_t, __gmp_binary_expr<mpz_class, __gmp_expr<mpq_t, T>, eval_fun> >      \
    2786  {                                                                           \
    2787  private:                                                                    \
    2788    typedef mpz_class val1_type;                                              \
    2789    typedef __gmp_expr<mpq_t, T> val2_type;                                   \
    2790                                                                              \
    2791    __gmp_binary_expr<val1_type, val2_type, eval_fun> expr;                   \
    2792  public:                                                                     \
    2793    __gmp_expr(const val1_type &val1, const val2_type &val2)                  \
    2794      : expr(val1, val2) { }                                                  \
    2795    void eval(mpq_ptr q) const                                                \
    2796    {                                                                         \
    2797      mpq_class temp(expr.val2);                                              \
    2798      eval_fun::eval(q, expr.val1.get_mpz_t(), temp.get_mpq_t());             \
    2799    }                                                                         \
    2800    const val1_type & get_val1() const { return expr.val1; }                  \
    2801    const val2_type & get_val2() const { return expr.val2; }                  \
    2802    mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); }           \
    2803  };                                                                          \
    2804                                                                              \
    2805  template <class T>                                                          \
    2806  class __gmp_expr                                                            \
    2807  <mpq_t, __gmp_binary_expr<mpq_class, __gmp_expr<mpz_t, T>, eval_fun> >      \
    2808  {                                                                           \
    2809  private:                                                                    \
    2810    typedef mpq_class val1_type;                                              \
    2811    typedef __gmp_expr<mpz_t, T> val2_type;                                   \
    2812                                                                              \
    2813    __gmp_binary_expr<val1_type, val2_type, eval_fun> expr;                   \
    2814  public:                                                                     \
    2815    __gmp_expr(const val1_type &val1, const val2_type &val2)                  \
    2816      : expr(val1, val2) { }                                                  \
    2817    void eval(mpq_ptr q) const                                                \
    2818    {                                                                         \
    2819      mpz_class temp(expr.val2);                                              \
    2820      eval_fun::eval(q, expr.val1.get_mpq_t(), temp.get_mpz_t());             \
    2821    }                                                                         \
    2822    const val1_type & get_val1() const { return expr.val1; }                  \
    2823    const val2_type & get_val2() const { return expr.val2; }                  \
    2824    mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); }           \
    2825  };                                                                          \
    2826                                                                              \
    2827  template <class T>                                                          \
    2828  class __gmp_expr                                                            \
    2829  <mpq_t, __gmp_binary_expr<__gmp_expr<mpz_t, T>, mpq_class, eval_fun> >      \
    2830  {                                                                           \
    2831  private:                                                                    \
    2832    typedef __gmp_expr<mpz_t, T> val1_type;                                   \
    2833    typedef mpq_class val2_type;                                              \
    2834                                                                              \
    2835    __gmp_binary_expr<val1_type, val2_type, eval_fun> expr;                   \
    2836  public:                                                                     \
    2837    __gmp_expr(const val1_type &val1, const val2_type &val2)                  \
    2838      : expr(val1, val2) { }                                                  \
    2839    void eval(mpq_ptr q) const                                                \
    2840    {                                                                         \
    2841      mpz_class temp(expr.val1);                                              \
    2842      eval_fun::eval(q, temp.get_mpz_t(), expr.val2.get_mpq_t());             \
    2843    }                                                                         \
    2844    const val1_type & get_val1() const { return expr.val1; }                  \
    2845    const val2_type & get_val2() const { return expr.val2; }                  \
    2846    mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); }           \
    2847  };                                                                          \
    2848                                                                              \
    2849  template <class T>                                                          \
    2850  class __gmp_expr                                                            \
    2851  <mpq_t, __gmp_binary_expr<__gmp_expr<mpq_t, T>, mpz_class, eval_fun> >      \
    2852  {                                                                           \
    2853  private:                                                                    \
    2854    typedef __gmp_expr<mpq_t, T> val1_type;                                   \
    2855    typedef mpz_class val2_type;                                              \
    2856                                                                              \
    2857    __gmp_binary_expr<val1_type, val2_type, eval_fun> expr;                   \
    2858  public:                                                                     \
    2859    __gmp_expr(const val1_type &val1, const val2_type &val2)                  \
    2860      : expr(val1, val2) { }                                                  \
    2861    void eval(mpq_ptr q) const                                                \
    2862    {                                                                         \
    2863      mpq_class temp(expr.val1);                                              \
    2864      eval_fun::eval(q, temp.get_mpq_t(), expr.val2.get_mpz_t());             \
    2865    }                                                                         \
    2866    const val1_type & get_val1() const { return expr.val1; }                  \
    2867    const val2_type & get_val2() const { return expr.val2; }                  \
    2868    mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); }           \
    2869  };                                                                          \
    2870                                                                              \
    2871  template <class T, class U>                                                 \
    2872  class __gmp_expr<mpq_t, __gmp_binary_expr                                   \
    2873  <__gmp_expr<mpz_t, T>, __gmp_expr<mpq_t, U>, eval_fun> >                    \
    2874  {                                                                           \
    2875  private:                                                                    \
    2876    typedef __gmp_expr<mpz_t, T> val1_type;                                   \
    2877    typedef __gmp_expr<mpq_t, U> val2_type;                                   \
    2878                                                                              \
    2879    __gmp_binary_expr<val1_type, val2_type, eval_fun> expr;                   \
    2880  public:                                                                     \
    2881    __gmp_expr(const val1_type &val1, const val2_type &val2)                  \
    2882      : expr(val1, val2) { }                                                  \
    2883    void eval(mpq_ptr q) const                                                \
    2884    {                                                                         \
    2885      mpz_class temp1(expr.val1);                                             \
    2886      expr.val2.eval(q);                                                      \
    2887      eval_fun::eval(q, temp1.get_mpz_t(), q);                                \
    2888    }                                                                         \
    2889    const val1_type & get_val1() const { return expr.val1; }                  \
    2890    const val2_type & get_val2() const { return expr.val2; }                  \
    2891    mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); }           \
    2892  };                                                                          \
    2893                                                                              \
    2894  template <class T, class U>                                                 \
    2895  class __gmp_expr<mpq_t, __gmp_binary_expr                                   \
    2896  <__gmp_expr<mpq_t, T>, __gmp_expr<mpz_t, U>, eval_fun> >                    \
    2897  {                                                                           \
    2898  private:                                                                    \
    2899    typedef __gmp_expr<mpq_t, T> val1_type;                                   \
    2900    typedef __gmp_expr<mpz_t, U> val2_type;                                   \
    2901                                                                              \
    2902    __gmp_binary_expr<val1_type, val2_type, eval_fun> expr;                   \
    2903  public:                                                                     \
    2904    __gmp_expr(const val1_type &val1, const val2_type &val2)                  \
    2905      : expr(val1, val2) { }                                                  \
    2906    void eval(mpq_ptr q) const                                                \
    2907    {                                                                         \
    2908      mpz_class temp2(expr.val2);                                             \
    2909      expr.val1.eval(q);                                             \
    2910      eval_fun::eval(q, q, temp2.get_mpz_t());                \
    2911    }                                                                         \
    2912    const val1_type & get_val1() const { return expr.val1; }                  \
    2913    const val2_type & get_val2() const { return expr.val2; }                  \
    2914    mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); }           \
    2915  };
    2916  
    2917  
    2918  __GMPZQ_DEFINE_EXPR(__gmp_binary_plus)
    2919  __GMPZQ_DEFINE_EXPR(__gmp_binary_minus)
    2920  
    2921  
    2922  
    2923  /**************** Macros for defining functions ****************/
    2924  /* Results of operators and functions are instances of __gmp_expr<T, U>.
    2925     T determines the numerical type of the expression: it can be either
    2926     mpz_t, mpq_t, or mpf_t.  When the arguments of a binary
    2927     expression have different numerical types, __gmp_resolve_expr is used
    2928     to determine the "larger" type.
    2929     U is either __gmp_unary_expr<V, Op> or __gmp_binary_expr<V, W, Op>,
    2930     where V and W are the arguments' types -- they can in turn be
    2931     expressions, thus allowing to build compound expressions to any
    2932     degree of complexity.
    2933     Op is a function object that must have an eval() method accepting
    2934     appropriate arguments.
    2935     Actual evaluation of a __gmp_expr<T, U> object is done when it gets
    2936     assigned to an mp*_class ("lazy" evaluation): this is done by calling
    2937     its eval() method. */
    2938  
    2939  
    2940  // non-member unary operators and functions
    2941  
    2942  #define __GMP_DEFINE_UNARY_FUNCTION(fun, eval_fun)                           \
    2943                                                                               \
    2944  template <class T, class U>                                                  \
    2945  inline __gmp_expr<T, __gmp_unary_expr<__gmp_expr<T, U>, eval_fun> >          \
    2946  fun(const __gmp_expr<T, U> &expr)                                            \
    2947  {                                                                            \
    2948    return __gmp_expr<T, __gmp_unary_expr<__gmp_expr<T, U>, eval_fun> >(expr); \
    2949  }
    2950  
    2951  // variant that only works for one of { mpz, mpq, mpf }
    2952  
    2953  #define __GMP_DEFINE_UNARY_FUNCTION_1(T, fun, eval_fun)                      \
    2954                                                                               \
    2955  template <class U>                                                           \
    2956  inline __gmp_expr<T, __gmp_unary_expr<__gmp_expr<T, U>, eval_fun> >          \
    2957  fun(const __gmp_expr<T, U> &expr)                                            \
    2958  {                                                                            \
    2959    return __gmp_expr<T, __gmp_unary_expr<__gmp_expr<T, U>, eval_fun> >(expr); \
    2960  }
    2961  
    2962  #define __GMP_DEFINE_UNARY_TYPE_FUNCTION(type, fun, eval_fun) \
    2963                                                                \
    2964  template <class T, class U>                                   \
    2965  inline type fun(const __gmp_expr<T, U> &expr)                 \
    2966  {                                                             \
    2967    __gmp_expr<T, T> const& temp(expr); \
    2968    return eval_fun::eval(temp.__get_mp());                     \
    2969  }
    2970  
    2971  
    2972  // non-member binary operators and functions
    2973  
    2974  #define __GMPP_DEFINE_BINARY_FUNCTION(fun, eval_fun)                   \
    2975                                                                         \
    2976  template <class T, class U, class V, class W>                          \
    2977  inline __gmp_expr<typename __gmp_resolve_expr<T, V>::value_type,       \
    2978  __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<V, W>, eval_fun> >      \
    2979  fun(const __gmp_expr<T, U> &expr1, const __gmp_expr<V, W> &expr2)      \
    2980  {                                                                      \
    2981    return __gmp_expr<typename __gmp_resolve_expr<T, V>::value_type,     \
    2982       __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<V, W>, eval_fun> > \
    2983      (expr1, expr2);                                                    \
    2984  }
    2985  
    2986  #define __GMPNN_DEFINE_BINARY_FUNCTION(fun, eval_fun, type, bigtype)       \
    2987                                                                             \
    2988  template <class T, class U>                                                \
    2989  inline __gmp_expr                                                          \
    2990  <T, __gmp_binary_expr<__gmp_expr<T, U>, bigtype, eval_fun> >               \
    2991  fun(const __gmp_expr<T, U> &expr, type t)                                  \
    2992  {                                                                          \
    2993    return __gmp_expr                                                        \
    2994      <T, __gmp_binary_expr<__gmp_expr<T, U>, bigtype, eval_fun> >(expr, t); \
    2995  }                                                                          \
    2996                                                                             \
    2997  template <class T, class U>                                                \
    2998  inline __gmp_expr                                                          \
    2999  <T, __gmp_binary_expr<bigtype, __gmp_expr<T, U>, eval_fun> >               \
    3000  fun(type t, const __gmp_expr<T, U> &expr)                                  \
    3001  {                                                                          \
    3002    return __gmp_expr                                                        \
    3003      <T, __gmp_binary_expr<bigtype, __gmp_expr<T, U>, eval_fun> >(t, expr); \
    3004  }
    3005  
    3006  #define __GMPNS_DEFINE_BINARY_FUNCTION(fun, eval_fun, type)          \
    3007  __GMPNN_DEFINE_BINARY_FUNCTION(fun, eval_fun, type, signed long int)
    3008  
    3009  #define __GMPNU_DEFINE_BINARY_FUNCTION(fun, eval_fun, type)            \
    3010  __GMPNN_DEFINE_BINARY_FUNCTION(fun, eval_fun, type, unsigned long int)
    3011  
    3012  #define __GMPND_DEFINE_BINARY_FUNCTION(fun, eval_fun, type) \
    3013  __GMPNN_DEFINE_BINARY_FUNCTION(fun, eval_fun, type, double)
    3014  
    3015  #define __GMPNLD_DEFINE_BINARY_FUNCTION(fun, eval_fun, type)     \
    3016  __GMPNN_DEFINE_BINARY_FUNCTION(fun, eval_fun, type, long double)
    3017  
    3018  #define __GMPN_DEFINE_BINARY_FUNCTION(fun, eval_fun)              \
    3019  __GMPNS_DEFINE_BINARY_FUNCTION(fun, eval_fun, signed char)        \
    3020  __GMPNU_DEFINE_BINARY_FUNCTION(fun, eval_fun, unsigned char)      \
    3021  __GMPNS_DEFINE_BINARY_FUNCTION(fun, eval_fun, signed int)         \
    3022  __GMPNU_DEFINE_BINARY_FUNCTION(fun, eval_fun, unsigned int)       \
    3023  __GMPNS_DEFINE_BINARY_FUNCTION(fun, eval_fun, signed short int)   \
    3024  __GMPNU_DEFINE_BINARY_FUNCTION(fun, eval_fun, unsigned short int) \
    3025  __GMPNS_DEFINE_BINARY_FUNCTION(fun, eval_fun, signed long int)    \
    3026  __GMPNU_DEFINE_BINARY_FUNCTION(fun, eval_fun, unsigned long int)  \
    3027  __GMPND_DEFINE_BINARY_FUNCTION(fun, eval_fun, float)              \
    3028  __GMPND_DEFINE_BINARY_FUNCTION(fun, eval_fun, double)             \
    3029  /* __GMPNLD_DEFINE_BINARY_FUNCTION(fun, eval_fun, long double) */
    3030  
    3031  #define __GMP_DEFINE_BINARY_FUNCTION(fun, eval_fun) \
    3032  __GMPP_DEFINE_BINARY_FUNCTION(fun, eval_fun)        \
    3033  __GMPN_DEFINE_BINARY_FUNCTION(fun, eval_fun)
    3034  
    3035  // variant that only works for one of { mpz, mpq, mpf }
    3036  
    3037  #define __GMPP_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun)              \
    3038                                                                         \
    3039  template <class U, class W>                                            \
    3040  inline __gmp_expr<T,                                                   \
    3041  __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<T, W>, eval_fun> >      \
    3042  fun(const __gmp_expr<T, U> &expr1, const __gmp_expr<T, W> &expr2)      \
    3043  {                                                                      \
    3044    return __gmp_expr<T,                                                 \
    3045       __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<T, W>, eval_fun> > \
    3046      (expr1, expr2);                                                    \
    3047  }
    3048  
    3049  #define __GMPNN_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, type, bigtype)  \
    3050                                                                             \
    3051  template <class U>                                                         \
    3052  inline __gmp_expr                                                          \
    3053  <T, __gmp_binary_expr<__gmp_expr<T, U>, bigtype, eval_fun> >               \
    3054  fun(const __gmp_expr<T, U> &expr, type t)                                  \
    3055  {                                                                          \
    3056    return __gmp_expr                                                        \
    3057      <T, __gmp_binary_expr<__gmp_expr<T, U>, bigtype, eval_fun> >(expr, t); \
    3058  }                                                                          \
    3059                                                                             \
    3060  template <class U>                                                         \
    3061  inline __gmp_expr                                                          \
    3062  <T, __gmp_binary_expr<bigtype, __gmp_expr<T, U>, eval_fun> >               \
    3063  fun(type t, const __gmp_expr<T, U> &expr)                                  \
    3064  {                                                                          \
    3065    return __gmp_expr                                                        \
    3066      <T, __gmp_binary_expr<bigtype, __gmp_expr<T, U>, eval_fun> >(t, expr); \
    3067  }
    3068  
    3069  #define __GMPNS_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, type)          \
    3070  __GMPNN_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, type, signed long int)
    3071  
    3072  #define __GMPNU_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, type)          \
    3073  __GMPNN_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, type, unsigned long int)
    3074  
    3075  #define __GMPND_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, type) \
    3076  __GMPNN_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, type, double)
    3077  
    3078  #define __GMPNLD_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, type)     \
    3079  __GMPNN_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, type, long double)
    3080  
    3081  #define __GMPN_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun)              \
    3082  __GMPNS_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, signed char)        \
    3083  __GMPNU_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, unsigned char)      \
    3084  __GMPNS_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, signed int)         \
    3085  __GMPNU_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, unsigned int)       \
    3086  __GMPNS_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, signed short int)   \
    3087  __GMPNU_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, unsigned short int) \
    3088  __GMPNS_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, signed long int)    \
    3089  __GMPNU_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, unsigned long int)  \
    3090  __GMPND_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, float)              \
    3091  __GMPND_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, double)             \
    3092  /* __GMPNLD_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, long double) */
    3093  
    3094  #define __GMP_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun) \
    3095  __GMPP_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun)        \
    3096  __GMPN_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun)
    3097  
    3098  
    3099  #define __GMP_DEFINE_BINARY_FUNCTION_UI(fun, eval_fun)                 \
    3100                                                                         \
    3101  template <class T, class U>                                            \
    3102  inline __gmp_expr                                                      \
    3103  <T, __gmp_binary_expr<__gmp_expr<T, U>, mp_bitcnt_t, eval_fun> > \
    3104  fun(const __gmp_expr<T, U> &expr, mp_bitcnt_t l)                 \
    3105  {                                                                      \
    3106    return __gmp_expr<T, __gmp_binary_expr                               \
    3107      <__gmp_expr<T, U>, mp_bitcnt_t, eval_fun> >(expr, l);        \
    3108  }
    3109  
    3110  
    3111  #define __GMPP_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun)         \
    3112                                                                          \
    3113  template <class T, class U, class V, class W>                           \
    3114  inline type fun(const __gmp_expr<T, U> &expr1,                          \
    3115  		const __gmp_expr<V, W> &expr2)                          \
    3116  {                                                                       \
    3117    __gmp_expr<T, T> const& temp1(expr1);                                 \
    3118    __gmp_expr<V, V> const& temp2(expr2);                                 \
    3119    return eval_fun::eval(temp1.__get_mp(), temp2.__get_mp());            \
    3120  }
    3121  
    3122  #define __GMPNN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun,   \
    3123  					    type2, bigtype)        \
    3124                                                                     \
    3125  template <class T, class U>                                        \
    3126  inline type fun(const __gmp_expr<T, U> &expr, type2 t)             \
    3127  {                                                                  \
    3128    __gmp_expr<T, T> const& temp(expr);      \
    3129    return eval_fun::eval(temp.__get_mp(), static_cast<bigtype>(t)); \
    3130  }                                                                  \
    3131                                                                     \
    3132  template <class T, class U>                                        \
    3133  inline type fun(type2 t, const __gmp_expr<T, U> &expr)             \
    3134  {                                                                  \
    3135    __gmp_expr<T, T> const& temp(expr);      \
    3136    return eval_fun::eval(static_cast<bigtype>(t), temp.__get_mp()); \
    3137  }
    3138  
    3139  #define __GMPNS_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, type2) \
    3140  __GMPNN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun,                \
    3141  				    type2, signed long int)
    3142  
    3143  #define __GMPNU_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, type2) \
    3144  __GMPNN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun,                \
    3145  				    type2, unsigned long int)
    3146  
    3147  #define __GMPND_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, type2) \
    3148  __GMPNN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, type2, double)
    3149  
    3150  #define __GMPNLD_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, type2)     \
    3151  __GMPNN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, type2, long double)
    3152  
    3153  #define __GMPN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun)              \
    3154  __GMPNS_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, signed char)        \
    3155  __GMPNU_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, unsigned char)      \
    3156  __GMPNS_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, signed int)         \
    3157  __GMPNU_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, unsigned int)       \
    3158  __GMPNS_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, signed short int)   \
    3159  __GMPNU_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, unsigned short int) \
    3160  __GMPNS_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, signed long int)    \
    3161  __GMPNU_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, unsigned long int)  \
    3162  __GMPND_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, float)              \
    3163  __GMPND_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, double)             \
    3164  /* __GMPNLD_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, long double) */
    3165  
    3166  #define __GMP_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun) \
    3167  __GMPP_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun)        \
    3168  __GMPN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun)
    3169  
    3170  
    3171  // member operators
    3172  
    3173  #define __GMPP_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun)                 \
    3174                                                                               \
    3175  template <class T, class U>                                                  \
    3176  inline type##_class & type##_class::fun(const __gmp_expr<T, U> &expr)        \
    3177  {                                                                            \
    3178    __gmp_set_expr(mp, __gmp_expr<type##_t, __gmp_binary_expr                  \
    3179  		 <type##_class, __gmp_expr<T, U>, eval_fun> >(*this, expr)); \
    3180    return *this;                                                              \
    3181  }
    3182  
    3183  #define __GMPNN_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun,    \
    3184  					 type2, bigtype)         \
    3185                                                                   \
    3186  inline type##_class & type##_class::fun(type2 t)                 \
    3187  {                                                                \
    3188    __gmp_set_expr(mp, __gmp_expr<type##_t, __gmp_binary_expr      \
    3189  		 <type##_class, bigtype, eval_fun> >(*this, t)); \
    3190    return *this;                                                  \
    3191  }
    3192  
    3193  #define __GMPNS_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, type2) \
    3194  __GMPNN_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun,                \
    3195  				 type2, signed long int)
    3196  
    3197  #define __GMPNU_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, type2) \
    3198  __GMPNN_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun,                \
    3199  				 type2, unsigned long int)
    3200  
    3201  #define __GMPND_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, type2) \
    3202  __GMPNN_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, type2, double)
    3203  
    3204  #define __GMPNLD_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, type2)     \
    3205  __GMPNN_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, type2, long double)
    3206  
    3207  #define __GMPN_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun)              \
    3208  __GMPNS_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, signed char)        \
    3209  __GMPNU_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, unsigned char)      \
    3210  __GMPNS_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, signed int)         \
    3211  __GMPNU_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, unsigned int)       \
    3212  __GMPNS_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, signed short int)   \
    3213  __GMPNU_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, unsigned short int) \
    3214  __GMPNS_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, signed long int)    \
    3215  __GMPNU_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, unsigned long int)  \
    3216  __GMPND_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, float)              \
    3217  __GMPND_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, double)             \
    3218  /* __GMPNLD_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, long double) */
    3219  
    3220  #define __GMP_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun) \
    3221  __GMPP_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun)        \
    3222  __GMPN_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun)
    3223  
    3224  #define __GMPZ_DEFINE_COMPOUND_OPERATOR(fun, eval_fun) \
    3225  __GMP_DEFINE_COMPOUND_OPERATOR(mpz, fun, eval_fun)
    3226  
    3227  #define __GMPQ_DEFINE_COMPOUND_OPERATOR(fun, eval_fun) \
    3228  __GMP_DEFINE_COMPOUND_OPERATOR(mpq, fun, eval_fun)
    3229  
    3230  #define __GMPF_DEFINE_COMPOUND_OPERATOR(fun, eval_fun) \
    3231  __GMP_DEFINE_COMPOUND_OPERATOR(mpf, fun, eval_fun)
    3232  
    3233  
    3234  
    3235  #define __GMP_DEFINE_COMPOUND_OPERATOR_UI(type, fun, eval_fun)  \
    3236                                                                  \
    3237  inline type##_class & type##_class::fun(mp_bitcnt_t l)    \
    3238  {                                                               \
    3239    __gmp_set_expr(mp, __gmp_expr<type##_t, __gmp_binary_expr     \
    3240      <type##_class, mp_bitcnt_t, eval_fun> >(*this, l));   \
    3241    return *this;                                                 \
    3242  }
    3243  
    3244  #define __GMPZ_DEFINE_COMPOUND_OPERATOR_UI(fun, eval_fun) \
    3245  __GMP_DEFINE_COMPOUND_OPERATOR_UI(mpz, fun, eval_fun)
    3246  
    3247  #define __GMPQ_DEFINE_COMPOUND_OPERATOR_UI(fun, eval_fun) \
    3248  __GMP_DEFINE_COMPOUND_OPERATOR_UI(mpq, fun, eval_fun)
    3249  
    3250  #define __GMPF_DEFINE_COMPOUND_OPERATOR_UI(fun, eval_fun) \
    3251  __GMP_DEFINE_COMPOUND_OPERATOR_UI(mpf, fun, eval_fun)
    3252  
    3253  
    3254  
    3255  #define __GMP_DEFINE_INCREMENT_OPERATOR(type, fun, eval_fun) \
    3256                                                               \
    3257  inline type##_class & type##_class::fun()                    \
    3258  {                                                            \
    3259    eval_fun::eval(mp);                                        \
    3260    return *this;                                              \
    3261  }                                                            \
    3262                                                               \
    3263  inline type##_class type##_class::fun(int)                   \
    3264  {                                                            \
    3265    type##_class temp(*this);                                  \
    3266    eval_fun::eval(mp);                                        \
    3267    return temp;                                               \
    3268  }
    3269  
    3270  #define __GMPZ_DEFINE_INCREMENT_OPERATOR(fun, eval_fun) \
    3271  __GMP_DEFINE_INCREMENT_OPERATOR(mpz, fun, eval_fun)
    3272  
    3273  #define __GMPQ_DEFINE_INCREMENT_OPERATOR(fun, eval_fun) \
    3274  __GMP_DEFINE_INCREMENT_OPERATOR(mpq, fun, eval_fun)
    3275  
    3276  #define __GMPF_DEFINE_INCREMENT_OPERATOR(fun, eval_fun) \
    3277  __GMP_DEFINE_INCREMENT_OPERATOR(mpf, fun, eval_fun)
    3278  
    3279  
    3280  #define __GMPP_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun)                  \
    3281  template <class U>                                                           \
    3282  __gmp_expr<T, __gmp_unary_expr<__gmp_expr<T, U>, eval_fun> >          \
    3283  fun(const __gmp_expr<T, U> &expr)                                            \
    3284  {                                                                            \
    3285    return __gmp_expr<T, __gmp_unary_expr<__gmp_expr<T, U>, eval_fun> >(expr); \
    3286  }
    3287  
    3288  #define __GMPNN_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, type, bigtype)  \
    3289  inline __gmp_expr<T, __gmp_unary_expr<bigtype, eval_fun> >                   \
    3290  fun(type expr)                                                               \
    3291  {                                                                            \
    3292    return __gmp_expr<T, __gmp_unary_expr<bigtype, eval_fun> >(expr);          \
    3293  }
    3294  
    3295  #define __GMPNS_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, type)  \
    3296  __GMPNN_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, type, signed long)
    3297  #define __GMPNU_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, type)  \
    3298  __GMPNN_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, type, unsigned long)
    3299  #define __GMPND_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, type)  \
    3300  __GMPNN_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, type, double)
    3301  
    3302  #define __GMPN_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun)                 \
    3303  __GMPNS_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, signed char)           \
    3304  __GMPNU_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, unsigned char)         \
    3305  __GMPNS_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, signed int)            \
    3306  __GMPNU_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, unsigned int)          \
    3307  __GMPNS_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, signed short int)      \
    3308  __GMPNU_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, unsigned short int)    \
    3309  __GMPNS_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, signed long int)       \
    3310  __GMPNU_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, unsigned long int)     \
    3311  __GMPND_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, float)                 \
    3312  __GMPND_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, double)                \
    3313  
    3314  #define __GMP_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun)                  \
    3315  __GMPP_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun)                         \
    3316  __GMPN_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun)                         \
    3317  
    3318  
    3319  /**************** Arithmetic operators and functions ****************/
    3320  
    3321  // non-member operators and functions
    3322  
    3323  __GMP_DEFINE_UNARY_FUNCTION(operator+, __gmp_unary_plus)
    3324  __GMP_DEFINE_UNARY_FUNCTION(operator-, __gmp_unary_minus)
    3325  __GMP_DEFINE_UNARY_FUNCTION_1(mpz_t, operator~, __gmp_unary_com)
    3326  
    3327  __GMP_DEFINE_BINARY_FUNCTION(operator+, __gmp_binary_plus)
    3328  __GMP_DEFINE_BINARY_FUNCTION(operator-, __gmp_binary_minus)
    3329  __GMP_DEFINE_BINARY_FUNCTION(operator*, __gmp_binary_multiplies)
    3330  __GMP_DEFINE_BINARY_FUNCTION(operator/, __gmp_binary_divides)
    3331  __GMP_DEFINE_BINARY_FUNCTION_1(mpz_t, operator%, __gmp_binary_modulus)
    3332  __GMP_DEFINE_BINARY_FUNCTION_1(mpz_t, operator&, __gmp_binary_and)
    3333  __GMP_DEFINE_BINARY_FUNCTION_1(mpz_t, operator|, __gmp_binary_ior)
    3334  __GMP_DEFINE_BINARY_FUNCTION_1(mpz_t, operator^, __gmp_binary_xor)
    3335  
    3336  __GMP_DEFINE_BINARY_FUNCTION_UI(operator<<, __gmp_binary_lshift)
    3337  __GMP_DEFINE_BINARY_FUNCTION_UI(operator>>, __gmp_binary_rshift)
    3338  
    3339  __GMP_DEFINE_BINARY_TYPE_FUNCTION(bool, operator==, __gmp_binary_equal)
    3340  __GMP_DEFINE_BINARY_TYPE_FUNCTION(bool, operator!=, ! __gmp_binary_equal)
    3341  __GMP_DEFINE_BINARY_TYPE_FUNCTION(bool, operator<, __gmp_binary_less)
    3342  __GMP_DEFINE_BINARY_TYPE_FUNCTION(bool, operator<=, ! __gmp_binary_greater)
    3343  __GMP_DEFINE_BINARY_TYPE_FUNCTION(bool, operator>, __gmp_binary_greater)
    3344  __GMP_DEFINE_BINARY_TYPE_FUNCTION(bool, operator>=, ! __gmp_binary_less)
    3345  
    3346  __GMP_DEFINE_UNARY_FUNCTION(abs, __gmp_abs_function)
    3347  __GMP_DEFINE_UNARY_FUNCTION_1(mpf_t, trunc, __gmp_trunc_function)
    3348  __GMP_DEFINE_UNARY_FUNCTION_1(mpf_t, floor, __gmp_floor_function)
    3349  __GMP_DEFINE_UNARY_FUNCTION_1(mpf_t, ceil, __gmp_ceil_function)
    3350  __GMP_DEFINE_UNARY_FUNCTION_1(mpf_t, sqrt, __gmp_sqrt_function)
    3351  __GMP_DEFINE_UNARY_FUNCTION_1(mpz_t, sqrt, __gmp_sqrt_function)
    3352  __GMP_DEFINE_UNARY_FUNCTION_1(mpz_t, factorial, __gmp_fac_function)
    3353  __GMP_DEFINE_UNARY_FUNCTION_1(mpz_t, primorial, __gmp_primorial_function)
    3354  __GMP_DEFINE_UNARY_FUNCTION_1(mpz_t, fibonacci, __gmp_fib_function)
    3355  __GMP_DEFINE_BINARY_FUNCTION_1(mpf_t, hypot, __gmp_hypot_function)
    3356  __GMP_DEFINE_BINARY_FUNCTION_1(mpz_t, gcd, __gmp_gcd_function)
    3357  __GMP_DEFINE_BINARY_FUNCTION_1(mpz_t, lcm, __gmp_lcm_function)
    3358  
    3359  __GMP_DEFINE_UNARY_TYPE_FUNCTION(int, sgn, __gmp_sgn_function)
    3360  __GMP_DEFINE_BINARY_TYPE_FUNCTION(int, cmp, __gmp_cmp_function)
    3361  
    3362  template <class T>
    3363  void swap(__gmp_expr<T, T>& x, __gmp_expr<T, T>& y) __GMPXX_NOEXCEPT
    3364  { x.swap(y); }
    3365  
    3366  // member operators for mpz_class
    3367  
    3368  __GMPZ_DEFINE_COMPOUND_OPERATOR(operator+=, __gmp_binary_plus)
    3369  __GMPZ_DEFINE_COMPOUND_OPERATOR(operator-=, __gmp_binary_minus)
    3370  __GMPZ_DEFINE_COMPOUND_OPERATOR(operator*=, __gmp_binary_multiplies)
    3371  __GMPZ_DEFINE_COMPOUND_OPERATOR(operator/=, __gmp_binary_divides)
    3372  __GMPZ_DEFINE_COMPOUND_OPERATOR(operator%=, __gmp_binary_modulus)
    3373  
    3374  __GMPZ_DEFINE_COMPOUND_OPERATOR(operator&=, __gmp_binary_and)
    3375  __GMPZ_DEFINE_COMPOUND_OPERATOR(operator|=, __gmp_binary_ior)
    3376  __GMPZ_DEFINE_COMPOUND_OPERATOR(operator^=, __gmp_binary_xor)
    3377  
    3378  __GMPZ_DEFINE_COMPOUND_OPERATOR_UI(operator<<=, __gmp_binary_lshift)
    3379  __GMPZ_DEFINE_COMPOUND_OPERATOR_UI(operator>>=, __gmp_binary_rshift)
    3380  
    3381  __GMPZ_DEFINE_INCREMENT_OPERATOR(operator++, __gmp_unary_increment)
    3382  __GMPZ_DEFINE_INCREMENT_OPERATOR(operator--, __gmp_unary_decrement)
    3383  
    3384  __GMP_DEFINE_UNARY_STATIC_MEMFUN(mpz_t, mpz_class::factorial, __gmp_fac_function)
    3385  __GMP_DEFINE_UNARY_STATIC_MEMFUN(mpz_t, mpz_class::primorial, __gmp_primorial_function)
    3386  __GMP_DEFINE_UNARY_STATIC_MEMFUN(mpz_t, mpz_class::fibonacci, __gmp_fib_function)
    3387  
    3388  // member operators for mpq_class
    3389  
    3390  __GMPQ_DEFINE_COMPOUND_OPERATOR(operator+=, __gmp_binary_plus)
    3391  __GMPQ_DEFINE_COMPOUND_OPERATOR(operator-=, __gmp_binary_minus)
    3392  __GMPQ_DEFINE_COMPOUND_OPERATOR(operator*=, __gmp_binary_multiplies)
    3393  __GMPQ_DEFINE_COMPOUND_OPERATOR(operator/=, __gmp_binary_divides)
    3394  
    3395  __GMPQ_DEFINE_COMPOUND_OPERATOR_UI(operator<<=, __gmp_binary_lshift)
    3396  __GMPQ_DEFINE_COMPOUND_OPERATOR_UI(operator>>=, __gmp_binary_rshift)
    3397  
    3398  __GMPQ_DEFINE_INCREMENT_OPERATOR(operator++, __gmp_unary_increment)
    3399  __GMPQ_DEFINE_INCREMENT_OPERATOR(operator--, __gmp_unary_decrement)
    3400  
    3401  // member operators for mpf_class
    3402  
    3403  __GMPF_DEFINE_COMPOUND_OPERATOR(operator+=, __gmp_binary_plus)
    3404  __GMPF_DEFINE_COMPOUND_OPERATOR(operator-=, __gmp_binary_minus)
    3405  __GMPF_DEFINE_COMPOUND_OPERATOR(operator*=, __gmp_binary_multiplies)
    3406  __GMPF_DEFINE_COMPOUND_OPERATOR(operator/=, __gmp_binary_divides)
    3407  
    3408  __GMPF_DEFINE_COMPOUND_OPERATOR_UI(operator<<=, __gmp_binary_lshift)
    3409  __GMPF_DEFINE_COMPOUND_OPERATOR_UI(operator>>=, __gmp_binary_rshift)
    3410  
    3411  __GMPF_DEFINE_INCREMENT_OPERATOR(operator++, __gmp_unary_increment)
    3412  __GMPF_DEFINE_INCREMENT_OPERATOR(operator--, __gmp_unary_decrement)
    3413  
    3414  
    3415  
    3416  /**************** Class wrapper for gmp_randstate_t ****************/
    3417  
    3418  class __gmp_urandomb_value { };
    3419  class __gmp_urandomm_value { };
    3420  
    3421  template <>
    3422  class __gmp_expr<mpz_t, __gmp_urandomb_value>
    3423  {
    3424  private:
    3425    __gmp_randstate_struct *state;
    3426    mp_bitcnt_t bits;
    3427  public:
    3428    __gmp_expr(gmp_randstate_t s, mp_bitcnt_t l) : state(s), bits(l) { }
    3429    void eval(mpz_ptr z) const { __gmp_rand_function::eval(z, state, bits); }
    3430    mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); }
    3431  };
    3432  
    3433  template <>
    3434  class __gmp_expr<mpz_t, __gmp_urandomm_value>
    3435  {
    3436  private:
    3437    __gmp_randstate_struct *state;
    3438    mpz_class range;
    3439  public:
    3440    __gmp_expr(gmp_randstate_t s, const mpz_class &z) : state(s), range(z) { }
    3441    void eval(mpz_ptr z) const
    3442    { __gmp_rand_function::eval(z, state, range.get_mpz_t()); }
    3443    mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); }
    3444  };
    3445  
    3446  template <>
    3447  class __gmp_expr<mpf_t, __gmp_urandomb_value>
    3448  {
    3449  private:
    3450    __gmp_randstate_struct *state;
    3451    mp_bitcnt_t bits;
    3452  public:
    3453    __gmp_expr(gmp_randstate_t s, mp_bitcnt_t l) : state(s), bits(l) { }
    3454    void eval(mpf_ptr f) const
    3455    {
    3456      __gmp_rand_function::eval(f, state,
    3457  	(bits>0) ? bits : mpf_get_prec(f));
    3458    }
    3459    mp_bitcnt_t get_prec() const
    3460    {
    3461      if (bits == 0)
    3462        return mpf_get_default_prec();
    3463      else
    3464        return bits;
    3465    }
    3466  };
    3467  
    3468  extern "C" {
    3469    typedef void __gmp_randinit_default_t (gmp_randstate_t);
    3470    typedef void __gmp_randinit_lc_2exp_t (gmp_randstate_t, mpz_srcptr, unsigned long int, mp_bitcnt_t);
    3471    typedef int __gmp_randinit_lc_2exp_size_t (gmp_randstate_t, mp_bitcnt_t);
    3472  }
    3473  
    3474  class gmp_randclass
    3475  {
    3476  private:
    3477    gmp_randstate_t state;
    3478  
    3479    // copy construction and assignment not allowed
    3480    gmp_randclass(const gmp_randclass &);
    3481    void operator=(const gmp_randclass &);
    3482  public:
    3483    // constructors and destructor
    3484    gmp_randclass(gmp_randalg_t alg, unsigned long int size)
    3485    {
    3486      switch (alg)
    3487        {
    3488        case GMP_RAND_ALG_LC: // no other cases for now
    3489        default:
    3490  	gmp_randinit(state, alg, size);
    3491  	break;
    3492        }
    3493    }
    3494  
    3495    // gmp_randinit_default
    3496    gmp_randclass(__gmp_randinit_default_t* f) { f(state); }
    3497  
    3498    // gmp_randinit_lc_2exp
    3499    gmp_randclass(__gmp_randinit_lc_2exp_t* f,
    3500  		mpz_class z, unsigned long int l1, mp_bitcnt_t l2)
    3501    { f(state, z.get_mpz_t(), l1, l2); }
    3502  
    3503    // gmp_randinit_lc_2exp_size
    3504    gmp_randclass(__gmp_randinit_lc_2exp_size_t* f,
    3505  		mp_bitcnt_t size)
    3506    {
    3507      if (f (state, size) == 0)
    3508        throw std::length_error ("gmp_randinit_lc_2exp_size");
    3509    }
    3510  
    3511    ~gmp_randclass() { gmp_randclear(state); }
    3512  
    3513    // initialize
    3514    void seed(); // choose a random seed some way (?)
    3515    void seed(unsigned long int s) { gmp_randseed_ui(state, s); }
    3516    void seed(const mpz_class &z) { gmp_randseed(state, z.get_mpz_t()); }
    3517  
    3518    // get random number
    3519    __gmp_expr<mpz_t, __gmp_urandomb_value> get_z_bits(mp_bitcnt_t l)
    3520    { return __gmp_expr<mpz_t, __gmp_urandomb_value>(state, l); }
    3521    __gmp_expr<mpz_t, __gmp_urandomb_value> get_z_bits(const mpz_class &z)
    3522    { return get_z_bits(z.get_ui()); }
    3523    // FIXME: z.get_bitcnt_t() ?
    3524  
    3525    __gmp_expr<mpz_t, __gmp_urandomm_value> get_z_range(const mpz_class &z)
    3526    { return __gmp_expr<mpz_t, __gmp_urandomm_value>(state, z); }
    3527  
    3528    __gmp_expr<mpf_t, __gmp_urandomb_value> get_f(mp_bitcnt_t prec = 0)
    3529    { return __gmp_expr<mpf_t, __gmp_urandomb_value>(state, prec); }
    3530  };
    3531  
    3532  
    3533  /**************** Specialize std::numeric_limits ****************/
    3534  
    3535  namespace std {
    3536    template <> class numeric_limits<mpz_class>
    3537    {
    3538    public:
    3539      static const bool is_specialized = true;
    3540      static mpz_class min() { return mpz_class(); }
    3541      static mpz_class max() { return mpz_class(); }
    3542      static mpz_class lowest() { return mpz_class(); }
    3543      static const int digits = 0;
    3544      static const int digits10 = 0;
    3545      static const int max_digits10 = 0;
    3546      static const bool is_signed = true;
    3547      static const bool is_integer = true;
    3548      static const bool is_exact = true;
    3549      static const int radix = 2;
    3550      static mpz_class epsilon() { return mpz_class(); }
    3551      static mpz_class round_error() { return mpz_class(); }
    3552      static const int min_exponent = 0;
    3553      static const int min_exponent10 = 0;
    3554      static const int max_exponent = 0;
    3555      static const int max_exponent10 = 0;
    3556      static const bool has_infinity = false;
    3557      static const bool has_quiet_NaN = false;
    3558      static const bool has_signaling_NaN = false;
    3559      static const float_denorm_style has_denorm = denorm_absent;
    3560      static const bool has_denorm_loss = false;
    3561      static mpz_class infinity() { return mpz_class(); }
    3562      static mpz_class quiet_NaN() { return mpz_class(); }
    3563      static mpz_class signaling_NaN() { return mpz_class(); }
    3564      static mpz_class denorm_min() { return mpz_class(); }
    3565      static const bool is_iec559 = false;
    3566      static const bool is_bounded = false;
    3567      static const bool is_modulo = false;
    3568      static const bool traps = false;
    3569      static const bool tinyness_before = false;
    3570      static const float_round_style round_style = round_toward_zero;
    3571    };
    3572  
    3573    template <> class numeric_limits<mpq_class>
    3574    {
    3575    public:
    3576      static const bool is_specialized = true;
    3577      static mpq_class min() { return mpq_class(); }
    3578      static mpq_class max() { return mpq_class(); }
    3579      static mpq_class lowest() { return mpq_class(); }
    3580      static const int digits = 0;
    3581      static const int digits10 = 0;
    3582      static const int max_digits10 = 0;
    3583      static const bool is_signed = true;
    3584      static const bool is_integer = false;
    3585      static const bool is_exact = true;
    3586      static const int radix = 2;
    3587      static mpq_class epsilon() { return mpq_class(); }
    3588      static mpq_class round_error() { return mpq_class(); }
    3589      static const int min_exponent = 0;
    3590      static const int min_exponent10 = 0;
    3591      static const int max_exponent = 0;
    3592      static const int max_exponent10 = 0;
    3593      static const bool has_infinity = false;
    3594      static const bool has_quiet_NaN = false;
    3595      static const bool has_signaling_NaN = false;
    3596      static const float_denorm_style has_denorm = denorm_absent;
    3597      static const bool has_denorm_loss = false;
    3598      static mpq_class infinity() { return mpq_class(); }
    3599      static mpq_class quiet_NaN() { return mpq_class(); }
    3600      static mpq_class signaling_NaN() { return mpq_class(); }
    3601      static mpq_class denorm_min() { return mpq_class(); }
    3602      static const bool is_iec559 = false;
    3603      static const bool is_bounded = false;
    3604      static const bool is_modulo = false;
    3605      static const bool traps = false;
    3606      static const bool tinyness_before = false;
    3607      static const float_round_style round_style = round_toward_zero;
    3608    };
    3609  
    3610    template <> class numeric_limits<mpf_class>
    3611    {
    3612    public:
    3613      static const bool is_specialized = true;
    3614      static mpf_class min() { return mpf_class(); }
    3615      static mpf_class max() { return mpf_class(); }
    3616      static mpf_class lowest() { return mpf_class(); }
    3617      static const int digits = 0;
    3618      static const int digits10 = 0;
    3619      static const int max_digits10 = 0;
    3620      static const bool is_signed = true;
    3621      static const bool is_integer = false;
    3622      static const bool is_exact = false;
    3623      static const int radix = 2;
    3624      static mpf_class epsilon() { return mpf_class(); }
    3625      static mpf_class round_error() { return mpf_class(); }
    3626      static const int min_exponent = 0;
    3627      static const int min_exponent10 = 0;
    3628      static const int max_exponent = 0;
    3629      static const int max_exponent10 = 0;
    3630      static const bool has_infinity = false;
    3631      static const bool has_quiet_NaN = false;
    3632      static const bool has_signaling_NaN = false;
    3633      static const float_denorm_style has_denorm = denorm_absent;
    3634      static const bool has_denorm_loss = false;
    3635      static mpf_class infinity() { return mpf_class(); }
    3636      static mpf_class quiet_NaN() { return mpf_class(); }
    3637      static mpf_class signaling_NaN() { return mpf_class(); }
    3638      static mpf_class denorm_min() { return mpf_class(); }
    3639      static const bool is_iec559 = false;
    3640      static const bool is_bounded = false;
    3641      static const bool is_modulo = false;
    3642      static const bool traps = false;
    3643      static const bool tinyness_before = false;
    3644      static const float_round_style round_style = round_indeterminate;
    3645    };
    3646  }
    3647  
    3648  
    3649  /**************** #undef all private macros ****************/
    3650  
    3651  #undef __GMPP_DECLARE_COMPOUND_OPERATOR
    3652  #undef __GMPN_DECLARE_COMPOUND_OPERATOR
    3653  #undef __GMP_DECLARE_COMPOUND_OPERATOR
    3654  #undef __GMP_DECLARE_COMPOUND_OPERATOR_UI
    3655  #undef __GMP_DECLARE_INCREMENT_OPERATOR
    3656  #undef __GMPXX_DEFINE_ARITHMETIC_CONSTRUCTORS
    3657  #undef __GMPXX_DEFINE_ARITHMETIC_ASSIGNMENTS
    3658  
    3659  #undef __GMPZQ_DEFINE_EXPR
    3660  
    3661  #undef __GMP_DEFINE_UNARY_FUNCTION_1
    3662  #undef __GMP_DEFINE_UNARY_FUNCTION
    3663  #undef __GMP_DEFINE_UNARY_TYPE_FUNCTION
    3664  
    3665  #undef __GMPP_DEFINE_BINARY_FUNCTION
    3666  #undef __GMPNN_DEFINE_BINARY_FUNCTION
    3667  #undef __GMPNS_DEFINE_BINARY_FUNCTION
    3668  #undef __GMPNU_DEFINE_BINARY_FUNCTION
    3669  #undef __GMPND_DEFINE_BINARY_FUNCTION
    3670  #undef __GMPNLD_DEFINE_BINARY_FUNCTION
    3671  #undef __GMPN_DEFINE_BINARY_FUNCTION
    3672  #undef __GMP_DEFINE_BINARY_FUNCTION
    3673  
    3674  #undef __GMP_DEFINE_BINARY_FUNCTION_UI
    3675  
    3676  #undef __GMPP_DEFINE_BINARY_TYPE_FUNCTION
    3677  #undef __GMPNN_DEFINE_BINARY_TYPE_FUNCTION
    3678  #undef __GMPNS_DEFINE_BINARY_TYPE_FUNCTION
    3679  #undef __GMPNU_DEFINE_BINARY_TYPE_FUNCTION
    3680  #undef __GMPND_DEFINE_BINARY_TYPE_FUNCTION
    3681  #undef __GMPNLD_DEFINE_BINARY_TYPE_FUNCTION
    3682  #undef __GMPN_DEFINE_BINARY_TYPE_FUNCTION
    3683  #undef __GMP_DEFINE_BINARY_TYPE_FUNCTION
    3684  
    3685  #undef __GMPZ_DEFINE_COMPOUND_OPERATOR
    3686  
    3687  #undef __GMPP_DEFINE_COMPOUND_OPERATOR
    3688  #undef __GMPNN_DEFINE_COMPOUND_OPERATOR
    3689  #undef __GMPNS_DEFINE_COMPOUND_OPERATOR
    3690  #undef __GMPNU_DEFINE_COMPOUND_OPERATOR
    3691  #undef __GMPND_DEFINE_COMPOUND_OPERATOR
    3692  #undef __GMPNLD_DEFINE_COMPOUND_OPERATOR
    3693  #undef __GMPN_DEFINE_COMPOUND_OPERATOR
    3694  #undef __GMP_DEFINE_COMPOUND_OPERATOR
    3695  
    3696  #undef __GMPQ_DEFINE_COMPOUND_OPERATOR
    3697  #undef __GMPF_DEFINE_COMPOUND_OPERATOR
    3698  
    3699  #undef __GMP_DEFINE_COMPOUND_OPERATOR_UI
    3700  #undef __GMPZ_DEFINE_COMPOUND_OPERATOR_UI
    3701  #undef __GMPQ_DEFINE_COMPOUND_OPERATOR_UI
    3702  #undef __GMPF_DEFINE_COMPOUND_OPERATOR_UI
    3703  
    3704  #undef __GMP_DEFINE_INCREMENT_OPERATOR
    3705  #undef __GMPZ_DEFINE_INCREMENT_OPERATOR
    3706  #undef __GMPQ_DEFINE_INCREMENT_OPERATOR
    3707  #undef __GMPF_DEFINE_INCREMENT_OPERATOR
    3708  
    3709  #undef __GMPXX_CONSTANT_TRUE
    3710  #undef __GMPXX_CONSTANT
    3711  
    3712  #endif /* __GMP_PLUSPLUS__ */