w32tex
About: TeX Live provides a comprehensive TeX system including all the major TeX-related programs, macro packages, and fonts that are free software. Windows sources.
  Fossies Dox: w32tex-src.tar.xz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

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