github.com/aergoio/aergo@v1.3.1/libtool/src/gmp-6.1.2/gmpxx.h (about)

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