Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-17 09:55:31

0001 /* gmpxx.h -- C++ class wrapper for GMP types.  -*- C++ -*-
0002 
0003 Copyright 2001-2003, 2006, 2008, 2011-2015, 2018 Free Software
0004 Foundation, Inc.
0005 
0006 This file is part of the GNU MP Library.
0007 
0008 The GNU MP Library is free software; you can redistribute it and/or modify
0009 it under the terms of either:
0010 
0011   * the GNU Lesser General Public License as published by the Free
0012     Software Foundation; either version 3 of the License, or (at your
0013     option) any later version.
0014 
0015 or
0016 
0017   * the GNU General Public License as published by the Free Software
0018     Foundation; either version 2 of the License, or (at your option) any
0019     later version.
0020 
0021 or both in parallel, as here.
0022 
0023 The GNU MP Library is distributed in the hope that it will be useful, but
0024 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
0025 or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
0026 for more details.
0027 
0028 You should have received copies of the GNU General Public License and the
0029 GNU Lesser General Public License along with the GNU MP Library.  If not,
0030 see https://www.gnu.org/licenses/.  */
0031 
0032 #ifndef __GMP_PLUSPLUS__
0033 #define __GMP_PLUSPLUS__
0034 
0035 #include <iosfwd>
0036 
0037 #include <cstring>  /* for strlen */
0038 #include <limits>  /* numeric_limits */
0039 #include <utility>
0040 #include <algorithm>  /* swap */
0041 #include <string>
0042 #include <stdexcept>
0043 #include <cfloat>
0044 #include <gmp.h>
0045 
0046 // wrapper for gcc's __builtin_constant_p
0047 // __builtin_constant_p has been in gcc since forever,
0048 // but g++-3.4 miscompiles it.
0049 #if __GMP_GNUC_PREREQ(4, 2)
0050 #define __GMPXX_CONSTANT(X) __builtin_constant_p(X)
0051 #else
0052 #define __GMPXX_CONSTANT(X) false
0053 #endif
0054 #define __GMPXX_CONSTANT_TRUE(X) (__GMPXX_CONSTANT(X) && (X))
0055 
0056 // Use C++11 features
0057 #ifndef __GMPXX_USE_CXX11
0058 #if __cplusplus >= 201103L
0059 #define __GMPXX_USE_CXX11 1
0060 #else
0061 #define __GMPXX_USE_CXX11 0
0062 #endif
0063 #endif
0064 
0065 #if __GMPXX_USE_CXX11
0066 #define __GMPXX_NOEXCEPT noexcept
0067 #include <type_traits> // for common_type
0068 #else
0069 #define __GMPXX_NOEXCEPT
0070 #endif
0071 
0072 // Max allocations for plain types when converted to GMP types
0073 #if GMP_NAIL_BITS != 0 && ! defined _LONG_LONG_LIMB
0074 #define __GMPZ_ULI_LIMBS 2
0075 #else
0076 #define __GMPZ_ULI_LIMBS 1
0077 #endif
0078 
0079 #define __GMPXX_BITS_TO_LIMBS(n)  (((n) + (GMP_NUMB_BITS - 1)) / GMP_NUMB_BITS)
0080 #define __GMPZ_DBL_LIMBS __GMPXX_BITS_TO_LIMBS(DBL_MAX_EXP)+1
0081 #define __GMPQ_NUM_DBL_LIMBS __GMPZ_DBL_LIMBS
0082 #define __GMPQ_DEN_DBL_LIMBS __GMPXX_BITS_TO_LIMBS(DBL_MANT_DIG+1-DBL_MIN_EXP)+1
0083 // The final +1s are a security margin. The current implementation of
0084 // mpq_set_d seems to need it for the denominator.
0085 
0086 inline void __mpz_set_ui_safe(mpz_ptr p, unsigned long l)
0087 {
0088   p->_mp_size = (l != 0);
0089   p->_mp_d[0] = l & GMP_NUMB_MASK;
0090 #if __GMPZ_ULI_LIMBS > 1
0091   l >>= GMP_NUMB_BITS;
0092   p->_mp_d[1] = l;
0093   p->_mp_size += (l != 0);
0094 #endif
0095 }
0096 
0097 inline void __mpz_set_si_safe(mpz_ptr p, long l)
0098 {
0099   if(l < 0)
0100   {
0101     __mpz_set_ui_safe(p, -static_cast<unsigned long>(l));
0102     mpz_neg(p, p);
0103   }
0104   else
0105     __mpz_set_ui_safe(p, l);
0106     // Note: we know the high bit of l is 0 so we could do slightly better
0107 }
0108 
0109 // Fake temporary variables
0110 #define __GMPXX_TMPZ_UI                         \
0111   mpz_t temp;                               \
0112   mp_limb_t limbs[__GMPZ_ULI_LIMBS];                    \
0113   temp->_mp_d = limbs;                          \
0114   __mpz_set_ui_safe (temp, l)
0115 #define __GMPXX_TMPZ_SI                         \
0116   mpz_t temp;                               \
0117   mp_limb_t limbs[__GMPZ_ULI_LIMBS];                    \
0118   temp->_mp_d = limbs;                          \
0119   __mpz_set_si_safe (temp, l)
0120 #define __GMPXX_TMPZ_D                          \
0121   mpz_t temp;                               \
0122   mp_limb_t limbs[__GMPZ_DBL_LIMBS];                    \
0123   temp->_mp_d = limbs;                          \
0124   temp->_mp_alloc = __GMPZ_DBL_LIMBS;                   \
0125   mpz_set_d (temp, d)
0126 
0127 #define __GMPXX_TMPQ_UI                         \
0128   mpq_t temp;                               \
0129   mp_limb_t limbs[__GMPZ_ULI_LIMBS+1];                  \
0130   mpq_numref(temp)->_mp_d = limbs;                  \
0131   __mpz_set_ui_safe (mpq_numref(temp), l);              \
0132   mpq_denref(temp)->_mp_d = limbs + __GMPZ_ULI_LIMBS;           \
0133   mpq_denref(temp)->_mp_size = 1;                   \
0134   mpq_denref(temp)->_mp_d[0] = 1
0135 #define __GMPXX_TMPQ_SI                         \
0136   mpq_t temp;                               \
0137   mp_limb_t limbs[__GMPZ_ULI_LIMBS+1];                  \
0138   mpq_numref(temp)->_mp_d = limbs;                  \
0139   __mpz_set_si_safe (mpq_numref(temp), l);              \
0140   mpq_denref(temp)->_mp_d = limbs + __GMPZ_ULI_LIMBS;           \
0141   mpq_denref(temp)->_mp_size = 1;                   \
0142   mpq_denref(temp)->_mp_d[0] = 1
0143 #define __GMPXX_TMPQ_D                          \
0144   mpq_t temp;                               \
0145   mp_limb_t limbs[__GMPQ_NUM_DBL_LIMBS + __GMPQ_DEN_DBL_LIMBS];     \
0146   mpq_numref(temp)->_mp_d = limbs;                  \
0147   mpq_numref(temp)->_mp_alloc = __GMPQ_NUM_DBL_LIMBS;           \
0148   mpq_denref(temp)->_mp_d = limbs + __GMPQ_NUM_DBL_LIMBS;       \
0149   mpq_denref(temp)->_mp_alloc = __GMPQ_DEN_DBL_LIMBS;           \
0150   mpq_set_d (temp, d)
0151 
0152 inline unsigned long __gmpxx_abs_ui (signed long l)
0153 {
0154   return l >= 0 ? static_cast<unsigned long>(l)
0155       : -static_cast<unsigned long>(l);
0156 }
0157 
0158 /**************** Function objects ****************/
0159 /* Any evaluation of a __gmp_expr ends up calling one of these functions
0160    all intermediate functions being inline, the evaluation should optimize
0161    to a direct call to the relevant function, thus yielding no overhead
0162    over the C interface. */
0163 
0164 struct __gmp_unary_plus
0165 {
0166   static void eval(mpz_ptr z, mpz_srcptr w) { mpz_set(z, w); }
0167   static void eval(mpq_ptr q, mpq_srcptr r) { mpq_set(q, r); }
0168   static void eval(mpf_ptr f, mpf_srcptr g) { mpf_set(f, g); }
0169 };
0170 
0171 struct __gmp_unary_minus
0172 {
0173   static void eval(mpz_ptr z, mpz_srcptr w) { mpz_neg(z, w); }
0174   static void eval(mpq_ptr q, mpq_srcptr r) { mpq_neg(q, r); }
0175   static void eval(mpf_ptr f, mpf_srcptr g) { mpf_neg(f, g); }
0176 };
0177 
0178 struct __gmp_unary_com
0179 {
0180   static void eval(mpz_ptr z, mpz_srcptr w) { mpz_com(z, w); }
0181 };
0182 
0183 struct __gmp_binary_plus
0184 {
0185   static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v)
0186   { mpz_add(z, w, v); }
0187 
0188   static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l)
0189   {
0190     // Ideally, those checks should happen earlier so that the tree
0191     // generated for a+0+b would just be sum(a,b).
0192     if (__GMPXX_CONSTANT(l) && l == 0)
0193     {
0194       if (z != w) mpz_set(z, w);
0195     }
0196     else
0197       mpz_add_ui(z, w, l);
0198   }
0199   static void eval(mpz_ptr z, unsigned long int l, mpz_srcptr w)
0200   { eval(z, w, l); }
0201   static void eval(mpz_ptr z, mpz_srcptr w, signed long int l)
0202   {
0203     if (l >= 0)
0204       eval(z, w, static_cast<unsigned long>(l));
0205     else
0206       mpz_sub_ui(z, w, -static_cast<unsigned long>(l));
0207   }
0208   static void eval(mpz_ptr z, signed long int l, mpz_srcptr w)
0209   { eval(z, w, l); }
0210   static void eval(mpz_ptr z, mpz_srcptr w, double d)
0211   {  __GMPXX_TMPZ_D;    mpz_add (z, w, temp); }
0212   static void eval(mpz_ptr z, double d, mpz_srcptr w)
0213   { eval(z, w, d); }
0214 
0215   static void eval(mpq_ptr q, mpq_srcptr r, mpq_srcptr s)
0216   { mpq_add(q, r, s); }
0217 
0218   static void eval(mpq_ptr q, mpq_srcptr r, unsigned long int l)
0219   {
0220     if (__GMPXX_CONSTANT(l) && l == 0)
0221     {
0222       if (q != r) mpq_set(q, r);
0223     }
0224     else if (__GMPXX_CONSTANT(l) && l == 1)
0225     {
0226       mpz_add (mpq_numref(q), mpq_numref(r), mpq_denref(r));
0227       if (q != r) mpz_set(mpq_denref(q), mpq_denref(r));
0228     }
0229     else
0230     {
0231       if (q == r)
0232         mpz_addmul_ui(mpq_numref(q), mpq_denref(q), l);
0233       else
0234       {
0235         mpz_mul_ui(mpq_numref(q), mpq_denref(r), l);
0236         mpz_add(mpq_numref(q), mpq_numref(q), mpq_numref(r));
0237         mpz_set(mpq_denref(q), mpq_denref(r));
0238       }
0239     }
0240   }
0241   static void eval(mpq_ptr q, unsigned long int l, mpq_srcptr r)
0242   { eval(q, r, l); }
0243   static inline void eval(mpq_ptr q, mpq_srcptr r, signed long int l);
0244   // defined after __gmp_binary_minus
0245   static void eval(mpq_ptr q, signed long int l, mpq_srcptr r)
0246   { eval(q, r, l); }
0247   static void eval(mpq_ptr q, mpq_srcptr r, double d)
0248   {  __GMPXX_TMPQ_D;    mpq_add (q, r, temp); }
0249   static void eval(mpq_ptr q, double d, mpq_srcptr r)
0250   { eval(q, r, d); }
0251 
0252   static void eval(mpq_ptr q, mpq_srcptr r, mpz_srcptr z)
0253   {
0254     if (q == r)
0255       mpz_addmul(mpq_numref(q), mpq_denref(q), z);
0256     else
0257     {
0258       mpz_mul(mpq_numref(q), mpq_denref(r), z);
0259       mpz_add(mpq_numref(q), mpq_numref(q), mpq_numref(r));
0260       mpz_set(mpq_denref(q), mpq_denref(r));
0261     }
0262   }
0263   static void eval(mpq_ptr q, mpz_srcptr z, mpq_srcptr r)
0264   { eval(q, r, z); }
0265 
0266   static void eval(mpf_ptr f, mpf_srcptr g, mpf_srcptr h)
0267   { mpf_add(f, g, h); }
0268 
0269   static void eval(mpf_ptr f, mpf_srcptr g, unsigned long int l)
0270   { mpf_add_ui(f, g, l); }
0271   static void eval(mpf_ptr f, unsigned long int l, mpf_srcptr g)
0272   { mpf_add_ui(f, g, l); }
0273   static void eval(mpf_ptr f, mpf_srcptr g, signed long int l)
0274   {
0275     if (l >= 0)
0276       mpf_add_ui(f, g, l);
0277     else
0278       mpf_sub_ui(f, g, -static_cast<unsigned long>(l));
0279   }
0280   static void eval(mpf_ptr f, signed long int l, mpf_srcptr g)
0281   { eval(f, g, l); }
0282   static void eval(mpf_ptr f, mpf_srcptr g, double d)
0283   {
0284     mpf_t temp;
0285     mpf_init2(temp, 8*sizeof(double));
0286     mpf_set_d(temp, d);
0287     mpf_add(f, g, temp);
0288     mpf_clear(temp);
0289   }
0290   static void eval(mpf_ptr f, double d, mpf_srcptr g)
0291   { eval(f, g, d); }
0292 };
0293 
0294 struct __gmp_binary_minus
0295 {
0296   static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v)
0297   { mpz_sub(z, w, v); }
0298 
0299   static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l)
0300   {
0301     if (__GMPXX_CONSTANT(l) && l == 0)
0302     {
0303       if (z != w) mpz_set(z, w);
0304     }
0305     else
0306       mpz_sub_ui(z, w, l);
0307   }
0308   static void eval(mpz_ptr z, unsigned long int l, mpz_srcptr w)
0309   {
0310     if (__GMPXX_CONSTANT(l) && l == 0)
0311     {
0312       mpz_neg(z, w);
0313     }
0314     else
0315       mpz_ui_sub(z, l, w);
0316   }
0317   static void eval(mpz_ptr z, mpz_srcptr w, signed long int l)
0318   {
0319     if (l >= 0)
0320       eval(z, w, static_cast<unsigned long>(l));
0321     else
0322       mpz_add_ui(z, w, -static_cast<unsigned long>(l));
0323   }
0324   static void eval(mpz_ptr z, signed long int l, mpz_srcptr w)
0325   {
0326     if (l >= 0)
0327       eval(z, static_cast<unsigned long>(l), w);
0328     else
0329       {
0330         mpz_add_ui(z, w, -static_cast<unsigned long>(l));
0331         mpz_neg(z, z);
0332       }
0333   }
0334   static void eval(mpz_ptr z, mpz_srcptr w, double d)
0335   {  __GMPXX_TMPZ_D;    mpz_sub (z, w, temp); }
0336   static void eval(mpz_ptr z, double d, mpz_srcptr w)
0337   {  __GMPXX_TMPZ_D;    mpz_sub (z, temp, w); }
0338 
0339   static void eval(mpq_ptr q, mpq_srcptr r, mpq_srcptr s)
0340   { mpq_sub(q, r, s); }
0341 
0342   static void eval(mpq_ptr q, mpq_srcptr r, unsigned long int l)
0343   {
0344     if (__GMPXX_CONSTANT(l) && l == 0)
0345     {
0346       if (q != r) mpq_set(q, r);
0347     }
0348     else if (__GMPXX_CONSTANT(l) && l == 1)
0349     {
0350       mpz_sub (mpq_numref(q), mpq_numref(r), mpq_denref(r));
0351       if (q != r) mpz_set(mpq_denref(q), mpq_denref(r));
0352     }
0353     else
0354     {
0355       if (q == r)
0356         mpz_submul_ui(mpq_numref(q), mpq_denref(q), l);
0357       else
0358       {
0359         mpz_mul_ui(mpq_numref(q), mpq_denref(r), l);
0360         mpz_sub(mpq_numref(q), mpq_numref(r), mpq_numref(q));
0361         mpz_set(mpq_denref(q), mpq_denref(r));
0362       }
0363     }
0364   }
0365   static void eval(mpq_ptr q, unsigned long int l, mpq_srcptr r)
0366   { eval(q, r, l); mpq_neg(q, q); }
0367   static void eval(mpq_ptr q, mpq_srcptr r, signed long int l)
0368   {
0369     if (l >= 0)
0370       eval(q, r, static_cast<unsigned long>(l));
0371     else
0372       __gmp_binary_plus::eval(q, r, -static_cast<unsigned long>(l));
0373   }
0374   static void eval(mpq_ptr q, signed long int l, mpq_srcptr r)
0375   { eval(q, r, l); mpq_neg(q, q); }
0376   static void eval(mpq_ptr q, mpq_srcptr r, double d)
0377   {  __GMPXX_TMPQ_D;    mpq_sub (q, r, temp); }
0378   static void eval(mpq_ptr q, double d, mpq_srcptr r)
0379   {  __GMPXX_TMPQ_D;    mpq_sub (q, temp, r); }
0380 
0381   static void eval(mpq_ptr q, mpq_srcptr r, mpz_srcptr z)
0382   {
0383     if (q == r)
0384       mpz_submul(mpq_numref(q), mpq_denref(q), z);
0385     else
0386     {
0387       mpz_mul(mpq_numref(q), mpq_denref(r), z);
0388       mpz_sub(mpq_numref(q), mpq_numref(r), mpq_numref(q));
0389       mpz_set(mpq_denref(q), mpq_denref(r));
0390     }
0391   }
0392   static void eval(mpq_ptr q, mpz_srcptr z, mpq_srcptr r)
0393   { eval(q, r, z); mpq_neg(q, q); }
0394 
0395   static void eval(mpf_ptr f, mpf_srcptr g, mpf_srcptr h)
0396   { mpf_sub(f, g, h); }
0397 
0398   static void eval(mpf_ptr f, mpf_srcptr g, unsigned long int l)
0399   { mpf_sub_ui(f, g, l); }
0400   static void eval(mpf_ptr f, unsigned long int l, mpf_srcptr g)
0401   { mpf_ui_sub(f, l, g); }
0402   static void eval(mpf_ptr f, mpf_srcptr g, signed long int l)
0403   {
0404     if (l >= 0)
0405       mpf_sub_ui(f, g, l);
0406     else
0407       mpf_add_ui(f, g, -static_cast<unsigned long>(l));
0408   }
0409   static void eval(mpf_ptr f, signed long int l, mpf_srcptr g)
0410   {
0411     if (l >= 0)
0412       mpf_sub_ui(f, g, l);
0413     else
0414       mpf_add_ui(f, g, -static_cast<unsigned long>(l));
0415     mpf_neg(f, f);
0416   }
0417   static void eval(mpf_ptr f, mpf_srcptr g, double d)
0418   {
0419     mpf_t temp;
0420     mpf_init2(temp, 8*sizeof(double));
0421     mpf_set_d(temp, d);
0422     mpf_sub(f, g, temp);
0423     mpf_clear(temp);
0424   }
0425   static void eval(mpf_ptr f, double d, mpf_srcptr g)
0426   {
0427     mpf_t temp;
0428     mpf_init2(temp, 8*sizeof(double));
0429     mpf_set_d(temp, d);
0430     mpf_sub(f, temp, g);
0431     mpf_clear(temp);
0432   }
0433 };
0434 
0435 // defined here so it can reference __gmp_binary_minus
0436 inline void
0437 __gmp_binary_plus::eval(mpq_ptr q, mpq_srcptr r, signed long int l)
0438 {
0439   if (l >= 0)
0440     eval(q, r, static_cast<unsigned long>(l));
0441   else
0442     __gmp_binary_minus::eval(q, r, -static_cast<unsigned long>(l));
0443 }
0444 
0445 struct __gmp_binary_lshift
0446 {
0447   static void eval(mpz_ptr z, mpz_srcptr w, mp_bitcnt_t l)
0448   {
0449     if (__GMPXX_CONSTANT(l) && (l == 0))
0450     {
0451       if (z != w) mpz_set(z, w);
0452     }
0453     else
0454       mpz_mul_2exp(z, w, l);
0455   }
0456   static void eval(mpq_ptr q, mpq_srcptr r, mp_bitcnt_t l)
0457   {
0458     if (__GMPXX_CONSTANT(l) && (l == 0))
0459     {
0460       if (q != r) mpq_set(q, r);
0461     }
0462     else
0463       mpq_mul_2exp(q, r, l);
0464   }
0465   static void eval(mpf_ptr f, mpf_srcptr g, mp_bitcnt_t l)
0466   { mpf_mul_2exp(f, g, l); }
0467 };
0468 
0469 struct __gmp_binary_rshift
0470 {
0471   static void eval(mpz_ptr z, mpz_srcptr w, mp_bitcnt_t l)
0472   {
0473     if (__GMPXX_CONSTANT(l) && (l == 0))
0474     {
0475       if (z != w) mpz_set(z, w);
0476     }
0477     else
0478       mpz_fdiv_q_2exp(z, w, l);
0479   }
0480   static void eval(mpq_ptr q, mpq_srcptr r, mp_bitcnt_t l)
0481   {
0482     if (__GMPXX_CONSTANT(l) && (l == 0))
0483     {
0484       if (q != r) mpq_set(q, r);
0485     }
0486     else
0487       mpq_div_2exp(q, r, l);
0488   }
0489   static void eval(mpf_ptr f, mpf_srcptr g, mp_bitcnt_t l)
0490   { mpf_div_2exp(f, g, l); }
0491 };
0492 
0493 struct __gmp_binary_multiplies
0494 {
0495   static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v)
0496   { mpz_mul(z, w, v); }
0497 
0498   static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l)
0499   {
0500 // gcc-3.3 doesn't have __builtin_ctzl. Don't bother optimizing for old gcc.
0501 #if __GMP_GNUC_PREREQ(3, 4)
0502     if (__GMPXX_CONSTANT(l) && (l & (l-1)) == 0)
0503     {
0504       if (l == 0)
0505       {
0506         z->_mp_size = 0;
0507       }
0508       else
0509       {
0510         __gmp_binary_lshift::eval(z, w, __builtin_ctzl(l));
0511       }
0512     }
0513     else
0514 #endif
0515       mpz_mul_ui(z, w, l);
0516   }
0517   static void eval(mpz_ptr z, unsigned long int l, mpz_srcptr w)
0518   { eval(z, w, l); }
0519   static void eval(mpz_ptr z, mpz_srcptr w, signed long int l)
0520   {
0521     if (__GMPXX_CONSTANT_TRUE(l >= 0))
0522       eval(z, w, static_cast<unsigned long>(l));
0523     else if (__GMPXX_CONSTANT_TRUE(l <= 0))
0524       {
0525         eval(z, w, -static_cast<unsigned long>(l));
0526     mpz_neg(z, z);
0527       }
0528     else
0529       mpz_mul_si (z, w, l);
0530   }
0531   static void eval(mpz_ptr z, signed long int l, mpz_srcptr w)
0532   { eval(z, w, l); }
0533   static void eval(mpz_ptr z, mpz_srcptr w, double d)
0534   {  __GMPXX_TMPZ_D;    mpz_mul (z, w, temp); }
0535   static void eval(mpz_ptr z, double d, mpz_srcptr w)
0536   { eval(z, w, d); }
0537 
0538   static void eval(mpq_ptr q, mpq_srcptr r, mpq_srcptr s)
0539   { mpq_mul(q, r, s); }
0540 
0541   static void eval(mpq_ptr q, mpq_srcptr r, unsigned long int l)
0542   {
0543 #if __GMP_GNUC_PREREQ(3, 4)
0544     if (__GMPXX_CONSTANT(l) && (l & (l-1)) == 0)
0545     {
0546       if (l == 0)
0547       {
0548     mpq_set_ui(q, 0, 1);
0549       }
0550       else
0551       {
0552         __gmp_binary_lshift::eval(q, r, __builtin_ctzl(l));
0553       }
0554     }
0555     else
0556 #endif
0557     {
0558       __GMPXX_TMPQ_UI;
0559       mpq_mul (q, r, temp);
0560     }
0561   }
0562   static void eval(mpq_ptr q, unsigned long int l, mpq_srcptr r)
0563   { eval(q, r, l); }
0564   static void eval(mpq_ptr q, mpq_srcptr r, signed long int l)
0565   {
0566     if (__GMPXX_CONSTANT_TRUE(l >= 0))
0567       eval(q, r, static_cast<unsigned long>(l));
0568     else if (__GMPXX_CONSTANT_TRUE(l <= 0))
0569       {
0570         eval(q, r, -static_cast<unsigned long>(l));
0571     mpq_neg(q, q);
0572       }
0573     else
0574       {
0575     __GMPXX_TMPQ_SI;
0576     mpq_mul (q, r, temp);
0577       }
0578   }
0579   static void eval(mpq_ptr q, signed long int l, mpq_srcptr r)
0580   { eval(q, r, l); }
0581   static void eval(mpq_ptr q, mpq_srcptr r, double d)
0582   {  __GMPXX_TMPQ_D;    mpq_mul (q, r, temp); }
0583   static void eval(mpq_ptr q, double d, mpq_srcptr r)
0584   { eval(q, r, d); }
0585 
0586   static void eval(mpf_ptr f, mpf_srcptr g, mpf_srcptr h)
0587   { mpf_mul(f, g, h); }
0588 
0589   static void eval(mpf_ptr f, mpf_srcptr g, unsigned long int l)
0590   { mpf_mul_ui(f, g, l); }
0591   static void eval(mpf_ptr f, unsigned long int l, mpf_srcptr g)
0592   { mpf_mul_ui(f, g, l); }
0593   static void eval(mpf_ptr f, mpf_srcptr g, signed long int l)
0594   {
0595     if (l >= 0)
0596       mpf_mul_ui(f, g, l);
0597     else
0598       {
0599     mpf_mul_ui(f, g, -static_cast<unsigned long>(l));
0600     mpf_neg(f, f);
0601       }
0602   }
0603   static void eval(mpf_ptr f, signed long int l, mpf_srcptr g)
0604   { eval(f, g, l); }
0605   static void eval(mpf_ptr f, mpf_srcptr g, double d)
0606   {
0607     mpf_t temp;
0608     mpf_init2(temp, 8*sizeof(double));
0609     mpf_set_d(temp, d);
0610     mpf_mul(f, g, temp);
0611     mpf_clear(temp);
0612   }
0613   static void eval(mpf_ptr f, double d, mpf_srcptr g)
0614   { eval(f, g, d); }
0615 };
0616 
0617 struct __gmp_binary_divides
0618 {
0619   static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v)
0620   { mpz_tdiv_q(z, w, v); }
0621 
0622   static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l)
0623   {
0624 #if __GMP_GNUC_PREREQ(3, 4)
0625     // Don't optimize division by 0...
0626     if (__GMPXX_CONSTANT(l) && (l & (l-1)) == 0 && l != 0)
0627     {
0628       if (l == 1)
0629       {
0630         if (z != w) mpz_set(z, w);
0631       }
0632       else
0633         mpz_tdiv_q_2exp(z, w, __builtin_ctzl(l));
0634         // warning: do not use rshift (fdiv)
0635     }
0636     else
0637 #endif
0638       mpz_tdiv_q_ui(z, w, l);
0639   }
0640   static void eval(mpz_ptr z, unsigned long int l, mpz_srcptr w)
0641   {
0642     if (mpz_sgn(w) >= 0)
0643       {
0644     if (mpz_fits_ulong_p(w))
0645       mpz_set_ui(z, l / mpz_get_ui(w));
0646     else
0647       mpz_set_ui(z, 0);
0648       }
0649     else
0650       {
0651     mpz_neg(z, w);
0652     if (mpz_fits_ulong_p(z))
0653       {
0654         mpz_set_ui(z, l / mpz_get_ui(z));
0655         mpz_neg(z, z);
0656       }
0657     else
0658       mpz_set_ui(z, 0);
0659       }
0660   }
0661   static void eval(mpz_ptr z, mpz_srcptr w, signed long int l)
0662   {
0663     if (l >= 0)
0664       eval(z, w, static_cast<unsigned long>(l));
0665     else
0666       {
0667     eval(z, w, -static_cast<unsigned long>(l));
0668     mpz_neg(z, z);
0669       }
0670   }
0671   static void eval(mpz_ptr z, signed long int l, mpz_srcptr w)
0672   {
0673     if (mpz_fits_slong_p(w))
0674       mpz_set_si(z, l / mpz_get_si(w));
0675     else
0676       {
0677         /* if w is bigger than a long then the quotient must be zero, unless
0678            l==LONG_MIN and w==-LONG_MIN in which case the quotient is -1 */
0679         mpz_set_si (z, (mpz_cmpabs_ui (w, __gmpxx_abs_ui(l)) == 0 ? -1 : 0));
0680       }
0681   }
0682   static void eval(mpz_ptr z, mpz_srcptr w, double d)
0683   {  __GMPXX_TMPZ_D;    mpz_tdiv_q (z, w, temp); }
0684   static void eval(mpz_ptr z, double d, mpz_srcptr w)
0685   {  __GMPXX_TMPZ_D;    mpz_tdiv_q (z, temp, w); }
0686 
0687   static void eval(mpq_ptr q, mpq_srcptr r, mpq_srcptr s)
0688   { mpq_div(q, r, s); }
0689 
0690   static void eval(mpq_ptr q, mpq_srcptr r, unsigned long int l)
0691   {
0692 #if __GMP_GNUC_PREREQ(3, 4)
0693     if (__GMPXX_CONSTANT(l) && (l & (l-1)) == 0 && l != 0)
0694       __gmp_binary_rshift::eval(q, r, __builtin_ctzl(l));
0695     else
0696 #endif
0697     {
0698       __GMPXX_TMPQ_UI;
0699       mpq_div (q, r, temp);
0700     }
0701   }
0702   static void eval(mpq_ptr q, unsigned long int l, mpq_srcptr r)
0703   {
0704     if (__GMPXX_CONSTANT_TRUE(l == 0))
0705       mpq_set_ui(q, 0, 1);
0706     else if (__GMPXX_CONSTANT_TRUE(l == 1))
0707       mpq_inv(q, r);
0708     else
0709       {
0710     __GMPXX_TMPQ_UI;
0711     mpq_div (q, temp, r);
0712       }
0713   }
0714   static void eval(mpq_ptr q, mpq_srcptr r, signed long int l)
0715   {
0716     if (__GMPXX_CONSTANT_TRUE(l >= 0))
0717       eval(q, r, static_cast<unsigned long>(l));
0718     else if (__GMPXX_CONSTANT_TRUE(l <= 0))
0719       {
0720         eval(q, r, -static_cast<unsigned long>(l));
0721     mpq_neg(q, q);
0722       }
0723     else
0724       {
0725     __GMPXX_TMPQ_SI;
0726     mpq_div (q, r, temp);
0727       }
0728   }
0729   static void eval(mpq_ptr q, signed long int l, mpq_srcptr r)
0730   {
0731     if (__GMPXX_CONSTANT_TRUE(l == 0))
0732       mpq_set_ui(q, 0, 1);
0733     else if (__GMPXX_CONSTANT_TRUE(l == 1))
0734       mpq_inv(q, r);
0735     else if (__GMPXX_CONSTANT_TRUE(l == -1))
0736       {
0737     mpq_inv(q, r);
0738     mpq_neg(q, q);
0739       }
0740     else
0741       {
0742     __GMPXX_TMPQ_SI;
0743     mpq_div (q, temp, r);
0744       }
0745   }
0746   static void eval(mpq_ptr q, mpq_srcptr r, double d)
0747   {  __GMPXX_TMPQ_D;    mpq_div (q, r, temp); }
0748   static void eval(mpq_ptr q, double d, mpq_srcptr r)
0749   {  __GMPXX_TMPQ_D;    mpq_div (q, temp, r); }
0750 
0751   static void eval(mpf_ptr f, mpf_srcptr g, mpf_srcptr h)
0752   { mpf_div(f, g, h); }
0753 
0754   static void eval(mpf_ptr f, mpf_srcptr g, unsigned long int l)
0755   { mpf_div_ui(f, g, l); }
0756   static void eval(mpf_ptr f, unsigned long int l, mpf_srcptr g)
0757   { mpf_ui_div(f, l, g); }
0758   static void eval(mpf_ptr f, mpf_srcptr g, signed long int l)
0759   {
0760     if (l >= 0)
0761       mpf_div_ui(f, g, l);
0762     else
0763       {
0764     mpf_div_ui(f, g, -static_cast<unsigned long>(l));
0765     mpf_neg(f, f);
0766       }
0767   }
0768   static void eval(mpf_ptr f, signed long int l, mpf_srcptr g)
0769   {
0770     if (l >= 0)
0771       mpf_ui_div(f, l, g);
0772     else
0773       {
0774     mpf_ui_div(f, -static_cast<unsigned long>(l), g);
0775     mpf_neg(f, f);
0776       }
0777   }
0778   static void eval(mpf_ptr f, mpf_srcptr g, double d)
0779   {
0780     mpf_t temp;
0781     mpf_init2(temp, 8*sizeof(double));
0782     mpf_set_d(temp, d);
0783     mpf_div(f, g, temp);
0784     mpf_clear(temp);
0785   }
0786   static void eval(mpf_ptr f, double d, mpf_srcptr g)
0787   {
0788     mpf_t temp;
0789     mpf_init2(temp, 8*sizeof(double));
0790     mpf_set_d(temp, d);
0791     mpf_div(f, temp, g);
0792     mpf_clear(temp);
0793   }
0794 };
0795 
0796 struct __gmp_binary_modulus
0797 {
0798   static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v)
0799   { mpz_tdiv_r(z, w, v); }
0800 
0801   static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l)
0802   { mpz_tdiv_r_ui(z, w, l); }
0803   static void eval(mpz_ptr z, unsigned long int l, mpz_srcptr w)
0804   {
0805     if (mpz_sgn(w) >= 0)
0806       {
0807     if (mpz_fits_ulong_p(w))
0808       mpz_set_ui(z, l % mpz_get_ui(w));
0809     else
0810       mpz_set_ui(z, l);
0811       }
0812     else
0813       {
0814     mpz_neg(z, w);
0815     if (mpz_fits_ulong_p(z))
0816       mpz_set_ui(z, l % mpz_get_ui(z));
0817     else
0818       mpz_set_ui(z, l);
0819       }
0820   }
0821   static void eval(mpz_ptr z, mpz_srcptr w, signed long int l)
0822   {
0823     mpz_tdiv_r_ui (z, w, __gmpxx_abs_ui(l));
0824   }
0825   static void eval(mpz_ptr z, signed long int l, mpz_srcptr w)
0826   {
0827     if (mpz_fits_slong_p(w))
0828       mpz_set_si(z, l % mpz_get_si(w));
0829     else
0830       {
0831         /* if w is bigger than a long then the remainder is l unchanged,
0832            unless l==LONG_MIN and w==-LONG_MIN in which case it's 0 */
0833         mpz_set_si (z, mpz_cmpabs_ui (w, __gmpxx_abs_ui(l)) == 0 ? 0 : l);
0834       }
0835   }
0836   static void eval(mpz_ptr z, mpz_srcptr w, double d)
0837   {  __GMPXX_TMPZ_D;    mpz_tdiv_r (z, w, temp); }
0838   static void eval(mpz_ptr z, double d, mpz_srcptr w)
0839   {  __GMPXX_TMPZ_D;    mpz_tdiv_r (z, temp, w); }
0840 };
0841 
0842 struct __gmp_binary_and
0843 {
0844   static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v)
0845   { mpz_and(z, w, v); }
0846 
0847   static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l)
0848   {  __GMPXX_TMPZ_UI;   mpz_and (z, w, temp);  }
0849   static void eval(mpz_ptr z, unsigned long int l, mpz_srcptr w)
0850   { eval(z, w, l);  }
0851   static void eval(mpz_ptr z, mpz_srcptr w, signed long int l)
0852   {  __GMPXX_TMPZ_SI;   mpz_and (z, w, temp);  }
0853   static void eval(mpz_ptr z, signed long int l, mpz_srcptr w)
0854   { eval(z, w, l);  }
0855   static void eval(mpz_ptr z, mpz_srcptr w, double d)
0856   {  __GMPXX_TMPZ_D;    mpz_and (z, w, temp); }
0857   static void eval(mpz_ptr z, double d, mpz_srcptr w)
0858   { eval(z, w, d);  }
0859 };
0860 
0861 struct __gmp_binary_ior
0862 {
0863   static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v)
0864   { mpz_ior(z, w, v); }
0865   static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l)
0866   {  __GMPXX_TMPZ_UI;   mpz_ior (z, w, temp);  }
0867   static void eval(mpz_ptr z, unsigned long int l, mpz_srcptr w)
0868   { eval(z, w, l);  }
0869   static void eval(mpz_ptr z, mpz_srcptr w, signed long int l)
0870   {  __GMPXX_TMPZ_SI;   mpz_ior (z, w, temp);  }
0871   static void eval(mpz_ptr z, signed long int l, mpz_srcptr w)
0872   { eval(z, w, l);  }
0873   static void eval(mpz_ptr z, mpz_srcptr w, double d)
0874   {  __GMPXX_TMPZ_D;    mpz_ior (z, w, temp); }
0875   static void eval(mpz_ptr z, double d, mpz_srcptr w)
0876   { eval(z, w, d);  }
0877 };
0878 
0879 struct __gmp_binary_xor
0880 {
0881   static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v)
0882   { mpz_xor(z, w, v); }
0883   static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l)
0884   {  __GMPXX_TMPZ_UI;   mpz_xor (z, w, temp);  }
0885   static void eval(mpz_ptr z, unsigned long int l, mpz_srcptr w)
0886   { eval(z, w, l);  }
0887   static void eval(mpz_ptr z, mpz_srcptr w, signed long int l)
0888   {  __GMPXX_TMPZ_SI;   mpz_xor (z, w, temp);  }
0889   static void eval(mpz_ptr z, signed long int l, mpz_srcptr w)
0890   { eval(z, w, l);  }
0891   static void eval(mpz_ptr z, mpz_srcptr w, double d)
0892   {  __GMPXX_TMPZ_D;    mpz_xor (z, w, temp); }
0893   static void eval(mpz_ptr z, double d, mpz_srcptr w)
0894   { eval(z, w, d);  }
0895 };
0896 
0897 struct __gmp_cmp_function
0898 {
0899   static int eval(mpz_srcptr z, mpz_srcptr w) { return mpz_cmp(z, w); }
0900 
0901   static int eval(mpz_srcptr z, unsigned long int l)
0902   { return mpz_cmp_ui(z, l); }
0903   static int eval(unsigned long int l, mpz_srcptr z)
0904   { return -mpz_cmp_ui(z, l); }
0905   static int eval(mpz_srcptr z, signed long int l)
0906   { return mpz_cmp_si(z, l); }
0907   static int eval(signed long int l, mpz_srcptr z)
0908   { return -mpz_cmp_si(z, l); }
0909   static int eval(mpz_srcptr z, double d)
0910   { return mpz_cmp_d(z, d); }
0911   static int eval(double d, mpz_srcptr z)
0912   { return -mpz_cmp_d(z, d); }
0913 
0914   static int eval(mpq_srcptr q, mpq_srcptr r) { return mpq_cmp(q, r); }
0915 
0916   static int eval(mpq_srcptr q, unsigned long int l)
0917   { return mpq_cmp_ui(q, l, 1); }
0918   static int eval(unsigned long int l, mpq_srcptr q)
0919   { return -mpq_cmp_ui(q, l, 1); }
0920   static int eval(mpq_srcptr q, signed long int l)
0921   { return mpq_cmp_si(q, l, 1); }
0922   static int eval(signed long int l, mpq_srcptr q)
0923   { return -mpq_cmp_si(q, l, 1); }
0924   static int eval(mpq_srcptr q, double d)
0925   {  __GMPXX_TMPQ_D;    return mpq_cmp (q, temp); }
0926   static int eval(double d, mpq_srcptr q)
0927   {  __GMPXX_TMPQ_D;    return mpq_cmp (temp, q); }
0928   static int eval(mpq_srcptr q, mpz_srcptr z)
0929   { return mpq_cmp_z(q, z); }
0930   static int eval(mpz_srcptr z, mpq_srcptr q)
0931   { return -mpq_cmp_z(q, z); }
0932 
0933   static int eval(mpf_srcptr f, mpf_srcptr g) { return mpf_cmp(f, g); }
0934 
0935   static int eval(mpf_srcptr f, unsigned long int l)
0936   { return mpf_cmp_ui(f, l); }
0937   static int eval(unsigned long int l, mpf_srcptr f)
0938   { return -mpf_cmp_ui(f, l); }
0939   static int eval(mpf_srcptr f, signed long int l)
0940   { return mpf_cmp_si(f, l); }
0941   static int eval(signed long int l, mpf_srcptr f)
0942   { return -mpf_cmp_si(f, l); }
0943   static int eval(mpf_srcptr f, double d)
0944   { return mpf_cmp_d(f, d); }
0945   static int eval(double d, mpf_srcptr f)
0946   { return -mpf_cmp_d(f, d); }
0947   static int eval(mpf_srcptr f, mpz_srcptr z)
0948   { return mpf_cmp_z(f, z); }
0949   static int eval(mpz_srcptr z, mpf_srcptr f)
0950   { return -mpf_cmp_z(f, z); }
0951   static int eval(mpf_srcptr f, mpq_srcptr q)
0952   {
0953     mpf_t qf;
0954     mpf_init(qf); /* Should we use the precision of f?  */
0955     mpf_set_q(qf, q);
0956     int ret = eval(f, qf);
0957     mpf_clear(qf);
0958     return ret;
0959   }
0960   static int eval(mpq_srcptr q, mpf_srcptr f)
0961   { return -eval(f, q); }
0962 };
0963 
0964 struct __gmp_binary_equal
0965 {
0966   static bool eval(mpz_srcptr z, mpz_srcptr w) { return mpz_cmp(z, w) == 0; }
0967 
0968   static bool eval(mpz_srcptr z, unsigned long int l)
0969   { return mpz_cmp_ui(z, l) == 0; }
0970   static bool eval(unsigned long int l, mpz_srcptr z)
0971   { return eval(z, l); }
0972   static bool eval(mpz_srcptr z, signed long int l)
0973   { return mpz_cmp_si(z, l) == 0; }
0974   static bool eval(signed long int l, mpz_srcptr z)
0975   { return eval(z, l); }
0976   static bool eval(mpz_srcptr z, double d)
0977   { return mpz_cmp_d(z, d) == 0; }
0978   static bool eval(double d, mpz_srcptr z)
0979   { return eval(z, d); }
0980 
0981   static bool eval(mpq_srcptr q, mpq_srcptr r)
0982   { return mpq_equal(q, r) != 0; }
0983 
0984   static bool eval(mpq_srcptr q, unsigned long int l)
0985   { return ((__GMPXX_CONSTANT(l) && l == 0) ||
0986         mpz_cmp_ui(mpq_denref(q), 1) == 0) &&
0987       mpz_cmp_ui(mpq_numref(q), l) == 0; }
0988   static bool eval(unsigned long int l, mpq_srcptr q)
0989   { return eval(q, l); }
0990   static bool eval(mpq_srcptr q, signed long int l)
0991   { return ((__GMPXX_CONSTANT(l) && l == 0) ||
0992         mpz_cmp_ui(mpq_denref(q), 1) == 0) &&
0993       mpz_cmp_si(mpq_numref(q), l) == 0; }
0994   static bool eval(signed long int l, mpq_srcptr q)
0995   { return eval(q, l); }
0996   static bool eval(mpq_srcptr q, double d)
0997   {  __GMPXX_TMPQ_D;    return mpq_equal (q, temp) != 0; }
0998   static bool eval(double d, mpq_srcptr q)
0999   { return eval(q, d); }
1000   static bool eval(mpq_srcptr q, mpz_srcptr z)
1001   { return mpz_cmp_ui(mpq_denref(q), 1) == 0 && mpz_cmp(mpq_numref(q), z) == 0; }
1002   static bool eval(mpz_srcptr z, mpq_srcptr q)
1003   { return eval(q, z); }
1004 
1005   static bool eval(mpf_srcptr f, mpf_srcptr g) { return mpf_cmp(f, g) == 0; }
1006 
1007   static bool eval(mpf_srcptr f, unsigned long int l)
1008   { return mpf_cmp_ui(f, l) == 0; }
1009   static bool eval(unsigned long int l, mpf_srcptr f)
1010   { return eval(f, l); }
1011   static bool eval(mpf_srcptr f, signed long int l)
1012   { return mpf_cmp_si(f, l) == 0; }
1013   static bool eval(signed long int l, mpf_srcptr f)
1014   { return eval(f, l); }
1015   static bool eval(mpf_srcptr f, double d)
1016   { return mpf_cmp_d(f, d) == 0; }
1017   static bool eval(double d, mpf_srcptr f)
1018   { return eval(f, d); }
1019   static bool eval(mpf_srcptr f, mpz_srcptr z)
1020   { return mpf_cmp_z(f, z) == 0; }
1021   static bool eval(mpz_srcptr z, mpf_srcptr f)
1022   { return eval(f, z); }
1023   static bool eval(mpf_srcptr f, mpq_srcptr q)
1024   { return __gmp_cmp_function::eval(f, q) == 0; }
1025   static bool eval(mpq_srcptr q, mpf_srcptr f)
1026   { return eval(f, q); }
1027 };
1028 
1029 struct __gmp_binary_less
1030 {
1031   static bool eval(mpz_srcptr z, mpz_srcptr w) { return mpz_cmp(z, w) < 0; }
1032 
1033   static bool eval(mpz_srcptr z, unsigned long int l)
1034   { return mpz_cmp_ui(z, l) < 0; }
1035   static bool eval(unsigned long int l, mpz_srcptr z)
1036   { return mpz_cmp_ui(z, l) > 0; }
1037   static bool eval(mpz_srcptr z, signed long int l)
1038   { return mpz_cmp_si(z, l) < 0; }
1039   static bool eval(signed long int l, mpz_srcptr z)
1040   { return mpz_cmp_si(z, l) > 0; }
1041   static bool eval(mpz_srcptr z, double d)
1042   { return mpz_cmp_d(z, d) < 0; }
1043   static bool eval(double d, mpz_srcptr z)
1044   { return mpz_cmp_d(z, d) > 0; }
1045 
1046   static bool eval(mpq_srcptr q, mpq_srcptr r) { return mpq_cmp(q, r) < 0; }
1047 
1048   static bool eval(mpq_srcptr q, unsigned long int l)
1049   { return mpq_cmp_ui(q, l, 1) < 0; }
1050   static bool eval(unsigned long int l, mpq_srcptr q)
1051   { return mpq_cmp_ui(q, l, 1) > 0; }
1052   static bool eval(mpq_srcptr q, signed long int l)
1053   { return mpq_cmp_si(q, l, 1) < 0; }
1054   static bool eval(signed long int l, mpq_srcptr q)
1055   { return mpq_cmp_si(q, l, 1) > 0; }
1056   static bool eval(mpq_srcptr q, double d)
1057   {  __GMPXX_TMPQ_D;    return mpq_cmp (q, temp) < 0; }
1058   static bool eval(double d, mpq_srcptr q)
1059   {  __GMPXX_TMPQ_D;    return mpq_cmp (temp, q) < 0; }
1060   static bool eval(mpq_srcptr q, mpz_srcptr z)
1061   { return mpq_cmp_z(q, z) < 0; }
1062   static bool eval(mpz_srcptr z, mpq_srcptr q)
1063   { return mpq_cmp_z(q, z) > 0; }
1064 
1065   static bool eval(mpf_srcptr f, mpf_srcptr g) { return mpf_cmp(f, g) < 0; }
1066 
1067   static bool eval(mpf_srcptr f, unsigned long int l)
1068   { return mpf_cmp_ui(f, l) < 0; }
1069   static bool eval(unsigned long int l, mpf_srcptr f)
1070   { return mpf_cmp_ui(f, l) > 0; }
1071   static bool eval(mpf_srcptr f, signed long int l)
1072   { return mpf_cmp_si(f, l) < 0; }
1073   static bool eval(signed long int l, mpf_srcptr f)
1074   { return mpf_cmp_si(f, l) > 0; }
1075   static bool eval(mpf_srcptr f, double d)
1076   { return mpf_cmp_d(f, d) < 0; }
1077   static bool eval(double d, mpf_srcptr f)
1078   { return mpf_cmp_d(f, d) > 0; }
1079   static bool eval(mpf_srcptr f, mpz_srcptr z)
1080   { return mpf_cmp_z(f, z) < 0; }
1081   static bool eval(mpz_srcptr z, mpf_srcptr f)
1082   { return mpf_cmp_z(f, z) > 0; }
1083   static bool eval(mpf_srcptr f, mpq_srcptr q)
1084   { return __gmp_cmp_function::eval(f, q) < 0; }
1085   static bool eval(mpq_srcptr q, mpf_srcptr f)
1086   { return __gmp_cmp_function::eval(q, f) < 0; }
1087 };
1088 
1089 struct __gmp_binary_greater
1090 {
1091   template <class T, class U>
1092   static inline bool eval(T t, U u) { return __gmp_binary_less::eval(u, t); }
1093 };
1094 
1095 struct __gmp_unary_increment
1096 {
1097   static void eval(mpz_ptr z) { mpz_add_ui(z, z, 1); }
1098   static void eval(mpq_ptr q)
1099   { mpz_add(mpq_numref(q), mpq_numref(q), mpq_denref(q)); }
1100   static void eval(mpf_ptr f) { mpf_add_ui(f, f, 1); }
1101 };
1102 
1103 struct __gmp_unary_decrement
1104 {
1105   static void eval(mpz_ptr z) { mpz_sub_ui(z, z, 1); }
1106   static void eval(mpq_ptr q)
1107   { mpz_sub(mpq_numref(q), mpq_numref(q), mpq_denref(q)); }
1108   static void eval(mpf_ptr f) { mpf_sub_ui(f, f, 1); }
1109 };
1110 
1111 struct __gmp_abs_function
1112 {
1113   static void eval(mpz_ptr z, mpz_srcptr w) { mpz_abs(z, w); }
1114   static void eval(mpq_ptr q, mpq_srcptr r) { mpq_abs(q, r); }
1115   static void eval(mpf_ptr f, mpf_srcptr g) { mpf_abs(f, g); }
1116 };
1117 
1118 struct __gmp_trunc_function
1119 {
1120   static void eval(mpf_ptr f, mpf_srcptr g) { mpf_trunc(f, g); }
1121 };
1122 
1123 struct __gmp_floor_function
1124 {
1125   static void eval(mpf_ptr f, mpf_srcptr g) { mpf_floor(f, g); }
1126 };
1127 
1128 struct __gmp_ceil_function
1129 {
1130   static void eval(mpf_ptr f, mpf_srcptr g) { mpf_ceil(f, g); }
1131 };
1132 
1133 struct __gmp_sqrt_function
1134 {
1135   static void eval(mpz_ptr z, mpz_srcptr w) { mpz_sqrt(z, w); }
1136   static void eval(mpf_ptr f, mpf_srcptr g) { mpf_sqrt(f, g); }
1137 };
1138 
1139 struct __gmp_hypot_function
1140 {
1141   static void eval(mpf_ptr f, mpf_srcptr g, mpf_srcptr h)
1142   {
1143     mpf_t temp;
1144     mpf_init2(temp, mpf_get_prec(f));
1145     mpf_mul(temp, g, g);
1146     mpf_mul(f, h, h);
1147     mpf_add(f, f, temp);
1148     mpf_sqrt(f, f);
1149     mpf_clear(temp);
1150   }
1151 
1152   static void eval(mpf_ptr f, mpf_srcptr g, unsigned long int l)
1153   {
1154     mpf_t temp;
1155     mpf_init2(temp, mpf_get_prec(f));
1156     mpf_mul(temp, g, g);
1157     mpf_set_ui(f, l);
1158     mpf_mul_ui(f, f, l);
1159     mpf_add(f, f, temp);
1160     mpf_clear(temp);
1161     mpf_sqrt(f, f);
1162   }
1163   static void eval(mpf_ptr f, unsigned long int l, mpf_srcptr g)
1164   { eval(f, g, l); }
1165   static void eval(mpf_ptr f, mpf_srcptr g, signed long int l)
1166   { eval(f, g, __gmpxx_abs_ui(l)); }
1167   static void eval(mpf_ptr f, signed long int l, mpf_srcptr g)
1168   { eval(f, g, l); }
1169   static void eval(mpf_ptr f, mpf_srcptr g, double d)
1170   {
1171     mpf_t temp;
1172     mpf_init2(temp, mpf_get_prec(f));
1173     mpf_mul(temp, g, g);
1174     mpf_set_d(f, d);
1175     mpf_mul(f, f, f);
1176     mpf_add(f, f, temp);
1177     mpf_sqrt(f, f);
1178     mpf_clear(temp);
1179   }
1180   static void eval(mpf_ptr f, double d, mpf_srcptr g)
1181   { eval(f, g, d); }
1182 };
1183 
1184 struct __gmp_sgn_function
1185 {
1186   static int eval(mpz_srcptr z) { return mpz_sgn(z); }
1187   static int eval(mpq_srcptr q) { return mpq_sgn(q); }
1188   static int eval(mpf_srcptr f) { return mpf_sgn(f); }
1189 };
1190 
1191 struct __gmp_gcd_function
1192 {
1193   static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v)
1194   { mpz_gcd(z, w, v); }
1195   static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l)
1196   { mpz_gcd_ui(z, w, l); }
1197   static void eval(mpz_ptr z, unsigned long int l, mpz_srcptr w)
1198   { eval(z, w, l); }
1199   static void eval(mpz_ptr z, mpz_srcptr w, signed long int l)
1200   { eval(z, w, __gmpxx_abs_ui(l)); }
1201   static void eval(mpz_ptr z, signed long int l, mpz_srcptr w)
1202   { eval(z, w, l); }
1203   static void eval(mpz_ptr z, mpz_srcptr w, double d)
1204   {  __GMPXX_TMPZ_D;    mpz_gcd (z, w, temp); }
1205   static void eval(mpz_ptr z, double d, mpz_srcptr w)
1206   { eval(z, w, d); }
1207 };
1208 
1209 struct __gmp_lcm_function
1210 {
1211   static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v)
1212   { mpz_lcm(z, w, v); }
1213   static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l)
1214   { mpz_lcm_ui(z, w, l); }
1215   static void eval(mpz_ptr z, unsigned long int l, mpz_srcptr w)
1216   { eval(z, w, l); }
1217   static void eval(mpz_ptr z, mpz_srcptr w, signed long int l)
1218   { eval(z, w, __gmpxx_abs_ui(l)); }
1219   static void eval(mpz_ptr z, signed long int l, mpz_srcptr w)
1220   { eval(z, w, l); }
1221   static void eval(mpz_ptr z, mpz_srcptr w, double d)
1222   {  __GMPXX_TMPZ_D;    mpz_lcm (z, w, temp); }
1223   static void eval(mpz_ptr z, double d, mpz_srcptr w)
1224   { eval(z, w, d); }
1225 };
1226 
1227 struct __gmp_rand_function
1228 {
1229   static void eval(mpz_ptr z, gmp_randstate_t s, mp_bitcnt_t l)
1230   { mpz_urandomb(z, s, l); }
1231   static void eval(mpz_ptr z, gmp_randstate_t s, mpz_srcptr w)
1232   { mpz_urandomm(z, s, w); }
1233   static void eval(mpf_ptr f, gmp_randstate_t s, mp_bitcnt_t prec)
1234   { mpf_urandomb(f, s, prec); }
1235 };
1236 
1237 struct __gmp_fac_function
1238 {
1239   static void eval(mpz_ptr z, unsigned long l) { mpz_fac_ui(z, l); }
1240   static void eval(mpz_ptr z, signed long l)
1241   {
1242     if (l < 0)
1243       throw std::domain_error ("factorial(negative)");
1244     eval(z, static_cast<unsigned long>(l));
1245   }
1246   static void eval(mpz_ptr z, mpz_srcptr w)
1247   {
1248     if (!mpz_fits_ulong_p(w))
1249       {
1250     if (mpz_sgn(w) < 0)
1251       throw std::domain_error ("factorial(negative)");
1252     else
1253       throw std::bad_alloc(); // or std::overflow_error ("factorial")?
1254       }
1255     eval(z, mpz_get_ui(w));
1256   }
1257   static void eval(mpz_ptr z, double d)
1258   {  __GMPXX_TMPZ_D;    eval (z, temp); }
1259 };
1260 
1261 struct __gmp_primorial_function
1262 {
1263   static void eval(mpz_ptr z, unsigned long l) { mpz_primorial_ui(z, l); }
1264   static void eval(mpz_ptr z, signed long l)
1265   {
1266     if (l < 0)
1267       throw std::domain_error ("primorial(negative)");
1268     eval(z, static_cast<unsigned long>(l));
1269   }
1270   static void eval(mpz_ptr z, mpz_srcptr w)
1271   {
1272     if (!mpz_fits_ulong_p(w))
1273       {
1274     if (mpz_sgn(w) < 0)
1275       throw std::domain_error ("primorial(negative)");
1276     else
1277       throw std::bad_alloc(); // or std::overflow_error ("primorial")?
1278       }
1279     eval(z, mpz_get_ui(w));
1280   }
1281   static void eval(mpz_ptr z, double d)
1282   {  __GMPXX_TMPZ_D;    eval (z, temp); }
1283 };
1284 
1285 struct __gmp_fib_function
1286 {
1287   static void eval(mpz_ptr z, unsigned long l) { mpz_fib_ui(z, l); }
1288   static void eval(mpz_ptr z, signed long l)
1289   {
1290     if (l < 0)
1291       {
1292     eval(z, -static_cast<unsigned long>(l));
1293     if ((l & 1) == 0)
1294       mpz_neg(z, z);
1295       }
1296     else
1297       eval(z, static_cast<unsigned long>(l));
1298   }
1299   static void eval(mpz_ptr z, mpz_srcptr w)
1300   {
1301     if (!mpz_fits_slong_p(w))
1302       throw std::bad_alloc(); // or std::overflow_error ("fibonacci")?
1303     eval(z, mpz_get_si(w));
1304   }
1305   static void eval(mpz_ptr z, double d)
1306   {  __GMPXX_TMPZ_D;    eval (z, temp); }
1307 };
1308 
1309 
1310 /**************** Auxiliary classes ****************/
1311 
1312 /* this is much the same as gmp_allocated_string in gmp-impl.h
1313    since gmp-impl.h is not publicly available, I redefine it here
1314    I use a different name to avoid possible clashes */
1315 
1316 extern "C" {
1317   typedef void (*__gmp_freefunc_t) (void *, size_t);
1318 }
1319 struct __gmp_alloc_cstring
1320 {
1321   char *str;
1322   __gmp_alloc_cstring(char *s) { str = s; }
1323   ~__gmp_alloc_cstring()
1324   {
1325     __gmp_freefunc_t freefunc;
1326     mp_get_memory_functions (NULL, NULL, &freefunc);
1327     (*freefunc) (str, std::strlen(str)+1);
1328   }
1329 };
1330 
1331 
1332 // general expression template class
1333 template <class T, class U>
1334 class __gmp_expr;
1335 
1336 
1337 // templates for resolving expression types
1338 template <class T>
1339 struct __gmp_resolve_ref
1340 {
1341   typedef T ref_type;
1342 };
1343 
1344 template <class T, class U>
1345 struct __gmp_resolve_ref<__gmp_expr<T, U> >
1346 {
1347   typedef const __gmp_expr<T, U> & ref_type;
1348 };
1349 
1350 
1351 template <class T, class U = T>
1352 struct __gmp_resolve_expr;
1353 
1354 template <>
1355 struct __gmp_resolve_expr<mpz_t>
1356 {
1357   typedef mpz_t value_type;
1358   typedef mpz_ptr ptr_type;
1359   typedef mpz_srcptr srcptr_type;
1360 };
1361 
1362 template <>
1363 struct __gmp_resolve_expr<mpq_t>
1364 {
1365   typedef mpq_t value_type;
1366   typedef mpq_ptr ptr_type;
1367   typedef mpq_srcptr srcptr_type;
1368 };
1369 
1370 template <>
1371 struct __gmp_resolve_expr<mpf_t>
1372 {
1373   typedef mpf_t value_type;
1374   typedef mpf_ptr ptr_type;
1375   typedef mpf_srcptr srcptr_type;
1376 };
1377 
1378 template <>
1379 struct __gmp_resolve_expr<mpz_t, mpq_t>
1380 {
1381   typedef mpq_t value_type;
1382 };
1383 
1384 template <>
1385 struct __gmp_resolve_expr<mpq_t, mpz_t>
1386 {
1387   typedef mpq_t value_type;
1388 };
1389 
1390 template <>
1391 struct __gmp_resolve_expr<mpz_t, mpf_t>
1392 {
1393   typedef mpf_t value_type;
1394 };
1395 
1396 template <>
1397 struct __gmp_resolve_expr<mpf_t, mpz_t>
1398 {
1399   typedef mpf_t value_type;
1400 };
1401 
1402 template <>
1403 struct __gmp_resolve_expr<mpq_t, mpf_t>
1404 {
1405   typedef mpf_t value_type;
1406 };
1407 
1408 template <>
1409 struct __gmp_resolve_expr<mpf_t, mpq_t>
1410 {
1411   typedef mpf_t value_type;
1412 };
1413 
1414 #if __GMPXX_USE_CXX11
1415 namespace std {
1416   template <class T, class U, class V, class W>
1417   struct common_type <__gmp_expr<T, U>, __gmp_expr<V, W> >
1418   {
1419   private:
1420     typedef typename __gmp_resolve_expr<T, V>::value_type X;
1421   public:
1422     typedef __gmp_expr<X, X> type;
1423   };
1424 
1425   template <class T, class U>
1426   struct common_type <__gmp_expr<T, U> >
1427   {
1428     typedef __gmp_expr<T, T> type;
1429   };
1430 
1431 #define __GMPXX_DECLARE_COMMON_TYPE(typ)    \
1432   template <class T, class U>           \
1433   struct common_type <__gmp_expr<T, U>, typ >   \
1434   {                     \
1435     typedef __gmp_expr<T, T> type;      \
1436   };                        \
1437                         \
1438   template <class T, class U>           \
1439   struct common_type <typ, __gmp_expr<T, U> >   \
1440   {                     \
1441     typedef __gmp_expr<T, T> type;      \
1442   }
1443 
1444   __GMPXX_DECLARE_COMMON_TYPE(signed char);
1445   __GMPXX_DECLARE_COMMON_TYPE(unsigned char);
1446   __GMPXX_DECLARE_COMMON_TYPE(signed int);
1447   __GMPXX_DECLARE_COMMON_TYPE(unsigned int);
1448   __GMPXX_DECLARE_COMMON_TYPE(signed short int);
1449   __GMPXX_DECLARE_COMMON_TYPE(unsigned short int);
1450   __GMPXX_DECLARE_COMMON_TYPE(signed long int);
1451   __GMPXX_DECLARE_COMMON_TYPE(unsigned long int);
1452   __GMPXX_DECLARE_COMMON_TYPE(float);
1453   __GMPXX_DECLARE_COMMON_TYPE(double);
1454 #undef __GMPXX_DECLARE_COMMON_TYPE
1455 }
1456 #endif
1457 
1458 // classes for evaluating unary and binary expressions
1459 template <class T, class Op>
1460 struct __gmp_unary_expr
1461 {
1462   typename __gmp_resolve_ref<T>::ref_type val;
1463 
1464   __gmp_unary_expr(const T &v) : val(v) { }
1465 private:
1466   __gmp_unary_expr();
1467 };
1468 
1469 template <class T, class U, class Op>
1470 struct __gmp_binary_expr
1471 {
1472   typename __gmp_resolve_ref<T>::ref_type val1;
1473   typename __gmp_resolve_ref<U>::ref_type val2;
1474 
1475   __gmp_binary_expr(const T &v1, const U &v2) : val1(v1), val2(v2) { }
1476 private:
1477   __gmp_binary_expr();
1478 };
1479 
1480 
1481 
1482 /**************** Macros for in-class declarations ****************/
1483 /* This is just repetitive code that is easier to maintain if it's written
1484    only once */
1485 
1486 #define __GMPP_DECLARE_COMPOUND_OPERATOR(fun)                         \
1487   template <class T, class U>                                         \
1488   __gmp_expr<value_type, value_type> & fun(const __gmp_expr<T, U> &);
1489 
1490 #define __GMPN_DECLARE_COMPOUND_OPERATOR(fun) \
1491   __gmp_expr & fun(signed char);              \
1492   __gmp_expr & fun(unsigned char);            \
1493   __gmp_expr & fun(signed int);               \
1494   __gmp_expr & fun(unsigned int);             \
1495   __gmp_expr & fun(signed short int);         \
1496   __gmp_expr & fun(unsigned short int);       \
1497   __gmp_expr & fun(signed long int);          \
1498   __gmp_expr & fun(unsigned long int);        \
1499   __gmp_expr & fun(float);                    \
1500   __gmp_expr & fun(double);                   \
1501   /* __gmp_expr & fun(long double); */
1502 
1503 #define __GMP_DECLARE_COMPOUND_OPERATOR(fun) \
1504 __GMPP_DECLARE_COMPOUND_OPERATOR(fun)        \
1505 __GMPN_DECLARE_COMPOUND_OPERATOR(fun)
1506 
1507 #define __GMP_DECLARE_COMPOUND_OPERATOR_UI(fun) \
1508   __gmp_expr & fun(mp_bitcnt_t);
1509 
1510 #define __GMP_DECLARE_INCREMENT_OPERATOR(fun) \
1511   inline __gmp_expr & fun();                  \
1512   inline __gmp_expr fun(int);
1513 
1514 #define __GMPXX_DEFINE_ARITHMETIC_CONSTRUCTORS      \
1515   __gmp_expr(signed char c) { init_si(c); }     \
1516   __gmp_expr(unsigned char c) { init_ui(c); }       \
1517   __gmp_expr(signed int i) { init_si(i); }      \
1518   __gmp_expr(unsigned int i) { init_ui(i); }        \
1519   __gmp_expr(signed short int s) { init_si(s); }    \
1520   __gmp_expr(unsigned short int s) { init_ui(s); }  \
1521   __gmp_expr(signed long int l) { init_si(l); }     \
1522   __gmp_expr(unsigned long int l) { init_ui(l); }   \
1523   __gmp_expr(float f) { init_d(f); }            \
1524   __gmp_expr(double d) { init_d(d); }
1525 
1526 #define __GMPXX_DEFINE_ARITHMETIC_ASSIGNMENTS       \
1527   __gmp_expr & operator=(signed char c) { assign_si(c); return *this; } \
1528   __gmp_expr & operator=(unsigned char c) { assign_ui(c); return *this; } \
1529   __gmp_expr & operator=(signed int i) { assign_si(i); return *this; } \
1530   __gmp_expr & operator=(unsigned int i) { assign_ui(i); return *this; } \
1531   __gmp_expr & operator=(signed short int s) { assign_si(s); return *this; } \
1532   __gmp_expr & operator=(unsigned short int s) { assign_ui(s); return *this; } \
1533   __gmp_expr & operator=(signed long int l) { assign_si(l); return *this; } \
1534   __gmp_expr & operator=(unsigned long int l) { assign_ui(l); return *this; } \
1535   __gmp_expr & operator=(float f) { assign_d(f); return *this; } \
1536   __gmp_expr & operator=(double d) { assign_d(d); return *this; }
1537 
1538 #define __GMPP_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun)                 \
1539 template <class U>                                                           \
1540 static __gmp_expr<T, __gmp_unary_expr<__gmp_expr<T, U>, eval_fun> >          \
1541 fun(const __gmp_expr<T, U> &expr);
1542 
1543 #define __GMPNN_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, type, bigtype) \
1544 static inline __gmp_expr<T, __gmp_unary_expr<bigtype, eval_fun> >            \
1545 fun(type expr);
1546 
1547 #define __GMPNS_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, type)  \
1548 __GMPNN_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, type, signed long)
1549 #define __GMPNU_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, type)  \
1550 __GMPNN_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, type, unsigned long)
1551 #define __GMPND_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, type)  \
1552 __GMPNN_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, type, double)
1553 
1554 #define __GMPN_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun)                 \
1555 __GMPNS_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, signed char)           \
1556 __GMPNU_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, unsigned char)         \
1557 __GMPNS_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, signed int)            \
1558 __GMPNU_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, unsigned int)          \
1559 __GMPNS_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, signed short int)      \
1560 __GMPNU_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, unsigned short int)    \
1561 __GMPNS_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, signed long int)       \
1562 __GMPNU_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, unsigned long int)     \
1563 __GMPND_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, float)                 \
1564 __GMPND_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, double)
1565 
1566 #define __GMP_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun)                  \
1567 __GMPP_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun)                         \
1568 __GMPN_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun)
1569 
1570 /**************** mpz_class -- wrapper for mpz_t ****************/
1571 
1572 template <>
1573 class __gmp_expr<mpz_t, mpz_t>
1574 {
1575 private:
1576   typedef mpz_t value_type;
1577   value_type mp;
1578 
1579   // Helper functions used for all arithmetic types
1580   void assign_ui(unsigned long l)
1581   {
1582     if (__GMPXX_CONSTANT_TRUE(l == 0))
1583       __get_mp()->_mp_size = 0;
1584     else
1585       mpz_set_ui(mp, l);
1586   }
1587   void assign_si(signed long l)
1588   {
1589     if (__GMPXX_CONSTANT_TRUE(l >= 0))
1590       assign_ui(l);
1591     else if (__GMPXX_CONSTANT_TRUE(l <= 0))
1592       {
1593     assign_ui(-static_cast<unsigned long>(l));
1594     mpz_neg(mp, mp);
1595       }
1596     else
1597       mpz_set_si(mp, l);
1598   }
1599   void assign_d (double d)
1600   {
1601     mpz_set_d (mp, d);
1602   }
1603 
1604   void init_ui(unsigned long l)
1605   {
1606     if (__GMPXX_CONSTANT_TRUE(l == 0))
1607       mpz_init(mp);
1608     else
1609       mpz_init_set_ui(mp, l);
1610   }
1611   void init_si(signed long l)
1612   {
1613     if (__GMPXX_CONSTANT_TRUE(l >= 0))
1614       init_ui(l);
1615     else if (__GMPXX_CONSTANT_TRUE(l <= 0))
1616       {
1617     init_ui(-static_cast<unsigned long>(l));
1618     mpz_neg(mp, mp);
1619       }
1620     else
1621       mpz_init_set_si(mp, l);
1622   }
1623   void init_d (double d)
1624   {
1625     mpz_init_set_d (mp, d);
1626   }
1627 
1628 public:
1629   mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); }
1630 
1631   // constructors and destructor
1632   __gmp_expr() __GMPXX_NOEXCEPT { mpz_init(mp); }
1633 
1634   __gmp_expr(const __gmp_expr &z) { mpz_init_set(mp, z.mp); }
1635 #if __GMPXX_USE_CXX11
1636   __gmp_expr(__gmp_expr &&z) noexcept
1637   { *__get_mp() = *z.__get_mp(); mpz_init(z.mp); }
1638 #endif
1639   template <class T>
1640   __gmp_expr(const __gmp_expr<mpz_t, T> &expr)
1641   { mpz_init(mp); __gmp_set_expr(mp, expr); }
1642   template <class T, class U>
1643   explicit __gmp_expr(const __gmp_expr<T, U> &expr)
1644   { mpz_init(mp); __gmp_set_expr(mp, expr); }
1645 
1646   __GMPXX_DEFINE_ARITHMETIC_CONSTRUCTORS
1647 
1648   explicit __gmp_expr(const char *s, int base = 0)
1649   {
1650     if (mpz_init_set_str (mp, s, base) != 0)
1651       {
1652         mpz_clear (mp);
1653         throw std::invalid_argument ("mpz_set_str");
1654       }
1655   }
1656   explicit __gmp_expr(const std::string &s, int base = 0)
1657   {
1658     if (mpz_init_set_str(mp, s.c_str(), base) != 0)
1659       {
1660         mpz_clear (mp);
1661         throw std::invalid_argument ("mpz_set_str");
1662       }
1663   }
1664 
1665   explicit __gmp_expr(mpz_srcptr z) { mpz_init_set(mp, z); }
1666 
1667   ~__gmp_expr() { mpz_clear(mp); }
1668 
1669   void swap(__gmp_expr& z) __GMPXX_NOEXCEPT
1670   { std::swap(*__get_mp(), *z.__get_mp()); }
1671 
1672   // assignment operators
1673   __gmp_expr & operator=(const __gmp_expr &z)
1674   { mpz_set(mp, z.mp); return *this; }
1675 #if __GMPXX_USE_CXX11
1676   __gmp_expr & operator=(__gmp_expr &&z) noexcept
1677   { swap(z); return *this; }
1678 #endif
1679   template <class T, class U>
1680   __gmp_expr<value_type, value_type> & operator=(const __gmp_expr<T, U> &expr)
1681   { __gmp_set_expr(mp, expr); return *this; }
1682 
1683   __GMPXX_DEFINE_ARITHMETIC_ASSIGNMENTS
1684 
1685   __gmp_expr & operator=(const char *s)
1686   {
1687     if (mpz_set_str (mp, s, 0) != 0)
1688       throw std::invalid_argument ("mpz_set_str");
1689     return *this;
1690   }
1691   __gmp_expr & operator=(const std::string &s)
1692   {
1693     if (mpz_set_str(mp, s.c_str(), 0) != 0)
1694       throw std::invalid_argument ("mpz_set_str");
1695     return *this;
1696   }
1697 
1698   // string input/output functions
1699   int set_str(const char *s, int base)
1700   { return mpz_set_str(mp, s, base); }
1701   int set_str(const std::string &s, int base)
1702   { return mpz_set_str(mp, s.c_str(), base); }
1703   std::string get_str(int base = 10) const
1704   {
1705     __gmp_alloc_cstring temp(mpz_get_str(0, base, mp));
1706     return std::string(temp.str);
1707   }
1708 
1709   // conversion functions
1710   mpz_srcptr __get_mp() const { return mp; }
1711   mpz_ptr __get_mp() { return mp; }
1712   mpz_srcptr get_mpz_t() const { return mp; }
1713   mpz_ptr get_mpz_t() { return mp; }
1714 
1715   signed long int get_si() const { return mpz_get_si(mp); }
1716   unsigned long int get_ui() const { return mpz_get_ui(mp); }
1717   double get_d() const { return mpz_get_d(mp); }
1718 
1719   // bool fits_schar_p() const { return mpz_fits_schar_p(mp); }
1720   // bool fits_uchar_p() const { return mpz_fits_uchar_p(mp); }
1721   bool fits_sint_p() const { return mpz_fits_sint_p(mp); }
1722   bool fits_uint_p() const { return mpz_fits_uint_p(mp); }
1723   bool fits_sshort_p() const { return mpz_fits_sshort_p(mp); }
1724   bool fits_ushort_p() const { return mpz_fits_ushort_p(mp); }
1725   bool fits_slong_p() const { return mpz_fits_slong_p(mp); }
1726   bool fits_ulong_p() const { return mpz_fits_ulong_p(mp); }
1727   // bool fits_float_p() const { return mpz_fits_float_p(mp); }
1728   // bool fits_double_p() const { return mpz_fits_double_p(mp); }
1729   // bool fits_ldouble_p() const { return mpz_fits_ldouble_p(mp); }
1730 
1731 #if __GMPXX_USE_CXX11
1732   explicit operator bool() const { return __get_mp()->_mp_size != 0; }
1733 #endif
1734 
1735   // member operators
1736   __GMP_DECLARE_COMPOUND_OPERATOR(operator+=)
1737   __GMP_DECLARE_COMPOUND_OPERATOR(operator-=)
1738   __GMP_DECLARE_COMPOUND_OPERATOR(operator*=)
1739   __GMP_DECLARE_COMPOUND_OPERATOR(operator/=)
1740   __GMP_DECLARE_COMPOUND_OPERATOR(operator%=)
1741 
1742   __GMP_DECLARE_COMPOUND_OPERATOR(operator&=)
1743   __GMP_DECLARE_COMPOUND_OPERATOR(operator|=)
1744   __GMP_DECLARE_COMPOUND_OPERATOR(operator^=)
1745 
1746   __GMP_DECLARE_COMPOUND_OPERATOR_UI(operator<<=)
1747   __GMP_DECLARE_COMPOUND_OPERATOR_UI(operator>>=)
1748 
1749   __GMP_DECLARE_INCREMENT_OPERATOR(operator++)
1750   __GMP_DECLARE_INCREMENT_OPERATOR(operator--)
1751 
1752   __GMP_DECLARE_UNARY_STATIC_MEMFUN(mpz_t, factorial, __gmp_fac_function)
1753   __GMP_DECLARE_UNARY_STATIC_MEMFUN(mpz_t, primorial, __gmp_primorial_function)
1754   __GMP_DECLARE_UNARY_STATIC_MEMFUN(mpz_t, fibonacci, __gmp_fib_function)
1755 };
1756 
1757 typedef __gmp_expr<mpz_t, mpz_t> mpz_class;
1758 
1759 
1760 /**************** mpq_class -- wrapper for mpq_t ****************/
1761 
1762 template <>
1763 class __gmp_expr<mpq_t, mpq_t>
1764 {
1765 private:
1766   typedef mpq_t value_type;
1767   value_type mp;
1768 
1769   // Helper functions used for all arithmetic types
1770   void assign_ui(unsigned long l) { mpq_set_ui(mp, l, 1); }
1771   void assign_si(signed long l)
1772   {
1773     if (__GMPXX_CONSTANT_TRUE(l >= 0))
1774       assign_ui(l);
1775     else
1776       mpq_set_si(mp, l, 1);
1777   }
1778   void assign_d (double d)        { mpq_set_d (mp, d); }
1779 
1780   void init_ui(unsigned long l) { mpq_init(mp); get_num() = l; }
1781   void init_si(signed long l)   { mpq_init(mp); get_num() = l; }
1782   void init_d (double d)    { mpq_init(mp); assign_d (d); }
1783 
1784 public:
1785   mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); }
1786   void canonicalize() { mpq_canonicalize(mp); }
1787 
1788   // constructors and destructor
1789   __gmp_expr() { mpq_init(mp); }
1790 
1791   __gmp_expr(const __gmp_expr &q)
1792   {
1793     mpz_init_set(mpq_numref(mp), mpq_numref(q.mp));
1794     mpz_init_set(mpq_denref(mp), mpq_denref(q.mp));
1795   }
1796 #if __GMPXX_USE_CXX11
1797   __gmp_expr(__gmp_expr &&q)
1798   { *mp = *q.mp; mpq_init(q.mp); }
1799   __gmp_expr(mpz_class &&z)
1800   {
1801     *mpq_numref(mp) = *z.get_mpz_t();
1802     mpz_init_set_ui(mpq_denref(mp), 1);
1803     mpz_init(z.get_mpz_t());
1804   }
1805 #endif
1806   template <class T>
1807   __gmp_expr(const __gmp_expr<mpz_t, T> &expr)
1808   { mpq_init(mp); __gmp_set_expr(mp, expr); }
1809   template <class T>
1810   __gmp_expr(const __gmp_expr<mpq_t, T> &expr)
1811   { mpq_init(mp); __gmp_set_expr(mp, expr); }
1812   template <class T, class U>
1813   explicit __gmp_expr(const __gmp_expr<T, U> &expr)
1814   { mpq_init(mp); __gmp_set_expr(mp, expr); }
1815 
1816   __GMPXX_DEFINE_ARITHMETIC_CONSTRUCTORS
1817 
1818   explicit __gmp_expr(const char *s, int base = 0)
1819   {
1820     mpq_init (mp);
1821     // If s is the literal 0, we meant to call another constructor.
1822     // If s just happens to evaluate to 0, we would crash, so whatever.
1823     if (s == 0)
1824       {
1825     // Don't turn mpq_class(0,0) into 0
1826     mpz_set_si(mpq_denref(mp), base);
1827       }
1828     else if (mpq_set_str(mp, s, base) != 0)
1829       {
1830         mpq_clear (mp);
1831         throw std::invalid_argument ("mpq_set_str");
1832       }
1833   }
1834   explicit __gmp_expr(const std::string &s, int base = 0)
1835   {
1836     mpq_init(mp);
1837     if (mpq_set_str (mp, s.c_str(), base) != 0)
1838       {
1839         mpq_clear (mp);
1840         throw std::invalid_argument ("mpq_set_str");
1841       }
1842   }
1843   explicit __gmp_expr(mpq_srcptr q)
1844   {
1845     mpz_init_set(mpq_numref(mp), mpq_numref(q));
1846     mpz_init_set(mpq_denref(mp), mpq_denref(q));
1847   }
1848 
1849   __gmp_expr(const mpz_class &num, const mpz_class &den)
1850   {
1851     mpz_init_set(mpq_numref(mp), num.get_mpz_t());
1852     mpz_init_set(mpq_denref(mp), den.get_mpz_t());
1853   }
1854 
1855   ~__gmp_expr() { mpq_clear(mp); }
1856 
1857   void swap(__gmp_expr& q) __GMPXX_NOEXCEPT { std::swap(*mp, *q.mp); }
1858 
1859   // assignment operators
1860   __gmp_expr & operator=(const __gmp_expr &q)
1861   { mpq_set(mp, q.mp); return *this; }
1862 #if __GMPXX_USE_CXX11
1863   __gmp_expr & operator=(__gmp_expr &&q) noexcept
1864   { swap(q); return *this; }
1865   __gmp_expr & operator=(mpz_class &&z) noexcept
1866   { get_num() = std::move(z); get_den() = 1u; return *this; }
1867 #endif
1868   template <class T, class U>
1869   __gmp_expr<value_type, value_type> & operator=(const __gmp_expr<T, U> &expr)
1870   { __gmp_set_expr(mp, expr); return *this; }
1871 
1872   __GMPXX_DEFINE_ARITHMETIC_ASSIGNMENTS
1873 
1874   __gmp_expr & operator=(const char *s)
1875   {
1876     if (mpq_set_str (mp, s, 0) != 0)
1877       throw std::invalid_argument ("mpq_set_str");
1878     return *this;
1879   }
1880   __gmp_expr & operator=(const std::string &s)
1881   {
1882     if (mpq_set_str(mp, s.c_str(), 0) != 0)
1883       throw std::invalid_argument ("mpq_set_str");
1884     return *this;
1885   }
1886 
1887   // string input/output functions
1888   int set_str(const char *s, int base)
1889   { return mpq_set_str(mp, s, base); }
1890   int set_str(const std::string &s, int base)
1891   { return mpq_set_str(mp, s.c_str(), base); }
1892   std::string get_str(int base = 10) const
1893   {
1894     __gmp_alloc_cstring temp(mpq_get_str(0, base, mp));
1895     return std::string(temp.str);
1896   }
1897 
1898   // conversion functions
1899 
1900   // casting a reference to an mpz_t to mpz_class & is a dirty hack.
1901   // It kind of works because the internal representation of mpz_class is
1902   // exactly an mpz_t, but compilers are allowed to assume that mpq_class
1903   // and mpz_class do not alias... In mpz_class, we avoid using mp directly,
1904   // to reduce the risks of such problematic optimizations.
1905   const mpz_class & get_num() const
1906   { return reinterpret_cast<const mpz_class &>(*mpq_numref(mp)); }
1907   mpz_class & get_num()
1908   { return reinterpret_cast<mpz_class &>(*mpq_numref(mp)); }
1909   const mpz_class & get_den() const
1910   { return reinterpret_cast<const mpz_class &>(*mpq_denref(mp)); }
1911   mpz_class & get_den()
1912   { return reinterpret_cast<mpz_class &>(*mpq_denref(mp)); }
1913 
1914   mpq_srcptr __get_mp() const { return mp; }
1915   mpq_ptr __get_mp() { return mp; }
1916   mpq_srcptr get_mpq_t() const { return mp; }
1917   mpq_ptr get_mpq_t() { return mp; }
1918 
1919   mpz_srcptr get_num_mpz_t() const { return mpq_numref(mp); }
1920   mpz_ptr get_num_mpz_t() { return mpq_numref(mp); }
1921   mpz_srcptr get_den_mpz_t() const { return mpq_denref(mp); }
1922   mpz_ptr get_den_mpz_t() { return mpq_denref(mp); }
1923 
1924   double get_d() const { return mpq_get_d(mp); }
1925 
1926 #if __GMPXX_USE_CXX11
1927   explicit operator bool() const { return mpq_numref(mp)->_mp_size != 0; }
1928 #endif
1929 
1930   // compound assignments
1931   __GMP_DECLARE_COMPOUND_OPERATOR(operator+=)
1932   __GMP_DECLARE_COMPOUND_OPERATOR(operator-=)
1933   __GMP_DECLARE_COMPOUND_OPERATOR(operator*=)
1934   __GMP_DECLARE_COMPOUND_OPERATOR(operator/=)
1935 
1936   __GMP_DECLARE_COMPOUND_OPERATOR_UI(operator<<=)
1937   __GMP_DECLARE_COMPOUND_OPERATOR_UI(operator>>=)
1938 
1939   __GMP_DECLARE_INCREMENT_OPERATOR(operator++)
1940   __GMP_DECLARE_INCREMENT_OPERATOR(operator--)
1941 };
1942 
1943 typedef __gmp_expr<mpq_t, mpq_t> mpq_class;
1944 
1945 
1946 /**************** mpf_class -- wrapper for mpf_t ****************/
1947 
1948 template <>
1949 class __gmp_expr<mpf_t, mpf_t>
1950 {
1951 private:
1952   typedef mpf_t value_type;
1953   value_type mp;
1954 
1955   // Helper functions used for all arithmetic types
1956   void assign_ui(unsigned long l) { mpf_set_ui(mp, l); }
1957   void assign_si(signed long l)
1958   {
1959     if (__GMPXX_CONSTANT_TRUE(l >= 0))
1960       assign_ui(l);
1961     else
1962       mpf_set_si(mp, l);
1963   }
1964   void assign_d (double d)        { mpf_set_d (mp, d); }
1965 
1966   void init_ui(unsigned long l)
1967   {
1968     if (__GMPXX_CONSTANT_TRUE(l == 0))
1969       mpf_init(mp);
1970     else
1971       mpf_init_set_ui(mp, l);
1972   }
1973   void init_si(signed long l)
1974   {
1975     if (__GMPXX_CONSTANT_TRUE(l >= 0))
1976       init_ui(l);
1977     else
1978       mpf_init_set_si(mp, l);
1979   }
1980   void init_d (double d)    { mpf_init_set_d (mp, d); }
1981 
1982 public:
1983   mp_bitcnt_t get_prec() const { return mpf_get_prec(mp); }
1984 
1985   void set_prec(mp_bitcnt_t prec) { mpf_set_prec(mp, prec); }
1986   void set_prec_raw(mp_bitcnt_t prec) { mpf_set_prec_raw(mp, prec); }
1987 
1988   // constructors and destructor
1989   __gmp_expr() { mpf_init(mp); }
1990 
1991   __gmp_expr(const __gmp_expr &f)
1992   { mpf_init2(mp, f.get_prec()); mpf_set(mp, f.mp); }
1993 #if __GMPXX_USE_CXX11
1994   __gmp_expr(__gmp_expr &&f)
1995   { *mp = *f.mp; mpf_init2(f.mp, get_prec()); }
1996 #endif
1997   __gmp_expr(const __gmp_expr &f, mp_bitcnt_t prec)
1998   { mpf_init2(mp, prec); mpf_set(mp, f.mp); }
1999   template <class T, class U>
2000   __gmp_expr(const __gmp_expr<T, U> &expr)
2001   { mpf_init2(mp, expr.get_prec()); __gmp_set_expr(mp, expr); }
2002   template <class T, class U>
2003   __gmp_expr(const __gmp_expr<T, U> &expr, mp_bitcnt_t prec)
2004   { mpf_init2(mp, prec); __gmp_set_expr(mp, expr); }
2005 
2006   __GMPXX_DEFINE_ARITHMETIC_CONSTRUCTORS
2007 
2008   __gmp_expr(signed char c, mp_bitcnt_t prec)
2009   { mpf_init2(mp, prec); mpf_set_si(mp, c); }
2010   __gmp_expr(unsigned char c, mp_bitcnt_t prec)
2011   { mpf_init2(mp, prec); mpf_set_ui(mp, c); }
2012 
2013   __gmp_expr(signed int i, mp_bitcnt_t prec)
2014   { mpf_init2(mp, prec); mpf_set_si(mp, i); }
2015   __gmp_expr(unsigned int i, mp_bitcnt_t prec)
2016   { mpf_init2(mp, prec); mpf_set_ui(mp, i); }
2017 
2018   __gmp_expr(signed short int s, mp_bitcnt_t prec)
2019   { mpf_init2(mp, prec); mpf_set_si(mp, s); }
2020   __gmp_expr(unsigned short int s, mp_bitcnt_t prec)
2021   { mpf_init2(mp, prec); mpf_set_ui(mp, s); }
2022 
2023   __gmp_expr(signed long int l, mp_bitcnt_t prec)
2024   { mpf_init2(mp, prec); mpf_set_si(mp, l); }
2025   __gmp_expr(unsigned long int l, mp_bitcnt_t prec)
2026   { mpf_init2(mp, prec); mpf_set_ui(mp, l); }
2027 
2028   __gmp_expr(float f, mp_bitcnt_t prec)
2029   { mpf_init2(mp, prec); mpf_set_d(mp, f); }
2030   __gmp_expr(double d, mp_bitcnt_t prec)
2031   { mpf_init2(mp, prec); mpf_set_d(mp, d); }
2032   // __gmp_expr(long double ld) { mpf_init_set_d(mp, ld); }
2033   // __gmp_expr(long double ld, mp_bitcnt_t prec)
2034   // { mpf_init2(mp, prec); mpf_set_d(mp, ld); }
2035 
2036   explicit __gmp_expr(const char *s)
2037   {
2038     if (mpf_init_set_str (mp, s, 0) != 0)
2039       {
2040         mpf_clear (mp);
2041         throw std::invalid_argument ("mpf_set_str");
2042       }
2043   }
2044   __gmp_expr(const char *s, mp_bitcnt_t prec, int base = 0)
2045   {
2046     mpf_init2(mp, prec);
2047     if (mpf_set_str(mp, s, base) != 0)
2048       {
2049         mpf_clear (mp);
2050         throw std::invalid_argument ("mpf_set_str");
2051       }
2052   }
2053   explicit __gmp_expr(const std::string &s)
2054   {
2055     if (mpf_init_set_str(mp, s.c_str(), 0) != 0)
2056       {
2057         mpf_clear (mp);
2058         throw std::invalid_argument ("mpf_set_str");
2059       }
2060   }
2061   __gmp_expr(const std::string &s, mp_bitcnt_t prec, int base = 0)
2062   {
2063     mpf_init2(mp, prec);
2064     if (mpf_set_str(mp, s.c_str(), base) != 0)
2065       {
2066         mpf_clear (mp);
2067         throw std::invalid_argument ("mpf_set_str");
2068       }
2069   }
2070 
2071   explicit __gmp_expr(mpf_srcptr f)
2072   { mpf_init2(mp, mpf_get_prec(f)); mpf_set(mp, f); }
2073   __gmp_expr(mpf_srcptr f, mp_bitcnt_t prec)
2074   { mpf_init2(mp, prec); mpf_set(mp, f); }
2075 
2076   ~__gmp_expr() { mpf_clear(mp); }
2077 
2078   void swap(__gmp_expr& f) __GMPXX_NOEXCEPT { std::swap(*mp, *f.mp); }
2079 
2080   // assignment operators
2081   __gmp_expr & operator=(const __gmp_expr &f)
2082   { mpf_set(mp, f.mp); return *this; }
2083 #if __GMPXX_USE_CXX11
2084   __gmp_expr & operator=(__gmp_expr &&f) noexcept
2085   { swap(f); return *this; }
2086 #endif
2087   template <class T, class U>
2088   __gmp_expr<value_type, value_type> & operator=(const __gmp_expr<T, U> &expr)
2089   { __gmp_set_expr(mp, expr); return *this; }
2090 
2091   __GMPXX_DEFINE_ARITHMETIC_ASSIGNMENTS
2092 
2093   __gmp_expr & operator=(const char *s)
2094   {
2095     if (mpf_set_str (mp, s, 0) != 0)
2096       throw std::invalid_argument ("mpf_set_str");
2097     return *this;
2098   }
2099   __gmp_expr & operator=(const std::string &s)
2100   {
2101     if (mpf_set_str(mp, s.c_str(), 0) != 0)
2102       throw std::invalid_argument ("mpf_set_str");
2103     return *this;
2104   }
2105 
2106   // string input/output functions
2107   int set_str(const char *s, int base)
2108   { return mpf_set_str(mp, s, base); }
2109   int set_str(const std::string &s, int base)
2110   { return mpf_set_str(mp, s.c_str(), base); }
2111   std::string get_str(mp_exp_t &expo, int base = 10, size_t size = 0) const
2112   {
2113     __gmp_alloc_cstring temp(mpf_get_str(0, &expo, base, size, mp));
2114     return std::string(temp.str);
2115   }
2116 
2117   // conversion functions
2118   mpf_srcptr __get_mp() const { return mp; }
2119   mpf_ptr __get_mp() { return mp; }
2120   mpf_srcptr get_mpf_t() const { return mp; }
2121   mpf_ptr get_mpf_t() { return mp; }
2122 
2123   signed long int get_si() const { return mpf_get_si(mp); }
2124   unsigned long int get_ui() const { return mpf_get_ui(mp); }
2125   double get_d() const { return mpf_get_d(mp); }
2126 
2127   // bool fits_schar_p() const { return mpf_fits_schar_p(mp); }
2128   // bool fits_uchar_p() const { return mpf_fits_uchar_p(mp); }
2129   bool fits_sint_p() const { return mpf_fits_sint_p(mp); }
2130   bool fits_uint_p() const { return mpf_fits_uint_p(mp); }
2131   bool fits_sshort_p() const { return mpf_fits_sshort_p(mp); }
2132   bool fits_ushort_p() const { return mpf_fits_ushort_p(mp); }
2133   bool fits_slong_p() const { return mpf_fits_slong_p(mp); }
2134   bool fits_ulong_p() const { return mpf_fits_ulong_p(mp); }
2135   // bool fits_float_p() const { return mpf_fits_float_p(mp); }
2136   // bool fits_double_p() const { return mpf_fits_double_p(mp); }
2137   // bool fits_ldouble_p() const { return mpf_fits_ldouble_p(mp); }
2138 
2139 #if __GMPXX_USE_CXX11
2140   explicit operator bool() const { return mpf_sgn(mp) != 0; }
2141 #endif
2142 
2143   // compound assignments
2144   __GMP_DECLARE_COMPOUND_OPERATOR(operator+=)
2145   __GMP_DECLARE_COMPOUND_OPERATOR(operator-=)
2146   __GMP_DECLARE_COMPOUND_OPERATOR(operator*=)
2147   __GMP_DECLARE_COMPOUND_OPERATOR(operator/=)
2148 
2149   __GMP_DECLARE_COMPOUND_OPERATOR_UI(operator<<=)
2150   __GMP_DECLARE_COMPOUND_OPERATOR_UI(operator>>=)
2151 
2152   __GMP_DECLARE_INCREMENT_OPERATOR(operator++)
2153   __GMP_DECLARE_INCREMENT_OPERATOR(operator--)
2154 };
2155 
2156 typedef __gmp_expr<mpf_t, mpf_t> mpf_class;
2157 
2158 
2159 
2160 /**************** User-defined literals ****************/
2161 
2162 #if __GMPXX_USE_CXX11
2163 inline mpz_class operator"" _mpz(const char* s)
2164 {
2165   return mpz_class(s);
2166 }
2167 
2168 inline mpq_class operator"" _mpq(const char* s)
2169 {
2170   mpq_class q;
2171   q.get_num() = s;
2172   return q;
2173 }
2174 
2175 inline mpf_class operator"" _mpf(const char* s)
2176 {
2177   return mpf_class(s);
2178 }
2179 #endif
2180 
2181 /**************** I/O operators ****************/
2182 
2183 // these should (and will) be provided separately
2184 
2185 template <class T, class U>
2186 inline std::ostream & operator<<
2187 (std::ostream &o, const __gmp_expr<T, U> &expr)
2188 {
2189   __gmp_expr<T, T> const& temp(expr);
2190   return o << temp.__get_mp();
2191 }
2192 
2193 template <class T>
2194 inline std::istream & operator>>(std::istream &i, __gmp_expr<T, T> &expr)
2195 {
2196   return i >> expr.__get_mp();
2197 }
2198 
2199 /*
2200 // you might want to uncomment this
2201 inline std::istream & operator>>(std::istream &i, mpq_class &q)
2202 {
2203   i >> q.get_mpq_t();
2204   q.canonicalize();
2205   return i;
2206 }
2207 */
2208 
2209 
2210 /**************** Functions for type conversion ****************/
2211 
2212 inline void __gmp_set_expr(mpz_ptr z, const mpz_class &w)
2213 {
2214   mpz_set(z, w.get_mpz_t());
2215 }
2216 
2217 template <class T>
2218 inline void __gmp_set_expr(mpz_ptr z, const __gmp_expr<mpz_t, T> &expr)
2219 {
2220   expr.eval(z);
2221 }
2222 
2223 template <class T>
2224 inline void __gmp_set_expr(mpz_ptr z, const __gmp_expr<mpq_t, T> &expr)
2225 {
2226   mpq_class const& temp(expr);
2227   mpz_set_q(z, temp.get_mpq_t());
2228 }
2229 
2230 template <class T>
2231 inline void __gmp_set_expr(mpz_ptr z, const __gmp_expr<mpf_t, T> &expr)
2232 {
2233   mpf_class const& temp(expr);
2234   mpz_set_f(z, temp.get_mpf_t());
2235 }
2236 
2237 inline void __gmp_set_expr(mpq_ptr q, const mpz_class &z)
2238 {
2239   mpq_set_z(q, z.get_mpz_t());
2240 }
2241 
2242 template <class T>
2243 inline void __gmp_set_expr(mpq_ptr q, const __gmp_expr<mpz_t, T> &expr)
2244 {
2245   __gmp_set_expr(mpq_numref(q), expr);
2246   mpz_set_ui(mpq_denref(q), 1);
2247 }
2248 
2249 inline void __gmp_set_expr(mpq_ptr q, const mpq_class &r)
2250 {
2251   mpq_set(q, r.get_mpq_t());
2252 }
2253 
2254 template <class T>
2255 inline void __gmp_set_expr(mpq_ptr q, const __gmp_expr<mpq_t, T> &expr)
2256 {
2257   expr.eval(q);
2258 }
2259 
2260 template <class T>
2261 inline void __gmp_set_expr(mpq_ptr q, const __gmp_expr<mpf_t, T> &expr)
2262 {
2263   mpf_class const& temp(expr);
2264   mpq_set_f(q, temp.get_mpf_t());
2265 }
2266 
2267 template <class T>
2268 inline void __gmp_set_expr(mpf_ptr f, const __gmp_expr<mpz_t, T> &expr)
2269 {
2270   mpz_class const& temp(expr);
2271   mpf_set_z(f, temp.get_mpz_t());
2272 }
2273 
2274 template <class T>
2275 inline void __gmp_set_expr(mpf_ptr f, const __gmp_expr<mpq_t, T> &expr)
2276 {
2277   mpq_class const& temp(expr);
2278   mpf_set_q(f, temp.get_mpq_t());
2279 }
2280 
2281 inline void __gmp_set_expr(mpf_ptr f, const mpf_class &g)
2282 {
2283   mpf_set(f, g.get_mpf_t());
2284 }
2285 
2286 template <class T>
2287 inline void __gmp_set_expr(mpf_ptr f, const __gmp_expr<mpf_t, T> &expr)
2288 {
2289   expr.eval(f);
2290 }
2291 
2292 
2293 /* Temporary objects */
2294 
2295 template <class T>
2296 class __gmp_temp
2297 {
2298   __gmp_expr<T, T> val;
2299   public:
2300   template<class U, class V>
2301   __gmp_temp(U const& u, V) : val (u) {}
2302   typename __gmp_resolve_expr<T>::srcptr_type
2303   __get_mp() const { return val.__get_mp(); }
2304 };
2305 
2306 template <>
2307 class __gmp_temp <mpf_t>
2308 {
2309   mpf_class val;
2310   public:
2311   template<class U>
2312   __gmp_temp(U const& u, mpf_ptr res) : val (u, mpf_get_prec(res)) {}
2313   mpf_srcptr __get_mp() const { return val.__get_mp(); }
2314 };
2315 
2316 /**************** Specializations of __gmp_expr ****************/
2317 /* The eval() method of __gmp_expr<T, U> evaluates the corresponding
2318    expression and assigns the result to its argument, which is either an
2319    mpz_t, mpq_t, or mpf_t as specified by the T argument.
2320    Compound expressions are evaluated recursively (temporaries are created
2321    to hold intermediate values), while for simple expressions the eval()
2322    method of the appropriate function object (available as the Op argument
2323    of either __gmp_unary_expr<T, Op> or __gmp_binary_expr<T, U, Op>) is
2324    called. */
2325 
2326 
2327 /**************** Unary expressions ****************/
2328 /* cases:
2329    - simple:   argument is mp*_class, that is, __gmp_expr<T, T>
2330    - compound: argument is __gmp_expr<T, U> (with U not equal to T) */
2331 
2332 
2333 // simple expressions
2334 
2335 template <class T, class Op>
2336 class __gmp_expr<T, __gmp_unary_expr<__gmp_expr<T, T>, Op> >
2337 {
2338 private:
2339   typedef __gmp_expr<T, T> val_type;
2340 
2341   __gmp_unary_expr<val_type, Op> expr;
2342 public:
2343   explicit __gmp_expr(const val_type &val) : expr(val) { }
2344   void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
2345   { Op::eval(p, expr.val.__get_mp()); }
2346   const val_type & get_val() const { return expr.val; }
2347   mp_bitcnt_t get_prec() const { return expr.val.get_prec(); }
2348 };
2349 
2350 
2351 // simple expressions, U is a built-in numerical type
2352 
2353 template <class T, class U, class Op>
2354 class __gmp_expr<T, __gmp_unary_expr<U, Op> >
2355 {
2356 private:
2357   typedef U val_type;
2358 
2359   __gmp_unary_expr<val_type, Op> expr;
2360 public:
2361   explicit __gmp_expr(const val_type &val) : expr(val) { }
2362   void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
2363   { Op::eval(p, expr.val); }
2364   const val_type & get_val() const { return expr.val; }
2365   mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); }
2366 };
2367 
2368 
2369 // compound expressions
2370 
2371 template <class T, class U, class Op>
2372 class __gmp_expr<T, __gmp_unary_expr<__gmp_expr<T, U>, Op> >
2373 {
2374 private:
2375   typedef __gmp_expr<T, U> val_type;
2376 
2377   __gmp_unary_expr<val_type, Op> expr;
2378 public:
2379   explicit __gmp_expr(const val_type &val) : expr(val) { }
2380   void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
2381   { expr.val.eval(p); Op::eval(p, p); }
2382   const val_type & get_val() const { return expr.val; }
2383   mp_bitcnt_t get_prec() const { return expr.val.get_prec(); }
2384 };
2385 
2386 
2387 /**************** Binary expressions ****************/
2388 /* simple:
2389    - arguments are both mp*_class
2390    - one argument is mp*_class, one is a built-in type
2391    compound:
2392    - one is mp*_class, one is __gmp_expr<T, U>
2393    - one is __gmp_expr<T, U>, one is built-in
2394    - both arguments are __gmp_expr<...> */
2395 
2396 
2397 // simple expressions
2398 
2399 template <class T, class Op>
2400 class __gmp_expr
2401 <T, __gmp_binary_expr<__gmp_expr<T, T>, __gmp_expr<T, T>, Op> >
2402 {
2403 private:
2404   typedef __gmp_expr<T, T> val1_type;
2405   typedef __gmp_expr<T, T> val2_type;
2406 
2407   __gmp_binary_expr<val1_type, val2_type, Op> expr;
2408 public:
2409   __gmp_expr(const val1_type &val1, const val2_type &val2)
2410     : expr(val1, val2) { }
2411   void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
2412   { Op::eval(p, expr.val1.__get_mp(), expr.val2.__get_mp()); }
2413   const val1_type & get_val1() const { return expr.val1; }
2414   const val2_type & get_val2() const { return expr.val2; }
2415   mp_bitcnt_t get_prec() const
2416   {
2417     mp_bitcnt_t prec1 = expr.val1.get_prec(),
2418       prec2 = expr.val2.get_prec();
2419     return (prec1 > prec2) ? prec1 : prec2;
2420   }
2421 };
2422 
2423 
2424 // simple expressions, U is a built-in numerical type
2425 
2426 template <class T, class U, class Op>
2427 class __gmp_expr<T, __gmp_binary_expr<__gmp_expr<T, T>, U, Op> >
2428 {
2429 private:
2430   typedef __gmp_expr<T, T> val1_type;
2431   typedef U val2_type;
2432 
2433   __gmp_binary_expr<val1_type, val2_type, Op> expr;
2434 public:
2435   __gmp_expr(const val1_type &val1, const val2_type &val2)
2436     : expr(val1, val2) { }
2437   void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
2438   { Op::eval(p, expr.val1.__get_mp(), expr.val2); }
2439   const val1_type & get_val1() const { return expr.val1; }
2440   const val2_type & get_val2() const { return expr.val2; }
2441   mp_bitcnt_t get_prec() const { return expr.val1.get_prec(); }
2442 };
2443 
2444 template <class T, class U, class Op>
2445 class __gmp_expr<T, __gmp_binary_expr<U, __gmp_expr<T, T>, Op> >
2446 {
2447 private:
2448   typedef U val1_type;
2449   typedef __gmp_expr<T, T> val2_type;
2450 
2451   __gmp_binary_expr<val1_type, val2_type, Op> expr;
2452 public:
2453   __gmp_expr(const val1_type &val1, const val2_type &val2)
2454     : expr(val1, val2) { }
2455   void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
2456   { Op::eval(p, expr.val1, expr.val2.__get_mp()); }
2457   const val1_type & get_val1() const { return expr.val1; }
2458   const val2_type & get_val2() const { return expr.val2; }
2459   mp_bitcnt_t get_prec() const { return expr.val2.get_prec(); }
2460 };
2461 
2462 
2463 // compound expressions, one argument is a subexpression
2464 
2465 template <class T, class U, class V, class Op>
2466 class __gmp_expr
2467 <T, __gmp_binary_expr<__gmp_expr<T, T>, __gmp_expr<U, V>, Op> >
2468 {
2469 private:
2470   typedef __gmp_expr<T, T> val1_type;
2471   typedef __gmp_expr<U, V> val2_type;
2472 
2473   __gmp_binary_expr<val1_type, val2_type, Op> expr;
2474 public:
2475   __gmp_expr(const val1_type &val1, const val2_type &val2)
2476     : expr(val1, val2) { }
2477   void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
2478   {
2479     if(p != expr.val1.__get_mp())
2480     {
2481       __gmp_set_expr(p, expr.val2);
2482       Op::eval(p, expr.val1.__get_mp(), p);
2483     }
2484     else
2485     {
2486       __gmp_temp<T> temp(expr.val2, p);
2487       Op::eval(p, expr.val1.__get_mp(), temp.__get_mp());
2488     }
2489   }
2490   const val1_type & get_val1() const { return expr.val1; }
2491   const val2_type & get_val2() const { return expr.val2; }
2492   mp_bitcnt_t get_prec() const
2493   {
2494     mp_bitcnt_t prec1 = expr.val1.get_prec(),
2495       prec2 = expr.val2.get_prec();
2496     return (prec1 > prec2) ? prec1 : prec2;
2497   }
2498 };
2499 
2500 template <class T, class U, class V, class Op>
2501 class __gmp_expr
2502 <T, __gmp_binary_expr<__gmp_expr<U, V>, __gmp_expr<T, T>, Op> >
2503 {
2504 private:
2505   typedef __gmp_expr<U, V> val1_type;
2506   typedef __gmp_expr<T, T> val2_type;
2507 
2508   __gmp_binary_expr<val1_type, val2_type, Op> expr;
2509 public:
2510   __gmp_expr(const val1_type &val1, const val2_type &val2)
2511     : expr(val1, val2) { }
2512   void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
2513   {
2514     if(p != expr.val2.__get_mp())
2515     {
2516       __gmp_set_expr(p, expr.val1);
2517       Op::eval(p, p, expr.val2.__get_mp());
2518     }
2519     else
2520     {
2521       __gmp_temp<T> temp(expr.val1, p);
2522       Op::eval(p, temp.__get_mp(), expr.val2.__get_mp());
2523     }
2524   }
2525   const val1_type & get_val1() const { return expr.val1; }
2526   const val2_type & get_val2() const { return expr.val2; }
2527   mp_bitcnt_t get_prec() const
2528   {
2529     mp_bitcnt_t prec1 = expr.val1.get_prec(),
2530       prec2 = expr.val2.get_prec();
2531     return (prec1 > prec2) ? prec1 : prec2;
2532   }
2533 };
2534 
2535 template <class T, class U, class Op>
2536 class __gmp_expr
2537 <T, __gmp_binary_expr<__gmp_expr<T, T>, __gmp_expr<T, U>, Op> >
2538 {
2539 private:
2540   typedef __gmp_expr<T, T> val1_type;
2541   typedef __gmp_expr<T, U> val2_type;
2542 
2543   __gmp_binary_expr<val1_type, val2_type, Op> expr;
2544 public:
2545   __gmp_expr(const val1_type &val1, const val2_type &val2)
2546     : expr(val1, val2) { }
2547   void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
2548   {
2549     if(p != expr.val1.__get_mp())
2550     {
2551       __gmp_set_expr(p, expr.val2);
2552       Op::eval(p, expr.val1.__get_mp(), p);
2553     }
2554     else
2555     {
2556       __gmp_temp<T> temp(expr.val2, p);
2557       Op::eval(p, expr.val1.__get_mp(), temp.__get_mp());
2558     }
2559   }
2560   const val1_type & get_val1() const { return expr.val1; }
2561   const val2_type & get_val2() const { return expr.val2; }
2562   mp_bitcnt_t get_prec() const
2563   {
2564     mp_bitcnt_t prec1 = expr.val1.get_prec(),
2565       prec2 = expr.val2.get_prec();
2566     return (prec1 > prec2) ? prec1 : prec2;
2567   }
2568 };
2569 
2570 template <class T, class U, class Op>
2571 class __gmp_expr
2572 <T, __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<T, T>, Op> >
2573 {
2574 private:
2575   typedef __gmp_expr<T, U> val1_type;
2576   typedef __gmp_expr<T, T> val2_type;
2577 
2578   __gmp_binary_expr<val1_type, val2_type, Op> expr;
2579 public:
2580   __gmp_expr(const val1_type &val1, const val2_type &val2)
2581     : expr(val1, val2) { }
2582   void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
2583   {
2584     if(p != expr.val2.__get_mp())
2585     {
2586       __gmp_set_expr(p, expr.val1);
2587       Op::eval(p, p, expr.val2.__get_mp());
2588     }
2589     else
2590     {
2591       __gmp_temp<T> temp(expr.val1, p);
2592       Op::eval(p, temp.__get_mp(), expr.val2.__get_mp());
2593     }
2594   }
2595   const val1_type & get_val1() const { return expr.val1; }
2596   const val2_type & get_val2() const { return expr.val2; }
2597   mp_bitcnt_t get_prec() const
2598   {
2599     mp_bitcnt_t prec1 = expr.val1.get_prec(),
2600       prec2 = expr.val2.get_prec();
2601     return (prec1 > prec2) ? prec1 : prec2;
2602   }
2603 };
2604 
2605 
2606 // one argument is a subexpression, one is a built-in
2607 
2608 template <class T, class U, class V, class Op>
2609 class __gmp_expr<T, __gmp_binary_expr<__gmp_expr<T, U>, V, Op> >
2610 {
2611 private:
2612   typedef __gmp_expr<T, U> val1_type;
2613   typedef V val2_type;
2614 
2615   __gmp_binary_expr<val1_type, val2_type, Op> expr;
2616 public:
2617   __gmp_expr(const val1_type &val1, const val2_type &val2)
2618     : expr(val1, val2) { }
2619   void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
2620   {
2621     expr.val1.eval(p);
2622     Op::eval(p, p, expr.val2);
2623   }
2624   const val1_type & get_val1() const { return expr.val1; }
2625   const val2_type & get_val2() const { return expr.val2; }
2626   mp_bitcnt_t get_prec() const { return expr.val1.get_prec(); }
2627 };
2628 
2629 template <class T, class U, class V, class Op>
2630 class __gmp_expr<T, __gmp_binary_expr<U, __gmp_expr<T, V>, Op> >
2631 {
2632 private:
2633   typedef U val1_type;
2634   typedef __gmp_expr<T, V> val2_type;
2635 
2636   __gmp_binary_expr<val1_type, val2_type, Op> expr;
2637 public:
2638   __gmp_expr(const val1_type &val1, const val2_type &val2)
2639     : expr(val1, val2) { }
2640   void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
2641   {
2642     expr.val2.eval(p);
2643     Op::eval(p, expr.val1, p);
2644   }
2645   const val1_type & get_val1() const { return expr.val1; }
2646   const val2_type & get_val2() const { return expr.val2; }
2647   mp_bitcnt_t get_prec() const { return expr.val2.get_prec(); }
2648 };
2649 
2650 
2651 // both arguments are subexpressions
2652 
2653 template <class T, class U, class V, class W, class Op>
2654 class __gmp_expr
2655 <T, __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<V, W>, Op> >
2656 {
2657 private:
2658   typedef __gmp_expr<T, U> val1_type;
2659   typedef __gmp_expr<V, W> val2_type;
2660 
2661   __gmp_binary_expr<val1_type, val2_type, Op> expr;
2662 public:
2663   __gmp_expr(const val1_type &val1, const val2_type &val2)
2664     : expr(val1, val2) { }
2665   void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
2666   {
2667     __gmp_temp<T> temp2(expr.val2, p);
2668     expr.val1.eval(p);
2669     Op::eval(p, p, temp2.__get_mp());
2670   }
2671   const val1_type & get_val1() const { return expr.val1; }
2672   const val2_type & get_val2() const { return expr.val2; }
2673   mp_bitcnt_t get_prec() const
2674   {
2675     mp_bitcnt_t prec1 = expr.val1.get_prec(),
2676       prec2 = expr.val2.get_prec();
2677     return (prec1 > prec2) ? prec1 : prec2;
2678   }
2679 };
2680 
2681 template <class T, class U, class V, class W, class Op>
2682 class __gmp_expr
2683 <T, __gmp_binary_expr<__gmp_expr<U, V>, __gmp_expr<T, W>, Op> >
2684 {
2685 private:
2686   typedef __gmp_expr<U, V> val1_type;
2687   typedef __gmp_expr<T, W> val2_type;
2688 
2689   __gmp_binary_expr<val1_type, val2_type, Op> expr;
2690 public:
2691   __gmp_expr(const val1_type &val1, const val2_type &val2)
2692     : expr(val1, val2) { }
2693   void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
2694   {
2695     __gmp_temp<T> temp1(expr.val1, p);
2696     expr.val2.eval(p);
2697     Op::eval(p, temp1.__get_mp(), p);
2698   }
2699   const val1_type & get_val1() const { return expr.val1; }
2700   const val2_type & get_val2() const { return expr.val2; }
2701   mp_bitcnt_t get_prec() const
2702   {
2703     mp_bitcnt_t prec1 = expr.val1.get_prec(),
2704       prec2 = expr.val2.get_prec();
2705     return (prec1 > prec2) ? prec1 : prec2;
2706   }
2707 };
2708 
2709 template <class T, class U, class V, class Op>
2710 class __gmp_expr
2711 <T, __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<T, V>, Op> >
2712 {
2713 private:
2714   typedef __gmp_expr<T, U> val1_type;
2715   typedef __gmp_expr<T, V> val2_type;
2716 
2717   __gmp_binary_expr<val1_type, val2_type, Op> expr;
2718 public:
2719   __gmp_expr(const val1_type &val1, const val2_type &val2)
2720     : expr(val1, val2) { }
2721   void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
2722   {
2723     __gmp_temp<T> temp2(expr.val2, p);
2724     expr.val1.eval(p);
2725     Op::eval(p, p, temp2.__get_mp());
2726   }
2727   const val1_type & get_val1() const { return expr.val1; }
2728   const val2_type & get_val2() const { return expr.val2; }
2729   mp_bitcnt_t get_prec() const
2730   {
2731     mp_bitcnt_t prec1 = expr.val1.get_prec(),
2732       prec2 = expr.val2.get_prec();
2733     return (prec1 > prec2) ? prec1 : prec2;
2734   }
2735 };
2736 
2737 
2738 /**************** Special cases ****************/
2739 
2740 /* Some operations (i.e., add and subtract) with mixed mpz/mpq arguments
2741    can be done directly without first converting the mpz to mpq.
2742    Appropriate specializations of __gmp_expr are required. */
2743 
2744 
2745 #define __GMPZQ_DEFINE_EXPR(eval_fun)                                       \
2746                                                                             \
2747 template <>                                                                 \
2748 class __gmp_expr<mpq_t, __gmp_binary_expr<mpz_class, mpq_class, eval_fun> > \
2749 {                                                                           \
2750 private:                                                                    \
2751   typedef mpz_class val1_type;                                              \
2752   typedef mpq_class val2_type;                                              \
2753                                                                             \
2754   __gmp_binary_expr<val1_type, val2_type, eval_fun> expr;                   \
2755 public:                                                                     \
2756   __gmp_expr(const val1_type &val1, const val2_type &val2)                  \
2757     : expr(val1, val2) { }                                                  \
2758   void eval(mpq_ptr q) const                                                \
2759   { eval_fun::eval(q, expr.val1.get_mpz_t(), expr.val2.get_mpq_t()); }      \
2760   const val1_type & get_val1() const { return expr.val1; }                  \
2761   const val2_type & get_val2() const { return expr.val2; }                  \
2762   mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); }           \
2763 };                                                                          \
2764                                                                             \
2765 template <>                                                                 \
2766 class __gmp_expr<mpq_t, __gmp_binary_expr<mpq_class, mpz_class, eval_fun> > \
2767 {                                                                           \
2768 private:                                                                    \
2769   typedef mpq_class val1_type;                                              \
2770   typedef mpz_class val2_type;                                              \
2771                                                                             \
2772   __gmp_binary_expr<val1_type, val2_type, eval_fun> expr;                   \
2773 public:                                                                     \
2774   __gmp_expr(const val1_type &val1, const val2_type &val2)                  \
2775     : expr(val1, val2) { }                                                  \
2776   void eval(mpq_ptr q) const                                                \
2777   { eval_fun::eval(q, expr.val1.get_mpq_t(), expr.val2.get_mpz_t()); }      \
2778   const val1_type & get_val1() const { return expr.val1; }                  \
2779   const val2_type & get_val2() const { return expr.val2; }                  \
2780   mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); }           \
2781 };                                                                          \
2782                                                                             \
2783 template <class T>                                                          \
2784 class __gmp_expr                                                            \
2785 <mpq_t, __gmp_binary_expr<mpz_class, __gmp_expr<mpq_t, T>, eval_fun> >      \
2786 {                                                                           \
2787 private:                                                                    \
2788   typedef mpz_class val1_type;                                              \
2789   typedef __gmp_expr<mpq_t, T> val2_type;                                   \
2790                                                                             \
2791   __gmp_binary_expr<val1_type, val2_type, eval_fun> expr;                   \
2792 public:                                                                     \
2793   __gmp_expr(const val1_type &val1, const val2_type &val2)                  \
2794     : expr(val1, val2) { }                                                  \
2795   void eval(mpq_ptr q) const                                                \
2796   {                                                                         \
2797     mpq_class temp(expr.val2);                                              \
2798     eval_fun::eval(q, expr.val1.get_mpz_t(), temp.get_mpq_t());             \
2799   }                                                                         \
2800   const val1_type & get_val1() const { return expr.val1; }                  \
2801   const val2_type & get_val2() const { return expr.val2; }                  \
2802   mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); }           \
2803 };                                                                          \
2804                                                                             \
2805 template <class T>                                                          \
2806 class __gmp_expr                                                            \
2807 <mpq_t, __gmp_binary_expr<mpq_class, __gmp_expr<mpz_t, T>, eval_fun> >      \
2808 {                                                                           \
2809 private:                                                                    \
2810   typedef mpq_class val1_type;                                              \
2811   typedef __gmp_expr<mpz_t, T> val2_type;                                   \
2812                                                                             \
2813   __gmp_binary_expr<val1_type, val2_type, eval_fun> expr;                   \
2814 public:                                                                     \
2815   __gmp_expr(const val1_type &val1, const val2_type &val2)                  \
2816     : expr(val1, val2) { }                                                  \
2817   void eval(mpq_ptr q) const                                                \
2818   {                                                                         \
2819     mpz_class temp(expr.val2);                                              \
2820     eval_fun::eval(q, expr.val1.get_mpq_t(), temp.get_mpz_t());             \
2821   }                                                                         \
2822   const val1_type & get_val1() const { return expr.val1; }                  \
2823   const val2_type & get_val2() const { return expr.val2; }                  \
2824   mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); }           \
2825 };                                                                          \
2826                                                                             \
2827 template <class T>                                                          \
2828 class __gmp_expr                                                            \
2829 <mpq_t, __gmp_binary_expr<__gmp_expr<mpz_t, T>, mpq_class, eval_fun> >      \
2830 {                                                                           \
2831 private:                                                                    \
2832   typedef __gmp_expr<mpz_t, T> val1_type;                                   \
2833   typedef mpq_class val2_type;                                              \
2834                                                                             \
2835   __gmp_binary_expr<val1_type, val2_type, eval_fun> expr;                   \
2836 public:                                                                     \
2837   __gmp_expr(const val1_type &val1, const val2_type &val2)                  \
2838     : expr(val1, val2) { }                                                  \
2839   void eval(mpq_ptr q) const                                                \
2840   {                                                                         \
2841     mpz_class temp(expr.val1);                                              \
2842     eval_fun::eval(q, temp.get_mpz_t(), expr.val2.get_mpq_t());             \
2843   }                                                                         \
2844   const val1_type & get_val1() const { return expr.val1; }                  \
2845   const val2_type & get_val2() const { return expr.val2; }                  \
2846   mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); }           \
2847 };                                                                          \
2848                                                                             \
2849 template <class T>                                                          \
2850 class __gmp_expr                                                            \
2851 <mpq_t, __gmp_binary_expr<__gmp_expr<mpq_t, T>, mpz_class, eval_fun> >      \
2852 {                                                                           \
2853 private:                                                                    \
2854   typedef __gmp_expr<mpq_t, T> val1_type;                                   \
2855   typedef mpz_class val2_type;                                              \
2856                                                                             \
2857   __gmp_binary_expr<val1_type, val2_type, eval_fun> expr;                   \
2858 public:                                                                     \
2859   __gmp_expr(const val1_type &val1, const val2_type &val2)                  \
2860     : expr(val1, val2) { }                                                  \
2861   void eval(mpq_ptr q) const                                                \
2862   {                                                                         \
2863     mpq_class temp(expr.val1);                                              \
2864     eval_fun::eval(q, temp.get_mpq_t(), expr.val2.get_mpz_t());             \
2865   }                                                                         \
2866   const val1_type & get_val1() const { return expr.val1; }                  \
2867   const val2_type & get_val2() const { return expr.val2; }                  \
2868   mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); }           \
2869 };                                                                          \
2870                                                                             \
2871 template <class T, class U>                                                 \
2872 class __gmp_expr<mpq_t, __gmp_binary_expr                                   \
2873 <__gmp_expr<mpz_t, T>, __gmp_expr<mpq_t, U>, eval_fun> >                    \
2874 {                                                                           \
2875 private:                                                                    \
2876   typedef __gmp_expr<mpz_t, T> val1_type;                                   \
2877   typedef __gmp_expr<mpq_t, U> val2_type;                                   \
2878                                                                             \
2879   __gmp_binary_expr<val1_type, val2_type, eval_fun> expr;                   \
2880 public:                                                                     \
2881   __gmp_expr(const val1_type &val1, const val2_type &val2)                  \
2882     : expr(val1, val2) { }                                                  \
2883   void eval(mpq_ptr q) const                                                \
2884   {                                                                         \
2885     mpz_class temp1(expr.val1);                                             \
2886     expr.val2.eval(q);                                                      \
2887     eval_fun::eval(q, temp1.get_mpz_t(), q);                                \
2888   }                                                                         \
2889   const val1_type & get_val1() const { return expr.val1; }                  \
2890   const val2_type & get_val2() const { return expr.val2; }                  \
2891   mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); }           \
2892 };                                                                          \
2893                                                                             \
2894 template <class T, class U>                                                 \
2895 class __gmp_expr<mpq_t, __gmp_binary_expr                                   \
2896 <__gmp_expr<mpq_t, T>, __gmp_expr<mpz_t, U>, eval_fun> >                    \
2897 {                                                                           \
2898 private:                                                                    \
2899   typedef __gmp_expr<mpq_t, T> val1_type;                                   \
2900   typedef __gmp_expr<mpz_t, U> val2_type;                                   \
2901                                                                             \
2902   __gmp_binary_expr<val1_type, val2_type, eval_fun> expr;                   \
2903 public:                                                                     \
2904   __gmp_expr(const val1_type &val1, const val2_type &val2)                  \
2905     : expr(val1, val2) { }                                                  \
2906   void eval(mpq_ptr q) const                                                \
2907   {                                                                         \
2908     mpz_class temp2(expr.val2);                                             \
2909     expr.val1.eval(q);                                             \
2910     eval_fun::eval(q, q, temp2.get_mpz_t());                \
2911   }                                                                         \
2912   const val1_type & get_val1() const { return expr.val1; }                  \
2913   const val2_type & get_val2() const { return expr.val2; }                  \
2914   mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); }           \
2915 };
2916 
2917 
2918 __GMPZQ_DEFINE_EXPR(__gmp_binary_plus)
2919 __GMPZQ_DEFINE_EXPR(__gmp_binary_minus)
2920 
2921 
2922 
2923 /**************** Macros for defining functions ****************/
2924 /* Results of operators and functions are instances of __gmp_expr<T, U>.
2925    T determines the numerical type of the expression: it can be either
2926    mpz_t, mpq_t, or mpf_t.  When the arguments of a binary
2927    expression have different numerical types, __gmp_resolve_expr is used
2928    to determine the "larger" type.
2929    U is either __gmp_unary_expr<V, Op> or __gmp_binary_expr<V, W, Op>,
2930    where V and W are the arguments' types -- they can in turn be
2931    expressions, thus allowing to build compound expressions to any
2932    degree of complexity.
2933    Op is a function object that must have an eval() method accepting
2934    appropriate arguments.
2935    Actual evaluation of a __gmp_expr<T, U> object is done when it gets
2936    assigned to an mp*_class ("lazy" evaluation): this is done by calling
2937    its eval() method. */
2938 
2939 
2940 // non-member unary operators and functions
2941 
2942 #define __GMP_DEFINE_UNARY_FUNCTION(fun, eval_fun)                           \
2943                                                                              \
2944 template <class T, class U>                                                  \
2945 inline __gmp_expr<T, __gmp_unary_expr<__gmp_expr<T, U>, eval_fun> >          \
2946 fun(const __gmp_expr<T, U> &expr)                                            \
2947 {                                                                            \
2948   return __gmp_expr<T, __gmp_unary_expr<__gmp_expr<T, U>, eval_fun> >(expr); \
2949 }
2950 
2951 // variant that only works for one of { mpz, mpq, mpf }
2952 
2953 #define __GMP_DEFINE_UNARY_FUNCTION_1(T, fun, eval_fun)                      \
2954                                                                              \
2955 template <class U>                                                           \
2956 inline __gmp_expr<T, __gmp_unary_expr<__gmp_expr<T, U>, eval_fun> >          \
2957 fun(const __gmp_expr<T, U> &expr)                                            \
2958 {                                                                            \
2959   return __gmp_expr<T, __gmp_unary_expr<__gmp_expr<T, U>, eval_fun> >(expr); \
2960 }
2961 
2962 #define __GMP_DEFINE_UNARY_TYPE_FUNCTION(type, fun, eval_fun) \
2963                                                               \
2964 template <class T, class U>                                   \
2965 inline type fun(const __gmp_expr<T, U> &expr)                 \
2966 {                                                             \
2967   __gmp_expr<T, T> const& temp(expr); \
2968   return eval_fun::eval(temp.__get_mp());                     \
2969 }
2970 
2971 
2972 // non-member binary operators and functions
2973 
2974 #define __GMPP_DEFINE_BINARY_FUNCTION(fun, eval_fun)                   \
2975                                                                        \
2976 template <class T, class U, class V, class W>                          \
2977 inline __gmp_expr<typename __gmp_resolve_expr<T, V>::value_type,       \
2978 __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<V, W>, eval_fun> >      \
2979 fun(const __gmp_expr<T, U> &expr1, const __gmp_expr<V, W> &expr2)      \
2980 {                                                                      \
2981   return __gmp_expr<typename __gmp_resolve_expr<T, V>::value_type,     \
2982      __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<V, W>, eval_fun> > \
2983     (expr1, expr2);                                                    \
2984 }
2985 
2986 #define __GMPNN_DEFINE_BINARY_FUNCTION(fun, eval_fun, type, bigtype)       \
2987                                                                            \
2988 template <class T, class U>                                                \
2989 inline __gmp_expr                                                          \
2990 <T, __gmp_binary_expr<__gmp_expr<T, U>, bigtype, eval_fun> >               \
2991 fun(const __gmp_expr<T, U> &expr, type t)                                  \
2992 {                                                                          \
2993   return __gmp_expr                                                        \
2994     <T, __gmp_binary_expr<__gmp_expr<T, U>, bigtype, eval_fun> >(expr, t); \
2995 }                                                                          \
2996                                                                            \
2997 template <class T, class U>                                                \
2998 inline __gmp_expr                                                          \
2999 <T, __gmp_binary_expr<bigtype, __gmp_expr<T, U>, eval_fun> >               \
3000 fun(type t, const __gmp_expr<T, U> &expr)                                  \
3001 {                                                                          \
3002   return __gmp_expr                                                        \
3003     <T, __gmp_binary_expr<bigtype, __gmp_expr<T, U>, eval_fun> >(t, expr); \
3004 }
3005 
3006 #define __GMPNS_DEFINE_BINARY_FUNCTION(fun, eval_fun, type)          \
3007 __GMPNN_DEFINE_BINARY_FUNCTION(fun, eval_fun, type, signed long int)
3008 
3009 #define __GMPNU_DEFINE_BINARY_FUNCTION(fun, eval_fun, type)            \
3010 __GMPNN_DEFINE_BINARY_FUNCTION(fun, eval_fun, type, unsigned long int)
3011 
3012 #define __GMPND_DEFINE_BINARY_FUNCTION(fun, eval_fun, type) \
3013 __GMPNN_DEFINE_BINARY_FUNCTION(fun, eval_fun, type, double)
3014 
3015 #define __GMPNLD_DEFINE_BINARY_FUNCTION(fun, eval_fun, type)     \
3016 __GMPNN_DEFINE_BINARY_FUNCTION(fun, eval_fun, type, long double)
3017 
3018 #define __GMPN_DEFINE_BINARY_FUNCTION(fun, eval_fun)              \
3019 __GMPNS_DEFINE_BINARY_FUNCTION(fun, eval_fun, signed char)        \
3020 __GMPNU_DEFINE_BINARY_FUNCTION(fun, eval_fun, unsigned char)      \
3021 __GMPNS_DEFINE_BINARY_FUNCTION(fun, eval_fun, signed int)         \
3022 __GMPNU_DEFINE_BINARY_FUNCTION(fun, eval_fun, unsigned int)       \
3023 __GMPNS_DEFINE_BINARY_FUNCTION(fun, eval_fun, signed short int)   \
3024 __GMPNU_DEFINE_BINARY_FUNCTION(fun, eval_fun, unsigned short int) \
3025 __GMPNS_DEFINE_BINARY_FUNCTION(fun, eval_fun, signed long int)    \
3026 __GMPNU_DEFINE_BINARY_FUNCTION(fun, eval_fun, unsigned long int)  \
3027 __GMPND_DEFINE_BINARY_FUNCTION(fun, eval_fun, float)              \
3028 __GMPND_DEFINE_BINARY_FUNCTION(fun, eval_fun, double)             \
3029 /* __GMPNLD_DEFINE_BINARY_FUNCTION(fun, eval_fun, long double) */
3030 
3031 #define __GMP_DEFINE_BINARY_FUNCTION(fun, eval_fun) \
3032 __GMPP_DEFINE_BINARY_FUNCTION(fun, eval_fun)        \
3033 __GMPN_DEFINE_BINARY_FUNCTION(fun, eval_fun)
3034 
3035 // variant that only works for one of { mpz, mpq, mpf }
3036 
3037 #define __GMPP_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun)              \
3038                                                                        \
3039 template <class U, class W>                                            \
3040 inline __gmp_expr<T,                                                   \
3041 __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<T, W>, eval_fun> >      \
3042 fun(const __gmp_expr<T, U> &expr1, const __gmp_expr<T, W> &expr2)      \
3043 {                                                                      \
3044   return __gmp_expr<T,                                                 \
3045      __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<T, W>, eval_fun> > \
3046     (expr1, expr2);                                                    \
3047 }
3048 
3049 #define __GMPNN_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, type, bigtype)  \
3050                                                                            \
3051 template <class U>                                                         \
3052 inline __gmp_expr                                                          \
3053 <T, __gmp_binary_expr<__gmp_expr<T, U>, bigtype, eval_fun> >               \
3054 fun(const __gmp_expr<T, U> &expr, type t)                                  \
3055 {                                                                          \
3056   return __gmp_expr                                                        \
3057     <T, __gmp_binary_expr<__gmp_expr<T, U>, bigtype, eval_fun> >(expr, t); \
3058 }                                                                          \
3059                                                                            \
3060 template <class U>                                                         \
3061 inline __gmp_expr                                                          \
3062 <T, __gmp_binary_expr<bigtype, __gmp_expr<T, U>, eval_fun> >               \
3063 fun(type t, const __gmp_expr<T, U> &expr)                                  \
3064 {                                                                          \
3065   return __gmp_expr                                                        \
3066     <T, __gmp_binary_expr<bigtype, __gmp_expr<T, U>, eval_fun> >(t, expr); \
3067 }
3068 
3069 #define __GMPNS_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, type)          \
3070 __GMPNN_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, type, signed long int)
3071 
3072 #define __GMPNU_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, type)          \
3073 __GMPNN_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, type, unsigned long int)
3074 
3075 #define __GMPND_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, type) \
3076 __GMPNN_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, type, double)
3077 
3078 #define __GMPNLD_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, type)     \
3079 __GMPNN_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, type, long double)
3080 
3081 #define __GMPN_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun)              \
3082 __GMPNS_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, signed char)        \
3083 __GMPNU_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, unsigned char)      \
3084 __GMPNS_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, signed int)         \
3085 __GMPNU_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, unsigned int)       \
3086 __GMPNS_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, signed short int)   \
3087 __GMPNU_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, unsigned short int) \
3088 __GMPNS_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, signed long int)    \
3089 __GMPNU_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, unsigned long int)  \
3090 __GMPND_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, float)              \
3091 __GMPND_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, double)             \
3092 /* __GMPNLD_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, long double) */
3093 
3094 #define __GMP_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun) \
3095 __GMPP_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun)        \
3096 __GMPN_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun)
3097 
3098 
3099 #define __GMP_DEFINE_BINARY_FUNCTION_UI(fun, eval_fun)                 \
3100                                                                        \
3101 template <class T, class U>                                            \
3102 inline __gmp_expr                                                      \
3103 <T, __gmp_binary_expr<__gmp_expr<T, U>, mp_bitcnt_t, eval_fun> > \
3104 fun(const __gmp_expr<T, U> &expr, mp_bitcnt_t l)                 \
3105 {                                                                      \
3106   return __gmp_expr<T, __gmp_binary_expr                               \
3107     <__gmp_expr<T, U>, mp_bitcnt_t, eval_fun> >(expr, l);        \
3108 }
3109 
3110 
3111 #define __GMPP_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun)         \
3112                                                                         \
3113 template <class T, class U, class V, class W>                           \
3114 inline type fun(const __gmp_expr<T, U> &expr1,                          \
3115         const __gmp_expr<V, W> &expr2)                          \
3116 {                                                                       \
3117   __gmp_expr<T, T> const& temp1(expr1);                                 \
3118   __gmp_expr<V, V> const& temp2(expr2);                                 \
3119   return eval_fun::eval(temp1.__get_mp(), temp2.__get_mp());            \
3120 }
3121 
3122 #define __GMPNN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun,   \
3123                         type2, bigtype)        \
3124                                                                    \
3125 template <class T, class U>                                        \
3126 inline type fun(const __gmp_expr<T, U> &expr, type2 t)             \
3127 {                                                                  \
3128   __gmp_expr<T, T> const& temp(expr);      \
3129   return eval_fun::eval(temp.__get_mp(), static_cast<bigtype>(t)); \
3130 }                                                                  \
3131                                                                    \
3132 template <class T, class U>                                        \
3133 inline type fun(type2 t, const __gmp_expr<T, U> &expr)             \
3134 {                                                                  \
3135   __gmp_expr<T, T> const& temp(expr);      \
3136   return eval_fun::eval(static_cast<bigtype>(t), temp.__get_mp()); \
3137 }
3138 
3139 #define __GMPNS_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, type2) \
3140 __GMPNN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun,                \
3141                     type2, signed long int)
3142 
3143 #define __GMPNU_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, type2) \
3144 __GMPNN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun,                \
3145                     type2, unsigned long int)
3146 
3147 #define __GMPND_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, type2) \
3148 __GMPNN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, type2, double)
3149 
3150 #define __GMPNLD_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, type2)     \
3151 __GMPNN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, type2, long double)
3152 
3153 #define __GMPN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun)              \
3154 __GMPNS_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, signed char)        \
3155 __GMPNU_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, unsigned char)      \
3156 __GMPNS_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, signed int)         \
3157 __GMPNU_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, unsigned int)       \
3158 __GMPNS_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, signed short int)   \
3159 __GMPNU_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, unsigned short int) \
3160 __GMPNS_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, signed long int)    \
3161 __GMPNU_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, unsigned long int)  \
3162 __GMPND_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, float)              \
3163 __GMPND_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, double)             \
3164 /* __GMPNLD_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, long double) */
3165 
3166 #define __GMP_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun) \
3167 __GMPP_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun)        \
3168 __GMPN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun)
3169 
3170 
3171 // member operators
3172 
3173 #define __GMPP_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun)                 \
3174                                                                              \
3175 template <class T, class U>                                                  \
3176 inline type##_class & type##_class::fun(const __gmp_expr<T, U> &expr)        \
3177 {                                                                            \
3178   __gmp_set_expr(mp, __gmp_expr<type##_t, __gmp_binary_expr                  \
3179          <type##_class, __gmp_expr<T, U>, eval_fun> >(*this, expr)); \
3180   return *this;                                                              \
3181 }
3182 
3183 #define __GMPNN_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun,    \
3184                      type2, bigtype)         \
3185                                                                  \
3186 inline type##_class & type##_class::fun(type2 t)                 \
3187 {                                                                \
3188   __gmp_set_expr(mp, __gmp_expr<type##_t, __gmp_binary_expr      \
3189          <type##_class, bigtype, eval_fun> >(*this, t)); \
3190   return *this;                                                  \
3191 }
3192 
3193 #define __GMPNS_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, type2) \
3194 __GMPNN_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun,                \
3195                  type2, signed long int)
3196 
3197 #define __GMPNU_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, type2) \
3198 __GMPNN_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun,                \
3199                  type2, unsigned long int)
3200 
3201 #define __GMPND_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, type2) \
3202 __GMPNN_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, type2, double)
3203 
3204 #define __GMPNLD_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, type2)     \
3205 __GMPNN_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, type2, long double)
3206 
3207 #define __GMPN_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun)              \
3208 __GMPNS_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, signed char)        \
3209 __GMPNU_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, unsigned char)      \
3210 __GMPNS_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, signed int)         \
3211 __GMPNU_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, unsigned int)       \
3212 __GMPNS_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, signed short int)   \
3213 __GMPNU_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, unsigned short int) \
3214 __GMPNS_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, signed long int)    \
3215 __GMPNU_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, unsigned long int)  \
3216 __GMPND_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, float)              \
3217 __GMPND_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, double)             \
3218 /* __GMPNLD_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, long double) */
3219 
3220 #define __GMP_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun) \
3221 __GMPP_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun)        \
3222 __GMPN_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun)
3223 
3224 #define __GMPZ_DEFINE_COMPOUND_OPERATOR(fun, eval_fun) \
3225 __GMP_DEFINE_COMPOUND_OPERATOR(mpz, fun, eval_fun)
3226 
3227 #define __GMPQ_DEFINE_COMPOUND_OPERATOR(fun, eval_fun) \
3228 __GMP_DEFINE_COMPOUND_OPERATOR(mpq, fun, eval_fun)
3229 
3230 #define __GMPF_DEFINE_COMPOUND_OPERATOR(fun, eval_fun) \
3231 __GMP_DEFINE_COMPOUND_OPERATOR(mpf, fun, eval_fun)
3232 
3233 
3234 
3235 #define __GMP_DEFINE_COMPOUND_OPERATOR_UI(type, fun, eval_fun)  \
3236                                                                 \
3237 inline type##_class & type##_class::fun(mp_bitcnt_t l)    \
3238 {                                                               \
3239   __gmp_set_expr(mp, __gmp_expr<type##_t, __gmp_binary_expr     \
3240     <type##_class, mp_bitcnt_t, eval_fun> >(*this, l));   \
3241   return *this;                                                 \
3242 }
3243 
3244 #define __GMPZ_DEFINE_COMPOUND_OPERATOR_UI(fun, eval_fun) \
3245 __GMP_DEFINE_COMPOUND_OPERATOR_UI(mpz, fun, eval_fun)
3246 
3247 #define __GMPQ_DEFINE_COMPOUND_OPERATOR_UI(fun, eval_fun) \
3248 __GMP_DEFINE_COMPOUND_OPERATOR_UI(mpq, fun, eval_fun)
3249 
3250 #define __GMPF_DEFINE_COMPOUND_OPERATOR_UI(fun, eval_fun) \
3251 __GMP_DEFINE_COMPOUND_OPERATOR_UI(mpf, fun, eval_fun)
3252 
3253 
3254 
3255 #define __GMP_DEFINE_INCREMENT_OPERATOR(type, fun, eval_fun) \
3256                                                              \
3257 inline type##_class & type##_class::fun()                    \
3258 {                                                            \
3259   eval_fun::eval(mp);                                        \
3260   return *this;                                              \
3261 }                                                            \
3262                                                              \
3263 inline type##_class type##_class::fun(int)                   \
3264 {                                                            \
3265   type##_class temp(*this);                                  \
3266   eval_fun::eval(mp);                                        \
3267   return temp;                                               \
3268 }
3269 
3270 #define __GMPZ_DEFINE_INCREMENT_OPERATOR(fun, eval_fun) \
3271 __GMP_DEFINE_INCREMENT_OPERATOR(mpz, fun, eval_fun)
3272 
3273 #define __GMPQ_DEFINE_INCREMENT_OPERATOR(fun, eval_fun) \
3274 __GMP_DEFINE_INCREMENT_OPERATOR(mpq, fun, eval_fun)
3275 
3276 #define __GMPF_DEFINE_INCREMENT_OPERATOR(fun, eval_fun) \
3277 __GMP_DEFINE_INCREMENT_OPERATOR(mpf, fun, eval_fun)
3278 
3279 
3280 #define __GMPP_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun)                  \
3281 template <class U>                                                           \
3282 __gmp_expr<T, __gmp_unary_expr<__gmp_expr<T, U>, eval_fun> >          \
3283 fun(const __gmp_expr<T, U> &expr)                                            \
3284 {                                                                            \
3285   return __gmp_expr<T, __gmp_unary_expr<__gmp_expr<T, U>, eval_fun> >(expr); \
3286 }
3287 
3288 #define __GMPNN_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, type, bigtype)  \
3289 inline __gmp_expr<T, __gmp_unary_expr<bigtype, eval_fun> >                   \
3290 fun(type expr)                                                               \
3291 {                                                                            \
3292   return __gmp_expr<T, __gmp_unary_expr<bigtype, eval_fun> >(expr);          \
3293 }
3294 
3295 #define __GMPNS_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, type)  \
3296 __GMPNN_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, type, signed long)
3297 #define __GMPNU_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, type)  \
3298 __GMPNN_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, type, unsigned long)
3299 #define __GMPND_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, type)  \
3300 __GMPNN_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, type, double)
3301 
3302 #define __GMPN_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun)                 \
3303 __GMPNS_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, signed char)           \
3304 __GMPNU_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, unsigned char)         \
3305 __GMPNS_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, signed int)            \
3306 __GMPNU_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, unsigned int)          \
3307 __GMPNS_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, signed short int)      \
3308 __GMPNU_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, unsigned short int)    \
3309 __GMPNS_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, signed long int)       \
3310 __GMPNU_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, unsigned long int)     \
3311 __GMPND_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, float)                 \
3312 __GMPND_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, double)                \
3313 
3314 #define __GMP_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun)                  \
3315 __GMPP_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun)                         \
3316 __GMPN_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun)                         \
3317 
3318 
3319 /**************** Arithmetic operators and functions ****************/
3320 
3321 // non-member operators and functions
3322 
3323 __GMP_DEFINE_UNARY_FUNCTION(operator+, __gmp_unary_plus)
3324 __GMP_DEFINE_UNARY_FUNCTION(operator-, __gmp_unary_minus)
3325 __GMP_DEFINE_UNARY_FUNCTION_1(mpz_t, operator~, __gmp_unary_com)
3326 
3327 __GMP_DEFINE_BINARY_FUNCTION(operator+, __gmp_binary_plus)
3328 __GMP_DEFINE_BINARY_FUNCTION(operator-, __gmp_binary_minus)
3329 __GMP_DEFINE_BINARY_FUNCTION(operator*, __gmp_binary_multiplies)
3330 __GMP_DEFINE_BINARY_FUNCTION(operator/, __gmp_binary_divides)
3331 __GMP_DEFINE_BINARY_FUNCTION_1(mpz_t, operator%, __gmp_binary_modulus)
3332 __GMP_DEFINE_BINARY_FUNCTION_1(mpz_t, operator&, __gmp_binary_and)
3333 __GMP_DEFINE_BINARY_FUNCTION_1(mpz_t, operator|, __gmp_binary_ior)
3334 __GMP_DEFINE_BINARY_FUNCTION_1(mpz_t, operator^, __gmp_binary_xor)
3335 
3336 __GMP_DEFINE_BINARY_FUNCTION_UI(operator<<, __gmp_binary_lshift)
3337 __GMP_DEFINE_BINARY_FUNCTION_UI(operator>>, __gmp_binary_rshift)
3338 
3339 __GMP_DEFINE_BINARY_TYPE_FUNCTION(bool, operator==, __gmp_binary_equal)
3340 __GMP_DEFINE_BINARY_TYPE_FUNCTION(bool, operator!=, ! __gmp_binary_equal)
3341 __GMP_DEFINE_BINARY_TYPE_FUNCTION(bool, operator<, __gmp_binary_less)
3342 __GMP_DEFINE_BINARY_TYPE_FUNCTION(bool, operator<=, ! __gmp_binary_greater)
3343 __GMP_DEFINE_BINARY_TYPE_FUNCTION(bool, operator>, __gmp_binary_greater)
3344 __GMP_DEFINE_BINARY_TYPE_FUNCTION(bool, operator>=, ! __gmp_binary_less)
3345 
3346 __GMP_DEFINE_UNARY_FUNCTION(abs, __gmp_abs_function)
3347 __GMP_DEFINE_UNARY_FUNCTION_1(mpf_t, trunc, __gmp_trunc_function)
3348 __GMP_DEFINE_UNARY_FUNCTION_1(mpf_t, floor, __gmp_floor_function)
3349 __GMP_DEFINE_UNARY_FUNCTION_1(mpf_t, ceil, __gmp_ceil_function)
3350 __GMP_DEFINE_UNARY_FUNCTION_1(mpf_t, sqrt, __gmp_sqrt_function)
3351 __GMP_DEFINE_UNARY_FUNCTION_1(mpz_t, sqrt, __gmp_sqrt_function)
3352 __GMP_DEFINE_UNARY_FUNCTION_1(mpz_t, factorial, __gmp_fac_function)
3353 __GMP_DEFINE_UNARY_FUNCTION_1(mpz_t, primorial, __gmp_primorial_function)
3354 __GMP_DEFINE_UNARY_FUNCTION_1(mpz_t, fibonacci, __gmp_fib_function)
3355 __GMP_DEFINE_BINARY_FUNCTION_1(mpf_t, hypot, __gmp_hypot_function)
3356 __GMP_DEFINE_BINARY_FUNCTION_1(mpz_t, gcd, __gmp_gcd_function)
3357 __GMP_DEFINE_BINARY_FUNCTION_1(mpz_t, lcm, __gmp_lcm_function)
3358 
3359 __GMP_DEFINE_UNARY_TYPE_FUNCTION(int, sgn, __gmp_sgn_function)
3360 __GMP_DEFINE_BINARY_TYPE_FUNCTION(int, cmp, __gmp_cmp_function)
3361 
3362 template <class T>
3363 void swap(__gmp_expr<T, T>& x, __gmp_expr<T, T>& y) __GMPXX_NOEXCEPT
3364 { x.swap(y); }
3365 
3366 // member operators for mpz_class
3367 
3368 __GMPZ_DEFINE_COMPOUND_OPERATOR(operator+=, __gmp_binary_plus)
3369 __GMPZ_DEFINE_COMPOUND_OPERATOR(operator-=, __gmp_binary_minus)
3370 __GMPZ_DEFINE_COMPOUND_OPERATOR(operator*=, __gmp_binary_multiplies)
3371 __GMPZ_DEFINE_COMPOUND_OPERATOR(operator/=, __gmp_binary_divides)
3372 __GMPZ_DEFINE_COMPOUND_OPERATOR(operator%=, __gmp_binary_modulus)
3373 
3374 __GMPZ_DEFINE_COMPOUND_OPERATOR(operator&=, __gmp_binary_and)
3375 __GMPZ_DEFINE_COMPOUND_OPERATOR(operator|=, __gmp_binary_ior)
3376 __GMPZ_DEFINE_COMPOUND_OPERATOR(operator^=, __gmp_binary_xor)
3377 
3378 __GMPZ_DEFINE_COMPOUND_OPERATOR_UI(operator<<=, __gmp_binary_lshift)
3379 __GMPZ_DEFINE_COMPOUND_OPERATOR_UI(operator>>=, __gmp_binary_rshift)
3380 
3381 __GMPZ_DEFINE_INCREMENT_OPERATOR(operator++, __gmp_unary_increment)
3382 __GMPZ_DEFINE_INCREMENT_OPERATOR(operator--, __gmp_unary_decrement)
3383 
3384 __GMP_DEFINE_UNARY_STATIC_MEMFUN(mpz_t, mpz_class::factorial, __gmp_fac_function)
3385 __GMP_DEFINE_UNARY_STATIC_MEMFUN(mpz_t, mpz_class::primorial, __gmp_primorial_function)
3386 __GMP_DEFINE_UNARY_STATIC_MEMFUN(mpz_t, mpz_class::fibonacci, __gmp_fib_function)
3387 
3388 // member operators for mpq_class
3389 
3390 __GMPQ_DEFINE_COMPOUND_OPERATOR(operator+=, __gmp_binary_plus)
3391 __GMPQ_DEFINE_COMPOUND_OPERATOR(operator-=, __gmp_binary_minus)
3392 __GMPQ_DEFINE_COMPOUND_OPERATOR(operator*=, __gmp_binary_multiplies)
3393 __GMPQ_DEFINE_COMPOUND_OPERATOR(operator/=, __gmp_binary_divides)
3394 
3395 __GMPQ_DEFINE_COMPOUND_OPERATOR_UI(operator<<=, __gmp_binary_lshift)
3396 __GMPQ_DEFINE_COMPOUND_OPERATOR_UI(operator>>=, __gmp_binary_rshift)
3397 
3398 __GMPQ_DEFINE_INCREMENT_OPERATOR(operator++, __gmp_unary_increment)
3399 __GMPQ_DEFINE_INCREMENT_OPERATOR(operator--, __gmp_unary_decrement)
3400 
3401 // member operators for mpf_class
3402 
3403 __GMPF_DEFINE_COMPOUND_OPERATOR(operator+=, __gmp_binary_plus)
3404 __GMPF_DEFINE_COMPOUND_OPERATOR(operator-=, __gmp_binary_minus)
3405 __GMPF_DEFINE_COMPOUND_OPERATOR(operator*=, __gmp_binary_multiplies)
3406 __GMPF_DEFINE_COMPOUND_OPERATOR(operator/=, __gmp_binary_divides)
3407 
3408 __GMPF_DEFINE_COMPOUND_OPERATOR_UI(operator<<=, __gmp_binary_lshift)
3409 __GMPF_DEFINE_COMPOUND_OPERATOR_UI(operator>>=, __gmp_binary_rshift)
3410 
3411 __GMPF_DEFINE_INCREMENT_OPERATOR(operator++, __gmp_unary_increment)
3412 __GMPF_DEFINE_INCREMENT_OPERATOR(operator--, __gmp_unary_decrement)
3413 
3414 
3415 
3416 /**************** Class wrapper for gmp_randstate_t ****************/
3417 
3418 class __gmp_urandomb_value { };
3419 class __gmp_urandomm_value { };
3420 
3421 template <>
3422 class __gmp_expr<mpz_t, __gmp_urandomb_value>
3423 {
3424 private:
3425   __gmp_randstate_struct *state;
3426   mp_bitcnt_t bits;
3427 public:
3428   __gmp_expr(gmp_randstate_t s, mp_bitcnt_t l) : state(s), bits(l) { }
3429   void eval(mpz_ptr z) const { __gmp_rand_function::eval(z, state, bits); }
3430   mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); }
3431 };
3432 
3433 template <>
3434 class __gmp_expr<mpz_t, __gmp_urandomm_value>
3435 {
3436 private:
3437   __gmp_randstate_struct *state;
3438   mpz_class range;
3439 public:
3440   __gmp_expr(gmp_randstate_t s, const mpz_class &z) : state(s), range(z) { }
3441   void eval(mpz_ptr z) const
3442   { __gmp_rand_function::eval(z, state, range.get_mpz_t()); }
3443   mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); }
3444 };
3445 
3446 template <>
3447 class __gmp_expr<mpf_t, __gmp_urandomb_value>
3448 {
3449 private:
3450   __gmp_randstate_struct *state;
3451   mp_bitcnt_t bits;
3452 public:
3453   __gmp_expr(gmp_randstate_t s, mp_bitcnt_t l) : state(s), bits(l) { }
3454   void eval(mpf_ptr f) const
3455   {
3456     __gmp_rand_function::eval(f, state,
3457     (bits>0) ? bits : mpf_get_prec(f));
3458   }
3459   mp_bitcnt_t get_prec() const
3460   {
3461     if (bits == 0)
3462       return mpf_get_default_prec();
3463     else
3464       return bits;
3465   }
3466 };
3467 
3468 extern "C" {
3469   typedef void __gmp_randinit_default_t (gmp_randstate_t);
3470   typedef void __gmp_randinit_lc_2exp_t (gmp_randstate_t, mpz_srcptr, unsigned long int, mp_bitcnt_t);
3471   typedef int __gmp_randinit_lc_2exp_size_t (gmp_randstate_t, mp_bitcnt_t);
3472 }
3473 
3474 class gmp_randclass
3475 {
3476 private:
3477   gmp_randstate_t state;
3478 
3479   // copy construction and assignment not allowed
3480   gmp_randclass(const gmp_randclass &);
3481   void operator=(const gmp_randclass &);
3482 public:
3483   // constructors and destructor
3484   gmp_randclass(gmp_randalg_t alg, unsigned long int size)
3485   {
3486     switch (alg)
3487       {
3488       case GMP_RAND_ALG_LC: // no other cases for now
3489       default:
3490     gmp_randinit(state, alg, size);
3491     break;
3492       }
3493   }
3494 
3495   // gmp_randinit_default
3496   gmp_randclass(__gmp_randinit_default_t* f) { f(state); }
3497 
3498   // gmp_randinit_lc_2exp
3499   gmp_randclass(__gmp_randinit_lc_2exp_t* f,
3500         mpz_class z, unsigned long int l1, mp_bitcnt_t l2)
3501   { f(state, z.get_mpz_t(), l1, l2); }
3502 
3503   // gmp_randinit_lc_2exp_size
3504   gmp_randclass(__gmp_randinit_lc_2exp_size_t* f,
3505         mp_bitcnt_t size)
3506   {
3507     if (f (state, size) == 0)
3508       throw std::length_error ("gmp_randinit_lc_2exp_size");
3509   }
3510 
3511   ~gmp_randclass() { gmp_randclear(state); }
3512 
3513   // initialize
3514   void seed(); // choose a random seed some way (?)
3515   void seed(unsigned long int s) { gmp_randseed_ui(state, s); }
3516   void seed(const mpz_class &z) { gmp_randseed(state, z.get_mpz_t()); }
3517 
3518   // get random number
3519   __gmp_expr<mpz_t, __gmp_urandomb_value> get_z_bits(mp_bitcnt_t l)
3520   { return __gmp_expr<mpz_t, __gmp_urandomb_value>(state, l); }
3521   __gmp_expr<mpz_t, __gmp_urandomb_value> get_z_bits(const mpz_class &z)
3522   { return get_z_bits(z.get_ui()); }
3523   // FIXME: z.get_bitcnt_t() ?
3524 
3525   __gmp_expr<mpz_t, __gmp_urandomm_value> get_z_range(const mpz_class &z)
3526   { return __gmp_expr<mpz_t, __gmp_urandomm_value>(state, z); }
3527 
3528   __gmp_expr<mpf_t, __gmp_urandomb_value> get_f(mp_bitcnt_t prec = 0)
3529   { return __gmp_expr<mpf_t, __gmp_urandomb_value>(state, prec); }
3530 };
3531 
3532 
3533 /**************** Specialize std::numeric_limits ****************/
3534 
3535 namespace std {
3536   template <> class numeric_limits<mpz_class>
3537   {
3538   public:
3539     static const bool is_specialized = true;
3540     static mpz_class min() { return mpz_class(); }
3541     static mpz_class max() { return mpz_class(); }
3542     static mpz_class lowest() { return mpz_class(); }
3543     static const int digits = 0;
3544     static const int digits10 = 0;
3545     static const int max_digits10 = 0;
3546     static const bool is_signed = true;
3547     static const bool is_integer = true;
3548     static const bool is_exact = true;
3549     static const int radix = 2;
3550     static mpz_class epsilon() { return mpz_class(); }
3551     static mpz_class round_error() { return mpz_class(); }
3552     static const int min_exponent = 0;
3553     static const int min_exponent10 = 0;
3554     static const int max_exponent = 0;
3555     static const int max_exponent10 = 0;
3556     static const bool has_infinity = false;
3557     static const bool has_quiet_NaN = false;
3558     static const bool has_signaling_NaN = false;
3559     static const float_denorm_style has_denorm = denorm_absent;
3560     static const bool has_denorm_loss = false;
3561     static mpz_class infinity() { return mpz_class(); }
3562     static mpz_class quiet_NaN() { return mpz_class(); }
3563     static mpz_class signaling_NaN() { return mpz_class(); }
3564     static mpz_class denorm_min() { return mpz_class(); }
3565     static const bool is_iec559 = false;
3566     static const bool is_bounded = false;
3567     static const bool is_modulo = false;
3568     static const bool traps = false;
3569     static const bool tinyness_before = false;
3570     static const float_round_style round_style = round_toward_zero;
3571   };
3572 
3573   template <> class numeric_limits<mpq_class>
3574   {
3575   public:
3576     static const bool is_specialized = true;
3577     static mpq_class min() { return mpq_class(); }
3578     static mpq_class max() { return mpq_class(); }
3579     static mpq_class lowest() { return mpq_class(); }
3580     static const int digits = 0;
3581     static const int digits10 = 0;
3582     static const int max_digits10 = 0;
3583     static const bool is_signed = true;
3584     static const bool is_integer = false;
3585     static const bool is_exact = true;
3586     static const int radix = 2;
3587     static mpq_class epsilon() { return mpq_class(); }
3588     static mpq_class round_error() { return mpq_class(); }
3589     static const int min_exponent = 0;
3590     static const int min_exponent10 = 0;
3591     static const int max_exponent = 0;
3592     static const int max_exponent10 = 0;
3593     static const bool has_infinity = false;
3594     static const bool has_quiet_NaN = false;
3595     static const bool has_signaling_NaN = false;
3596     static const float_denorm_style has_denorm = denorm_absent;
3597     static const bool has_denorm_loss = false;
3598     static mpq_class infinity() { return mpq_class(); }
3599     static mpq_class quiet_NaN() { return mpq_class(); }
3600     static mpq_class signaling_NaN() { return mpq_class(); }
3601     static mpq_class denorm_min() { return mpq_class(); }
3602     static const bool is_iec559 = false;
3603     static const bool is_bounded = false;
3604     static const bool is_modulo = false;
3605     static const bool traps = false;
3606     static const bool tinyness_before = false;
3607     static const float_round_style round_style = round_toward_zero;
3608   };
3609 
3610   template <> class numeric_limits<mpf_class>
3611   {
3612   public:
3613     static const bool is_specialized = true;
3614     static mpf_class min() { return mpf_class(); }
3615     static mpf_class max() { return mpf_class(); }
3616     static mpf_class lowest() { return mpf_class(); }
3617     static const int digits = 0;
3618     static const int digits10 = 0;
3619     static const int max_digits10 = 0;
3620     static const bool is_signed = true;
3621     static const bool is_integer = false;
3622     static const bool is_exact = false;
3623     static const int radix = 2;
3624     static mpf_class epsilon() { return mpf_class(); }
3625     static mpf_class round_error() { return mpf_class(); }
3626     static const int min_exponent = 0;
3627     static const int min_exponent10 = 0;
3628     static const int max_exponent = 0;
3629     static const int max_exponent10 = 0;
3630     static const bool has_infinity = false;
3631     static const bool has_quiet_NaN = false;
3632     static const bool has_signaling_NaN = false;
3633     static const float_denorm_style has_denorm = denorm_absent;
3634     static const bool has_denorm_loss = false;
3635     static mpf_class infinity() { return mpf_class(); }
3636     static mpf_class quiet_NaN() { return mpf_class(); }
3637     static mpf_class signaling_NaN() { return mpf_class(); }
3638     static mpf_class denorm_min() { return mpf_class(); }
3639     static const bool is_iec559 = false;
3640     static const bool is_bounded = false;
3641     static const bool is_modulo = false;
3642     static const bool traps = false;
3643     static const bool tinyness_before = false;
3644     static const float_round_style round_style = round_indeterminate;
3645   };
3646 }
3647 
3648 
3649 /**************** #undef all private macros ****************/
3650 
3651 #undef __GMPP_DECLARE_COMPOUND_OPERATOR
3652 #undef __GMPN_DECLARE_COMPOUND_OPERATOR
3653 #undef __GMP_DECLARE_COMPOUND_OPERATOR
3654 #undef __GMP_DECLARE_COMPOUND_OPERATOR_UI
3655 #undef __GMP_DECLARE_INCREMENT_OPERATOR
3656 #undef __GMPXX_DEFINE_ARITHMETIC_CONSTRUCTORS
3657 #undef __GMPXX_DEFINE_ARITHMETIC_ASSIGNMENTS
3658 
3659 #undef __GMPZQ_DEFINE_EXPR
3660 
3661 #undef __GMP_DEFINE_UNARY_FUNCTION_1
3662 #undef __GMP_DEFINE_UNARY_FUNCTION
3663 #undef __GMP_DEFINE_UNARY_TYPE_FUNCTION
3664 
3665 #undef __GMPP_DEFINE_BINARY_FUNCTION
3666 #undef __GMPNN_DEFINE_BINARY_FUNCTION
3667 #undef __GMPNS_DEFINE_BINARY_FUNCTION
3668 #undef __GMPNU_DEFINE_BINARY_FUNCTION
3669 #undef __GMPND_DEFINE_BINARY_FUNCTION
3670 #undef __GMPNLD_DEFINE_BINARY_FUNCTION
3671 #undef __GMPN_DEFINE_BINARY_FUNCTION
3672 #undef __GMP_DEFINE_BINARY_FUNCTION
3673 
3674 #undef __GMP_DEFINE_BINARY_FUNCTION_UI
3675 
3676 #undef __GMPP_DEFINE_BINARY_TYPE_FUNCTION
3677 #undef __GMPNN_DEFINE_BINARY_TYPE_FUNCTION
3678 #undef __GMPNS_DEFINE_BINARY_TYPE_FUNCTION
3679 #undef __GMPNU_DEFINE_BINARY_TYPE_FUNCTION
3680 #undef __GMPND_DEFINE_BINARY_TYPE_FUNCTION
3681 #undef __GMPNLD_DEFINE_BINARY_TYPE_FUNCTION
3682 #undef __GMPN_DEFINE_BINARY_TYPE_FUNCTION
3683 #undef __GMP_DEFINE_BINARY_TYPE_FUNCTION
3684 
3685 #undef __GMPZ_DEFINE_COMPOUND_OPERATOR
3686 
3687 #undef __GMPP_DEFINE_COMPOUND_OPERATOR
3688 #undef __GMPNN_DEFINE_COMPOUND_OPERATOR
3689 #undef __GMPNS_DEFINE_COMPOUND_OPERATOR
3690 #undef __GMPNU_DEFINE_COMPOUND_OPERATOR
3691 #undef __GMPND_DEFINE_COMPOUND_OPERATOR
3692 #undef __GMPNLD_DEFINE_COMPOUND_OPERATOR
3693 #undef __GMPN_DEFINE_COMPOUND_OPERATOR
3694 #undef __GMP_DEFINE_COMPOUND_OPERATOR
3695 
3696 #undef __GMPQ_DEFINE_COMPOUND_OPERATOR
3697 #undef __GMPF_DEFINE_COMPOUND_OPERATOR
3698 
3699 #undef __GMP_DEFINE_COMPOUND_OPERATOR_UI
3700 #undef __GMPZ_DEFINE_COMPOUND_OPERATOR_UI
3701 #undef __GMPQ_DEFINE_COMPOUND_OPERATOR_UI
3702 #undef __GMPF_DEFINE_COMPOUND_OPERATOR_UI
3703 
3704 #undef __GMP_DEFINE_INCREMENT_OPERATOR
3705 #undef __GMPZ_DEFINE_INCREMENT_OPERATOR
3706 #undef __GMPQ_DEFINE_INCREMENT_OPERATOR
3707 #undef __GMPF_DEFINE_INCREMENT_OPERATOR
3708 
3709 #undef __GMPXX_CONSTANT_TRUE
3710 #undef __GMPXX_CONSTANT
3711 
3712 #endif /* __GMP_PLUSPLUS__ */