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