1 /* gmpxx.h -- C++ class wrapper for GMP types. -*- C++ -*-
3 Copyright 2001, 2002, 2003, 2006, 2008, 2011, 2012 Free Software Foundation,
6 This file is part of the GNU MP Library.
8 The GNU MP Library is free software; you can redistribute it and/or modify
9 it under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or (at your
11 option) any later version.
13 The GNU MP Library is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
16 License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with the GNU MP Library. If not, see http://www.gnu.org/licenses/. */
21 #ifndef __GMP_PLUSPLUS__
22 #define __GMP_PLUSPLUS__
26 #include <cstring> /* for strlen */
27 #include <limits> /* numeric_limits */
29 #include <algorithm> /* swap */
35 // wrapper for gcc's __builtin_constant_p
36 // __builtin_constant_p has been in gcc since forever,
37 // but g++-3.4 miscompiles it.
38 #if __GMP_GNUC_PREREQ(4, 2)
39 #define __GMPXX_CONSTANT(X) __builtin_constant_p(X)
41 #define __GMPXX_CONSTANT(X) false
45 #ifndef __GMPXX_USE_CXX11
46 #if __cplusplus >= 201103L
47 #define __GMPXX_USE_CXX11 1
49 #define __GMPXX_USE_CXX11 0
54 #define __GMPXX_NOEXCEPT noexcept
55 #include <type_traits> // for common_type
57 #define __GMPXX_NOEXCEPT
60 // Max allocations for plain types when converted to mpz_t
61 #define __GMPZ_DBL_LIMBS (2 + DBL_MAX_EXP / GMP_NUMB_BITS)
63 #if GMP_NAIL_BITS != 0 && ! defined _LONG_LONG_LIMB
64 #define __GMPZ_ULI_LIMBS 2
66 #define __GMPZ_ULI_LIMBS 1
69 inline void __mpz_set_ui_safe(mpz_ptr p, unsigned long l)
71 p->_mp_size = (l != 0);
72 p->_mp_d[0] = l & GMP_NUMB_MASK;
73 #if __GMPZ_ULI_LIMBS > 1
76 p->_mp_size += (l != 0);
80 inline void __mpz_set_si_safe(mpz_ptr p, long l)
84 __mpz_set_ui_safe(p, -static_cast<unsigned long>(l));
88 __mpz_set_ui_safe(p, l);
89 // Note: we know the high bit of l is 0 so we could do slightly better
92 // Fake temporary variables
93 #define __GMPXX_TMPZ_UI \
95 mp_limb_t limbs[__GMPZ_ULI_LIMBS]; \
96 temp->_mp_d = limbs; \
97 __mpz_set_ui_safe (temp, l)
98 #define __GMPXX_TMPZ_SI \
100 mp_limb_t limbs[__GMPZ_ULI_LIMBS]; \
101 temp->_mp_d = limbs; \
102 __mpz_set_si_safe (temp, l)
103 #define __GMPXX_TMPZ_D \
105 mp_limb_t limbs[__GMPZ_DBL_LIMBS]; \
106 temp->_mp_d = limbs; \
107 temp->_mp_alloc = __GMPZ_DBL_LIMBS; \
110 #define __GMPXX_TMPQ_UI \
112 mp_limb_t limbs[__GMPZ_ULI_LIMBS+1]; \
113 mpq_numref(temp)->_mp_d = limbs; \
114 __mpz_set_ui_safe (mpq_numref(temp), l); \
115 mpq_denref(temp)->_mp_d = limbs + __GMPZ_ULI_LIMBS; \
116 mpq_denref(temp)->_mp_size = 1; \
117 mpq_denref(temp)->_mp_d[0] = 1
118 #define __GMPXX_TMPQ_SI \
120 mp_limb_t limbs[__GMPZ_ULI_LIMBS+1]; \
121 mpq_numref(temp)->_mp_d = limbs; \
122 __mpz_set_si_safe (mpq_numref(temp), l); \
123 mpq_denref(temp)->_mp_d = limbs + __GMPZ_ULI_LIMBS; \
124 mpq_denref(temp)->_mp_size = 1; \
125 mpq_denref(temp)->_mp_d[0] = 1
127 inline unsigned long __gmpxx_abs_ui (signed long l)
129 return l >= 0 ? static_cast<unsigned long>(l)
130 : -static_cast<unsigned long>(l);
133 /**************** Function objects ****************/
134 /* Any evaluation of a __gmp_expr ends up calling one of these functions
135 all intermediate functions being inline, the evaluation should optimize
136 to a direct call to the relevant function, thus yielding no overhead
137 over the C interface. */
139 struct __gmp_unary_plus
141 static void eval(mpz_ptr z, mpz_srcptr w) { mpz_set(z, w); }
142 static void eval(mpq_ptr q, mpq_srcptr r) { mpq_set(q, r); }
143 static void eval(mpf_ptr f, mpf_srcptr g) { mpf_set(f, g); }
146 struct __gmp_unary_minus
148 static void eval(mpz_ptr z, mpz_srcptr w) { mpz_neg(z, w); }
149 static void eval(mpq_ptr q, mpq_srcptr r) { mpq_neg(q, r); }
150 static void eval(mpf_ptr f, mpf_srcptr g) { mpf_neg(f, g); }
153 struct __gmp_unary_com
155 static void eval(mpz_ptr z, mpz_srcptr w) { mpz_com(z, w); }
158 struct __gmp_binary_plus
160 static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v)
161 { mpz_add(z, w, v); }
163 static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l)
165 // Ideally, those checks should happen earlier so that the tree
166 // generated for a+0+b would just be sum(a,b).
167 if (__GMPXX_CONSTANT(l) && l == 0)
169 if (z != w) mpz_set(z, w);
174 static void eval(mpz_ptr z, unsigned long int l, mpz_srcptr w)
176 static void eval(mpz_ptr z, mpz_srcptr w, signed long int l)
179 eval(z, w, static_cast<unsigned long>(l));
181 mpz_sub_ui(z, w, -static_cast<unsigned long>(l));
183 static void eval(mpz_ptr z, signed long int l, mpz_srcptr w)
185 static void eval(mpz_ptr z, mpz_srcptr w, double d)
186 { __GMPXX_TMPZ_D; mpz_add (z, w, temp); }
187 static void eval(mpz_ptr z, double d, mpz_srcptr w)
190 static void eval(mpq_ptr q, mpq_srcptr r, mpq_srcptr s)
191 { mpq_add(q, r, s); }
193 static void eval(mpq_ptr q, mpq_srcptr r, unsigned long int l)
195 if (__GMPXX_CONSTANT(l) && l == 0)
197 if (q != r) mpq_set(q, r);
202 mpz_addmul_ui(mpq_numref(q), mpq_denref(q), l);
205 mpz_mul_ui(mpq_numref(q), mpq_denref(r), l);
206 mpz_add(mpq_numref(q), mpq_numref(q), mpq_numref(r));
207 mpz_set(mpq_denref(q), mpq_denref(r));
211 static void eval(mpq_ptr q, unsigned long int l, mpq_srcptr r)
213 static inline void eval(mpq_ptr q, mpq_srcptr r, signed long int l);
214 // defined after __gmp_binary_minus
215 static void eval(mpq_ptr q, signed long int l, mpq_srcptr r)
217 static void eval(mpq_ptr q, mpq_srcptr r, double d)
225 static void eval(mpq_ptr q, double d, mpq_srcptr r)
228 static void eval(mpq_ptr q, mpq_srcptr r, mpz_srcptr z)
231 mpz_addmul(mpq_numref(q), mpq_denref(q), z);
234 mpz_mul(mpq_numref(q), mpq_denref(r), z);
235 mpz_add(mpq_numref(q), mpq_numref(q), mpq_numref(r));
236 mpz_set(mpq_denref(q), mpq_denref(r));
239 static void eval(mpq_ptr q, mpz_srcptr z, mpq_srcptr r)
242 static void eval(mpf_ptr f, mpf_srcptr g, mpf_srcptr h)
243 { mpf_add(f, g, h); }
245 static void eval(mpf_ptr f, mpf_srcptr g, unsigned long int l)
246 { mpf_add_ui(f, g, l); }
247 static void eval(mpf_ptr f, unsigned long int l, mpf_srcptr g)
248 { mpf_add_ui(f, g, l); }
249 static void eval(mpf_ptr f, mpf_srcptr g, signed long int l)
254 mpf_sub_ui(f, g, -static_cast<unsigned long>(l));
256 static void eval(mpf_ptr f, signed long int l, mpf_srcptr g)
258 static void eval(mpf_ptr f, mpf_srcptr g, double d)
261 mpf_init2(temp, 8*sizeof(double));
266 static void eval(mpf_ptr f, double d, mpf_srcptr g)
270 struct __gmp_binary_minus
272 static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v)
273 { mpz_sub(z, w, v); }
275 static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l)
277 if (__GMPXX_CONSTANT(l) && l == 0)
279 if (z != w) mpz_set(z, w);
284 static void eval(mpz_ptr z, unsigned long int l, mpz_srcptr w)
286 if (__GMPXX_CONSTANT(l) && l == 0)
293 static void eval(mpz_ptr z, mpz_srcptr w, signed long int l)
296 eval(z, w, static_cast<unsigned long>(l));
298 mpz_add_ui(z, w, -static_cast<unsigned long>(l));
300 static void eval(mpz_ptr z, signed long int l, mpz_srcptr w)
303 eval(z, static_cast<unsigned long>(l), w);
306 mpz_add_ui(z, w, -static_cast<unsigned long>(l));
310 static void eval(mpz_ptr z, mpz_srcptr w, double d)
311 { __GMPXX_TMPZ_D; mpz_sub (z, w, temp); }
312 static void eval(mpz_ptr z, double d, mpz_srcptr w)
313 { __GMPXX_TMPZ_D; mpz_sub (z, temp, w); }
315 static void eval(mpq_ptr q, mpq_srcptr r, mpq_srcptr s)
316 { mpq_sub(q, r, s); }
318 static void eval(mpq_ptr q, mpq_srcptr r, unsigned long int l)
320 if (__GMPXX_CONSTANT(l) && l == 0)
322 if (q != r) mpq_set(q, r);
327 mpz_submul_ui(mpq_numref(q), mpq_denref(q), l);
330 mpz_mul_ui(mpq_numref(q), mpq_denref(r), l);
331 mpz_sub(mpq_numref(q), mpq_numref(r), mpq_numref(q));
332 mpz_set(mpq_denref(q), mpq_denref(r));
336 static void eval(mpq_ptr q, unsigned long int l, mpq_srcptr r)
337 { eval(q, r, l); mpq_neg(q, q); }
338 static void eval(mpq_ptr q, mpq_srcptr r, signed long int l)
341 eval(q, r, static_cast<unsigned long>(l));
343 __gmp_binary_plus::eval(q, r, -static_cast<unsigned long>(l));
345 static void eval(mpq_ptr q, signed long int l, mpq_srcptr r)
346 { eval(q, r, l); mpq_neg(q, q); }
347 static void eval(mpq_ptr q, mpq_srcptr r, double d)
355 static void eval(mpq_ptr q, double d, mpq_srcptr r)
364 static void eval(mpq_ptr q, mpq_srcptr r, mpz_srcptr z)
367 mpz_submul(mpq_numref(q), mpq_denref(q), z);
370 mpz_mul(mpq_numref(q), mpq_denref(r), z);
371 mpz_sub(mpq_numref(q), mpq_numref(r), mpq_numref(q));
372 mpz_set(mpq_denref(q), mpq_denref(r));
375 static void eval(mpq_ptr q, mpz_srcptr z, mpq_srcptr r)
376 { eval(q, r, z); mpq_neg(q, q); }
378 static void eval(mpf_ptr f, mpf_srcptr g, mpf_srcptr h)
379 { mpf_sub(f, g, h); }
381 static void eval(mpf_ptr f, mpf_srcptr g, unsigned long int l)
382 { mpf_sub_ui(f, g, l); }
383 static void eval(mpf_ptr f, unsigned long int l, mpf_srcptr g)
384 { mpf_ui_sub(f, l, g); }
385 static void eval(mpf_ptr f, mpf_srcptr g, signed long int l)
390 mpf_add_ui(f, g, -static_cast<unsigned long>(l));
392 static void eval(mpf_ptr f, signed long int l, mpf_srcptr g)
397 mpf_add_ui(f, g, -static_cast<unsigned long>(l));
400 static void eval(mpf_ptr f, mpf_srcptr g, double d)
403 mpf_init2(temp, 8*sizeof(double));
408 static void eval(mpf_ptr f, double d, mpf_srcptr g)
411 mpf_init2(temp, 8*sizeof(double));
418 // defined here so it can reference __gmp_binary_minus
420 __gmp_binary_plus::eval(mpq_ptr q, mpq_srcptr r, signed long int l)
423 eval(q, r, static_cast<unsigned long>(l));
425 __gmp_binary_minus::eval(q, r, -static_cast<unsigned long>(l));
428 struct __gmp_binary_lshift
430 static void eval(mpz_ptr z, mpz_srcptr w, mp_bitcnt_t l)
432 if (__GMPXX_CONSTANT(l) && (l == 0))
434 if (z != w) mpz_set(z, w);
437 mpz_mul_2exp(z, w, l);
439 static void eval(mpq_ptr q, mpq_srcptr r, mp_bitcnt_t l)
441 if (__GMPXX_CONSTANT(l) && (l == 0))
443 if (q != r) mpq_set(q, r);
446 mpq_mul_2exp(q, r, l);
448 static void eval(mpf_ptr f, mpf_srcptr g, mp_bitcnt_t l)
449 { mpf_mul_2exp(f, g, l); }
452 struct __gmp_binary_rshift
454 static void eval(mpz_ptr z, mpz_srcptr w, mp_bitcnt_t l)
456 if (__GMPXX_CONSTANT(l) && (l == 0))
458 if (z != w) mpz_set(z, w);
461 mpz_fdiv_q_2exp(z, w, l);
463 static void eval(mpq_ptr q, mpq_srcptr r, mp_bitcnt_t l)
465 if (__GMPXX_CONSTANT(l) && (l == 0))
467 if (q != r) mpq_set(q, r);
470 mpq_div_2exp(q, r, l);
472 static void eval(mpf_ptr f, mpf_srcptr g, mp_bitcnt_t l)
473 { mpf_div_2exp(f, g, l); }
476 struct __gmp_binary_multiplies
478 static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v)
479 { mpz_mul(z, w, v); }
481 static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l)
483 // gcc-3.3 doesn't have __builtin_ctzl. Don't bother optimizing for old gcc.
484 #if __GMP_GNUC_PREREQ(3, 4)
485 if (__GMPXX_CONSTANT(l) && (l & (l-1)) == 0)
493 __gmp_binary_lshift::eval(z, w, __builtin_ctzl(l));
500 static void eval(mpz_ptr z, unsigned long int l, mpz_srcptr w)
502 static void eval(mpz_ptr z, mpz_srcptr w, signed long int l)
504 if (__GMPXX_CONSTANT(l))
507 eval(z, w, static_cast<unsigned long>(l));
510 eval(z, w, -static_cast<unsigned long>(l));
515 mpz_mul_si (z, w, l);
517 static void eval(mpz_ptr z, signed long int l, mpz_srcptr w)
519 static void eval(mpz_ptr z, mpz_srcptr w, double d)
520 { __GMPXX_TMPZ_D; mpz_mul (z, w, temp); }
521 static void eval(mpz_ptr z, double d, mpz_srcptr w)
524 static void eval(mpq_ptr q, mpq_srcptr r, mpq_srcptr s)
525 { mpq_mul(q, r, s); }
527 static void eval(mpq_ptr q, mpq_srcptr r, unsigned long int l)
529 #if __GMP_GNUC_PREREQ(3, 4)
530 if (__GMPXX_CONSTANT(l) && (l & (l-1)) == 0)
538 __gmp_binary_lshift::eval(q, r, __builtin_ctzl(l));
545 mpq_mul (q, r, temp);
548 static void eval(mpq_ptr q, unsigned long int l, mpq_srcptr r)
550 static void eval(mpq_ptr q, mpq_srcptr r, signed long int l)
552 if (__GMPXX_CONSTANT(l))
555 eval(q, r, static_cast<unsigned long>(l));
558 eval(q, r, -static_cast<unsigned long>(l));
565 mpq_mul (q, r, temp);
568 static void eval(mpq_ptr q, signed long int l, mpq_srcptr r)
570 static void eval(mpq_ptr q, mpq_srcptr r, double d)
578 static void eval(mpq_ptr q, double d, mpq_srcptr r)
581 static void eval(mpf_ptr f, mpf_srcptr g, mpf_srcptr h)
582 { mpf_mul(f, g, h); }
584 static void eval(mpf_ptr f, mpf_srcptr g, unsigned long int l)
585 { mpf_mul_ui(f, g, l); }
586 static void eval(mpf_ptr f, unsigned long int l, mpf_srcptr g)
587 { mpf_mul_ui(f, g, l); }
588 static void eval(mpf_ptr f, mpf_srcptr g, signed long int l)
594 mpf_mul_ui(f, g, -static_cast<unsigned long>(l));
598 static void eval(mpf_ptr f, signed long int l, mpf_srcptr g)
600 static void eval(mpf_ptr f, mpf_srcptr g, double d)
603 mpf_init2(temp, 8*sizeof(double));
608 static void eval(mpf_ptr f, double d, mpf_srcptr g)
612 struct __gmp_binary_divides
614 static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v)
615 { mpz_tdiv_q(z, w, v); }
617 static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l)
619 #if __GMP_GNUC_PREREQ(3, 4)
620 // Don't optimize division by 0...
621 if (__GMPXX_CONSTANT(l) && (l & (l-1)) == 0 && l != 0)
625 if (z != w) mpz_set(z, w);
628 mpz_tdiv_q_2exp(z, w, __builtin_ctzl(l));
629 // warning: do not use rshift (fdiv)
633 mpz_tdiv_q_ui(z, w, l);
635 static void eval(mpz_ptr z, unsigned long int l, mpz_srcptr w)
639 if (mpz_fits_ulong_p(w))
640 mpz_set_ui(z, l / mpz_get_ui(w));
647 if (mpz_fits_ulong_p(z))
649 mpz_set_ui(z, l / mpz_get_ui(z));
656 static void eval(mpz_ptr z, mpz_srcptr w, signed long int l)
659 eval(z, w, static_cast<unsigned long>(l));
662 eval(z, w, -static_cast<unsigned long>(l));
666 static void eval(mpz_ptr z, signed long int l, mpz_srcptr w)
668 if (mpz_fits_slong_p(w))
669 mpz_set_si(z, l / mpz_get_si(w));
672 /* if w is bigger than a long then the quotient must be zero, unless
673 l==LONG_MIN and w==-LONG_MIN in which case the quotient is -1 */
674 mpz_set_si (z, (mpz_cmpabs_ui (w, __gmpxx_abs_ui(l)) == 0 ? -1 : 0));
677 static void eval(mpz_ptr z, mpz_srcptr w, double d)
678 { __GMPXX_TMPZ_D; mpz_tdiv_q (z, w, temp); }
679 static void eval(mpz_ptr z, double d, mpz_srcptr w)
680 { __GMPXX_TMPZ_D; mpz_tdiv_q (z, temp, w); }
682 static void eval(mpq_ptr q, mpq_srcptr r, mpq_srcptr s)
683 { mpq_div(q, r, s); }
685 static void eval(mpq_ptr q, mpq_srcptr r, unsigned long int l)
687 #if __GMP_GNUC_PREREQ(3, 4)
688 if (__GMPXX_CONSTANT(l) && (l & (l-1)) == 0 && l != 0)
689 __gmp_binary_rshift::eval(q, r, __builtin_ctzl(l));
694 mpq_div (q, r, temp);
697 static void eval(mpq_ptr q, unsigned long int l, mpq_srcptr r)
698 { __GMPXX_TMPQ_UI; mpq_div (q, temp, r); }
699 static void eval(mpq_ptr q, mpq_srcptr r, signed long int l)
701 if (__GMPXX_CONSTANT(l))
704 eval(q, r, static_cast<unsigned long>(l));
707 eval(q, r, -static_cast<unsigned long>(l));
714 mpq_div (q, r, temp);
717 static void eval(mpq_ptr q, signed long int l, mpq_srcptr r)
718 { __GMPXX_TMPQ_SI; mpq_div (q, temp, r); }
719 static void eval(mpq_ptr q, mpq_srcptr r, double d)
727 static void eval(mpq_ptr q, double d, mpq_srcptr r)
736 static void eval(mpf_ptr f, mpf_srcptr g, mpf_srcptr h)
737 { mpf_div(f, g, h); }
739 static void eval(mpf_ptr f, mpf_srcptr g, unsigned long int l)
740 { mpf_div_ui(f, g, l); }
741 static void eval(mpf_ptr f, unsigned long int l, mpf_srcptr g)
742 { mpf_ui_div(f, l, g); }
743 static void eval(mpf_ptr f, mpf_srcptr g, signed long int l)
749 mpf_div_ui(f, g, -static_cast<unsigned long>(l));
753 static void eval(mpf_ptr f, signed long int l, mpf_srcptr g)
759 mpf_ui_div(f, -static_cast<unsigned long>(l), g);
763 static void eval(mpf_ptr f, mpf_srcptr g, double d)
766 mpf_init2(temp, 8*sizeof(double));
771 static void eval(mpf_ptr f, double d, mpf_srcptr g)
774 mpf_init2(temp, 8*sizeof(double));
781 struct __gmp_binary_modulus
783 static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v)
784 { mpz_tdiv_r(z, w, v); }
786 static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l)
787 { mpz_tdiv_r_ui(z, w, l); }
788 static void eval(mpz_ptr z, unsigned long int l, mpz_srcptr w)
792 if (mpz_fits_ulong_p(w))
793 mpz_set_ui(z, l % mpz_get_ui(w));
800 if (mpz_fits_ulong_p(z))
801 mpz_set_ui(z, l % mpz_get_ui(z));
806 static void eval(mpz_ptr z, mpz_srcptr w, signed long int l)
808 mpz_tdiv_r_ui (z, w, __gmpxx_abs_ui(l));
810 static void eval(mpz_ptr z, signed long int l, mpz_srcptr w)
812 if (mpz_fits_slong_p(w))
813 mpz_set_si(z, l % mpz_get_si(w));
816 /* if w is bigger than a long then the remainder is l unchanged,
817 unless l==LONG_MIN and w==-LONG_MIN in which case it's 0 */
818 mpz_set_si (z, mpz_cmpabs_ui (w, __gmpxx_abs_ui(l)) == 0 ? 0 : l);
821 static void eval(mpz_ptr z, mpz_srcptr w, double d)
822 { __GMPXX_TMPZ_D; mpz_tdiv_r (z, w, temp); }
823 static void eval(mpz_ptr z, double d, mpz_srcptr w)
824 { __GMPXX_TMPZ_D; mpz_tdiv_r (z, temp, w); }
827 struct __gmp_binary_and
829 static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v)
830 { mpz_and(z, w, v); }
832 static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l)
833 { __GMPXX_TMPZ_UI; mpz_and (z, w, temp); }
834 static void eval(mpz_ptr z, unsigned long int l, mpz_srcptr w)
836 static void eval(mpz_ptr z, mpz_srcptr w, signed long int l)
837 { __GMPXX_TMPZ_SI; mpz_and (z, w, temp); }
838 static void eval(mpz_ptr z, signed long int l, mpz_srcptr w)
840 static void eval(mpz_ptr z, mpz_srcptr w, double d)
841 { __GMPXX_TMPZ_D; mpz_and (z, w, temp); }
842 static void eval(mpz_ptr z, double d, mpz_srcptr w)
846 struct __gmp_binary_ior
848 static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v)
849 { mpz_ior(z, w, v); }
850 static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l)
851 { __GMPXX_TMPZ_UI; mpz_ior (z, w, temp); }
852 static void eval(mpz_ptr z, unsigned long int l, mpz_srcptr w)
854 static void eval(mpz_ptr z, mpz_srcptr w, signed long int l)
855 { __GMPXX_TMPZ_SI; mpz_ior (z, w, temp); }
856 static void eval(mpz_ptr z, signed long int l, mpz_srcptr w)
858 static void eval(mpz_ptr z, mpz_srcptr w, double d)
859 { __GMPXX_TMPZ_D; mpz_ior (z, w, temp); }
860 static void eval(mpz_ptr z, double d, mpz_srcptr w)
864 struct __gmp_binary_xor
866 static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v)
867 { mpz_xor(z, w, v); }
868 static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l)
869 { __GMPXX_TMPZ_UI; mpz_xor (z, w, temp); }
870 static void eval(mpz_ptr z, unsigned long int l, mpz_srcptr w)
872 static void eval(mpz_ptr z, mpz_srcptr w, signed long int l)
873 { __GMPXX_TMPZ_SI; mpz_xor (z, w, temp); }
874 static void eval(mpz_ptr z, signed long int l, mpz_srcptr w)
876 static void eval(mpz_ptr z, mpz_srcptr w, double d)
877 { __GMPXX_TMPZ_D; mpz_xor (z, w, temp); }
878 static void eval(mpz_ptr z, double d, mpz_srcptr w)
882 struct __gmp_binary_equal
884 static bool eval(mpz_srcptr z, mpz_srcptr w) { return mpz_cmp(z, w) == 0; }
886 static bool eval(mpz_srcptr z, unsigned long int l)
887 { return mpz_cmp_ui(z, l) == 0; }
888 static bool eval(unsigned long int l, mpz_srcptr z)
889 { return mpz_cmp_ui(z, l) == 0; }
890 static bool eval(mpz_srcptr z, signed long int l)
891 { return mpz_cmp_si(z, l) == 0; }
892 static bool eval(signed long int l, mpz_srcptr z)
893 { return mpz_cmp_si(z, l) == 0; }
894 static bool eval(mpz_srcptr z, double d)
895 { return mpz_cmp_d(z, d) == 0; }
896 static bool eval(double d, mpz_srcptr z)
897 { return mpz_cmp_d(z, d) == 0; }
899 static bool eval(mpq_srcptr q, mpq_srcptr r)
900 { return mpq_equal(q, r) != 0; }
902 static bool eval(mpq_srcptr q, unsigned long int l)
903 { return mpq_cmp_ui(q, l, 1) == 0; }
904 static bool eval(unsigned long int l, mpq_srcptr q)
905 { return mpq_cmp_ui(q, l, 1) == 0; }
906 static bool eval(mpq_srcptr q, signed long int l)
907 { return mpq_cmp_si(q, l, 1) == 0; }
908 static bool eval(signed long int l, mpq_srcptr q)
909 { return mpq_cmp_si(q, l, 1) == 0; }
910 static bool eval(mpq_srcptr q, double d)
916 b = (mpq_equal(q, temp) != 0);
920 static bool eval(double d, mpq_srcptr q)
925 static bool eval(mpf_srcptr f, mpf_srcptr g) { return mpf_cmp(f, g) == 0; }
927 static bool eval(mpf_srcptr f, unsigned long int l)
928 { return mpf_cmp_ui(f, l) == 0; }
929 static bool eval(unsigned long int l, mpf_srcptr f)
930 { return mpf_cmp_ui(f, l) == 0; }
931 static bool eval(mpf_srcptr f, signed long int l)
932 { return mpf_cmp_si(f, l) == 0; }
933 static bool eval(signed long int l, mpf_srcptr f)
934 { return mpf_cmp_si(f, l) == 0; }
935 static bool eval(mpf_srcptr f, double d)
936 { return mpf_cmp_d(f, d) == 0; }
937 static bool eval(double d, mpf_srcptr f)
938 { return mpf_cmp_d(f, d) == 0; }
941 struct __gmp_binary_less
943 static bool eval(mpz_srcptr z, mpz_srcptr w) { return mpz_cmp(z, w) < 0; }
945 static bool eval(mpz_srcptr z, unsigned long int l)
946 { return mpz_cmp_ui(z, l) < 0; }
947 static bool eval(unsigned long int l, mpz_srcptr z)
948 { return mpz_cmp_ui(z, l) > 0; }
949 static bool eval(mpz_srcptr z, signed long int l)
950 { return mpz_cmp_si(z, l) < 0; }
951 static bool eval(signed long int l, mpz_srcptr z)
952 { return mpz_cmp_si(z, l) > 0; }
953 static bool eval(mpz_srcptr z, double d)
954 { return mpz_cmp_d(z, d) < 0; }
955 static bool eval(double d, mpz_srcptr z)
956 { return mpz_cmp_d(z, d) > 0; }
958 static bool eval(mpq_srcptr q, mpq_srcptr r) { return mpq_cmp(q, r) < 0; }
960 static bool eval(mpq_srcptr q, unsigned long int l)
961 { return mpq_cmp_ui(q, l, 1) < 0; }
962 static bool eval(unsigned long int l, mpq_srcptr q)
963 { return mpq_cmp_ui(q, l, 1) > 0; }
964 static bool eval(mpq_srcptr q, signed long int l)
965 { return mpq_cmp_si(q, l, 1) < 0; }
966 static bool eval(signed long int l, mpq_srcptr q)
967 { return mpq_cmp_si(q, l, 1) > 0; }
968 static bool eval(mpq_srcptr q, double d)
974 b = (mpq_cmp(q, temp) < 0);
978 static bool eval(double d, mpq_srcptr q)
984 b = (mpq_cmp(temp, q) < 0);
989 static bool eval(mpf_srcptr f, mpf_srcptr g) { return mpf_cmp(f, g) < 0; }
991 static bool eval(mpf_srcptr f, unsigned long int l)
992 { return mpf_cmp_ui(f, l) < 0; }
993 static bool eval(unsigned long int l, mpf_srcptr f)
994 { return mpf_cmp_ui(f, l) > 0; }
995 static bool eval(mpf_srcptr f, signed long int l)
996 { return mpf_cmp_si(f, l) < 0; }
997 static bool eval(signed long int l, mpf_srcptr f)
998 { return mpf_cmp_si(f, l) > 0; }
999 static bool eval(mpf_srcptr f, double d)
1000 { return mpf_cmp_d(f, d) < 0; }
1001 static bool eval(double d, mpf_srcptr f)
1002 { return mpf_cmp_d(f, d) > 0; }
1005 struct __gmp_binary_greater
1007 static bool eval(mpz_srcptr z, mpz_srcptr w) { return mpz_cmp(z, w) > 0; }
1009 static bool eval(mpz_srcptr z, unsigned long int l)
1010 { return mpz_cmp_ui(z, l) > 0; }
1011 static bool eval(unsigned long int l, mpz_srcptr z)
1012 { return mpz_cmp_ui(z, l) < 0; }
1013 static bool eval(mpz_srcptr z, signed long int l)
1014 { return mpz_cmp_si(z, l) > 0; }
1015 static bool eval(signed long int l, mpz_srcptr z)
1016 { return mpz_cmp_si(z, l) < 0; }
1017 static bool eval(mpz_srcptr z, double d)
1018 { return mpz_cmp_d(z, d) > 0; }
1019 static bool eval(double d, mpz_srcptr z)
1020 { return mpz_cmp_d(z, d) < 0; }
1022 static bool eval(mpq_srcptr q, mpq_srcptr r) { return mpq_cmp(q, r) > 0; }
1024 static bool eval(mpq_srcptr q, unsigned long int l)
1025 { return mpq_cmp_ui(q, l, 1) > 0; }
1026 static bool eval(unsigned long int l, mpq_srcptr q)
1027 { return mpq_cmp_ui(q, l, 1) < 0; }
1028 static bool eval(mpq_srcptr q, signed long int l)
1029 { return mpq_cmp_si(q, l, 1) > 0; }
1030 static bool eval(signed long int l, mpq_srcptr q)
1031 { return mpq_cmp_si(q, l, 1) < 0; }
1032 static bool eval(mpq_srcptr q, double d)
1038 b = (mpq_cmp(q, temp) > 0);
1042 static bool eval(double d, mpq_srcptr q)
1048 b = (mpq_cmp(temp, q) > 0);
1053 static bool eval(mpf_srcptr f, mpf_srcptr g) { return mpf_cmp(f, g) > 0; }
1055 static bool eval(mpf_srcptr f, unsigned long int l)
1056 { return mpf_cmp_ui(f, l) > 0; }
1057 static bool eval(unsigned long int l, mpf_srcptr f)
1058 { return mpf_cmp_ui(f, l) < 0; }
1059 static bool eval(mpf_srcptr f, signed long int l)
1060 { return mpf_cmp_si(f, l) > 0; }
1061 static bool eval(signed long int l, mpf_srcptr f)
1062 { return mpf_cmp_si(f, l) < 0; }
1063 static bool eval(mpf_srcptr f, double d)
1064 { return mpf_cmp_d(f, d) > 0; }
1065 static bool eval(double d, mpf_srcptr f)
1066 { return mpf_cmp_d(f, d) < 0; }
1069 struct __gmp_unary_increment
1071 static void eval(mpz_ptr z) { mpz_add_ui(z, z, 1); }
1072 static void eval(mpq_ptr q)
1073 { mpz_add(mpq_numref(q), mpq_numref(q), mpq_denref(q)); }
1074 static void eval(mpf_ptr f) { mpf_add_ui(f, f, 1); }
1077 struct __gmp_unary_decrement
1079 static void eval(mpz_ptr z) { mpz_sub_ui(z, z, 1); }
1080 static void eval(mpq_ptr q)
1081 { mpz_sub(mpq_numref(q), mpq_numref(q), mpq_denref(q)); }
1082 static void eval(mpf_ptr f) { mpf_sub_ui(f, f, 1); }
1085 struct __gmp_abs_function
1087 static void eval(mpz_ptr z, mpz_srcptr w) { mpz_abs(z, w); }
1088 static void eval(mpq_ptr q, mpq_srcptr r) { mpq_abs(q, r); }
1089 static void eval(mpf_ptr f, mpf_srcptr g) { mpf_abs(f, g); }
1092 struct __gmp_trunc_function
1094 static void eval(mpf_ptr f, mpf_srcptr g) { mpf_trunc(f, g); }
1097 struct __gmp_floor_function
1099 static void eval(mpf_ptr f, mpf_srcptr g) { mpf_floor(f, g); }
1102 struct __gmp_ceil_function
1104 static void eval(mpf_ptr f, mpf_srcptr g) { mpf_ceil(f, g); }
1107 struct __gmp_sqrt_function
1109 static void eval(mpz_ptr z, mpz_srcptr w) { mpz_sqrt(z, w); }
1110 static void eval(mpf_ptr f, mpf_srcptr g) { mpf_sqrt(f, g); }
1113 struct __gmp_hypot_function
1115 static void eval(mpf_ptr f, mpf_srcptr g, mpf_srcptr h)
1118 mpf_init2(temp, mpf_get_prec(f));
1119 mpf_mul(temp, g, g);
1121 mpf_add(f, f, temp);
1126 static void eval(mpf_ptr f, mpf_srcptr g, unsigned long int l)
1129 mpf_init2(temp, mpf_get_prec(f));
1130 mpf_mul(temp, g, g);
1133 mpf_add(f, f, temp);
1137 static void eval(mpf_ptr f, unsigned long int l, mpf_srcptr g)
1139 static void eval(mpf_ptr f, mpf_srcptr g, signed long int l)
1142 mpf_init2(temp, mpf_get_prec(f));
1143 mpf_mul(temp, g, g);
1146 mpf_add(f, f, temp);
1150 static void eval(mpf_ptr f, signed long int l, mpf_srcptr g)
1152 static void eval(mpf_ptr f, mpf_srcptr g, double d)
1155 mpf_init2(temp, mpf_get_prec(f));
1156 mpf_mul(temp, g, g);
1159 mpf_add(f, f, temp);
1163 static void eval(mpf_ptr f, double d, mpf_srcptr g)
1167 struct __gmp_sgn_function
1169 static int eval(mpz_srcptr z) { return mpz_sgn(z); }
1170 static int eval(mpq_srcptr q) { return mpq_sgn(q); }
1171 static int eval(mpf_srcptr f) { return mpf_sgn(f); }
1174 struct __gmp_cmp_function
1176 static int eval(mpz_srcptr z, mpz_srcptr w) { return mpz_cmp(z, w); }
1178 static int eval(mpz_srcptr z, unsigned long int l)
1179 { return mpz_cmp_ui(z, l); }
1180 static int eval(unsigned long int l, mpz_srcptr z)
1181 { return -mpz_cmp_ui(z, l); }
1182 static int eval(mpz_srcptr z, signed long int l)
1183 { return mpz_cmp_si(z, l); }
1184 static int eval(signed long int l, mpz_srcptr z)
1185 { return -mpz_cmp_si(z, l); }
1186 static int eval(mpz_srcptr z, double d)
1187 { return mpz_cmp_d(z, d); }
1188 static int eval(double d, mpz_srcptr z)
1189 { return -mpz_cmp_d(z, d); }
1191 static int eval(mpq_srcptr q, mpq_srcptr r) { return mpq_cmp(q, r); }
1193 static int eval(mpq_srcptr q, unsigned long int l)
1194 { return mpq_cmp_ui(q, l, 1); }
1195 static int eval(unsigned long int l, mpq_srcptr q)
1196 { return -mpq_cmp_ui(q, l, 1); }
1197 static int eval(mpq_srcptr q, signed long int l)
1198 { return mpq_cmp_si(q, l, 1); }
1199 static int eval(signed long int l, mpq_srcptr q)
1200 { return -mpq_cmp_si(q, l, 1); }
1201 static int eval(mpq_srcptr q, double d)
1207 i = mpq_cmp(q, temp);
1211 static int eval(double d, mpq_srcptr q)
1217 i = mpq_cmp(temp, q);
1222 static int eval(mpf_srcptr f, mpf_srcptr g) { return mpf_cmp(f, g); }
1224 static int eval(mpf_srcptr f, unsigned long int l)
1225 { return mpf_cmp_ui(f, l); }
1226 static int eval(unsigned long int l, mpf_srcptr f)
1227 { return -mpf_cmp_ui(f, l); }
1228 static int eval(mpf_srcptr f, signed long int l)
1229 { return mpf_cmp_si(f, l); }
1230 static int eval(signed long int l, mpf_srcptr f)
1231 { return -mpf_cmp_si(f, l); }
1232 static int eval(mpf_srcptr f, double d)
1233 { return mpf_cmp_d(f, d); }
1234 static int eval(double d, mpf_srcptr f)
1235 { return -mpf_cmp_d(f, d); }
1238 struct __gmp_rand_function
1240 static void eval(mpz_ptr z, gmp_randstate_t s, mp_bitcnt_t l)
1241 { mpz_urandomb(z, s, l); }
1242 static void eval(mpz_ptr z, gmp_randstate_t s, mpz_srcptr w)
1243 { mpz_urandomm(z, s, w); }
1244 static void eval(mpf_ptr f, gmp_randstate_t s, mp_bitcnt_t prec)
1245 { mpf_urandomb(f, s, prec); }
1249 /**************** Auxiliary classes ****************/
1251 /* this is much the same as gmp_allocated_string in gmp-impl.h
1252 since gmp-impl.h is not publicly available, I redefine it here
1253 I use a different name to avoid possible clashes */
1256 typedef void (*__gmp_freefunc_t) (void *, size_t);
1258 struct __gmp_alloc_cstring
1261 __gmp_alloc_cstring(char *s) { str = s; }
1262 ~__gmp_alloc_cstring()
1264 __gmp_freefunc_t freefunc;
1265 mp_get_memory_functions (NULL, NULL, &freefunc);
1266 (*freefunc) (str, std::strlen(str)+1);
1271 // general expression template class
1272 template <class T, class U>
1276 // templates for resolving expression types
1278 struct __gmp_resolve_ref
1283 template <class T, class U>
1284 struct __gmp_resolve_ref<__gmp_expr<T, U> >
1286 typedef const __gmp_expr<T, U> & ref_type;
1290 template <class T, class U = T>
1291 struct __gmp_resolve_expr;
1294 struct __gmp_resolve_expr<mpz_t>
1296 typedef mpz_t value_type;
1297 typedef mpz_ptr ptr_type;
1298 typedef mpz_srcptr srcptr_type;
1302 struct __gmp_resolve_expr<mpq_t>
1304 typedef mpq_t value_type;
1305 typedef mpq_ptr ptr_type;
1306 typedef mpq_srcptr srcptr_type;
1310 struct __gmp_resolve_expr<mpf_t>
1312 typedef mpf_t value_type;
1313 typedef mpf_ptr ptr_type;
1314 typedef mpf_srcptr srcptr_type;
1318 struct __gmp_resolve_expr<mpz_t, mpq_t>
1320 typedef mpq_t value_type;
1324 struct __gmp_resolve_expr<mpq_t, mpz_t>
1326 typedef mpq_t value_type;
1330 struct __gmp_resolve_expr<mpz_t, mpf_t>
1332 typedef mpf_t value_type;
1336 struct __gmp_resolve_expr<mpf_t, mpz_t>
1338 typedef mpf_t value_type;
1342 struct __gmp_resolve_expr<mpq_t, mpf_t>
1344 typedef mpf_t value_type;
1348 struct __gmp_resolve_expr<mpf_t, mpq_t>
1350 typedef mpf_t value_type;
1353 #if __GMPXX_USE_CXX11
1355 template <class T, class U, class V, class W>
1356 struct common_type <__gmp_expr<T, U>, __gmp_expr<V, W> >
1359 typedef typename __gmp_resolve_expr<T, V>::value_type X;
1361 typedef __gmp_expr<X, X> type;
1364 template <class T, class U>
1365 struct common_type <__gmp_expr<T, U>, __gmp_expr<T, U> >
1367 typedef __gmp_expr<T, U> type;
1370 #define __GMPXX_DECLARE_COMMON_TYPE(typ) \
1371 template <class T, class U> \
1372 struct common_type <__gmp_expr<T, U>, typ > \
1374 typedef __gmp_expr<T, T> type; \
1377 template <class T, class U> \
1378 struct common_type <typ, __gmp_expr<T, U> > \
1380 typedef __gmp_expr<T, T> type; \
1383 __GMPXX_DECLARE_COMMON_TYPE(signed char);
1384 __GMPXX_DECLARE_COMMON_TYPE(unsigned char);
1385 __GMPXX_DECLARE_COMMON_TYPE(signed int);
1386 __GMPXX_DECLARE_COMMON_TYPE(unsigned int);
1387 __GMPXX_DECLARE_COMMON_TYPE(signed short int);
1388 __GMPXX_DECLARE_COMMON_TYPE(unsigned short int);
1389 __GMPXX_DECLARE_COMMON_TYPE(signed long int);
1390 __GMPXX_DECLARE_COMMON_TYPE(unsigned long int);
1391 __GMPXX_DECLARE_COMMON_TYPE(float);
1392 __GMPXX_DECLARE_COMMON_TYPE(double);
1393 #undef __GMPXX_DECLARE_COMMON_TYPE
1397 // classes for evaluating unary and binary expressions
1398 template <class T, class Op>
1399 struct __gmp_unary_expr
1403 __gmp_unary_expr(const T &v) : val(v) { }
1408 template <class T, class U, class Op>
1409 struct __gmp_binary_expr
1411 typename __gmp_resolve_ref<T>::ref_type val1;
1412 typename __gmp_resolve_ref<U>::ref_type val2;
1414 __gmp_binary_expr(const T &v1, const U &v2) : val1(v1), val2(v2) { }
1416 __gmp_binary_expr();
1421 /**************** Macros for in-class declarations ****************/
1422 /* This is just repetitive code that is easier to maintain if it's written
1425 #define __GMPP_DECLARE_COMPOUND_OPERATOR(fun) \
1426 template <class T, class U> \
1427 __gmp_expr<value_type, value_type> & fun(const __gmp_expr<T, U> &);
1429 #define __GMPN_DECLARE_COMPOUND_OPERATOR(fun) \
1430 __gmp_expr & fun(signed char); \
1431 __gmp_expr & fun(unsigned char); \
1432 __gmp_expr & fun(signed int); \
1433 __gmp_expr & fun(unsigned int); \
1434 __gmp_expr & fun(signed short int); \
1435 __gmp_expr & fun(unsigned short int); \
1436 __gmp_expr & fun(signed long int); \
1437 __gmp_expr & fun(unsigned long int); \
1438 __gmp_expr & fun(float); \
1439 __gmp_expr & fun(double); \
1440 /* __gmp_expr & fun(long double); */
1442 #define __GMP_DECLARE_COMPOUND_OPERATOR(fun) \
1443 __GMPP_DECLARE_COMPOUND_OPERATOR(fun) \
1444 __GMPN_DECLARE_COMPOUND_OPERATOR(fun)
1446 #define __GMP_DECLARE_COMPOUND_OPERATOR_UI(fun) \
1447 __gmp_expr & fun(mp_bitcnt_t);
1449 #define __GMP_DECLARE_INCREMENT_OPERATOR(fun) \
1450 inline __gmp_expr & fun(); \
1451 inline __gmp_expr fun(int);
1454 /**************** mpz_class -- wrapper for mpz_t ****************/
1457 class __gmp_expr<mpz_t, mpz_t>
1460 typedef mpz_t value_type;
1463 mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); }
1465 // constructors and destructor
1466 __gmp_expr() { mpz_init(mp); }
1468 __gmp_expr(const __gmp_expr &z) { mpz_init_set(mp, z.mp); }
1469 #if __GMPXX_USE_CXX11
1470 __gmp_expr(__gmp_expr &&z)
1471 { *mp = *z.mp; mpz_init(z.mp); }
1474 __gmp_expr(const __gmp_expr<mpz_t, T> &expr)
1475 { mpz_init(mp); __gmp_set_expr(mp, expr); }
1476 template <class T, class U>
1477 explicit __gmp_expr(const __gmp_expr<T, U> &expr)
1478 { mpz_init(mp); __gmp_set_expr(mp, expr); }
1480 __gmp_expr(signed char c) { mpz_init_set_si(mp, c); }
1481 __gmp_expr(unsigned char c) { mpz_init_set_ui(mp, c); }
1483 __gmp_expr(signed int i) { mpz_init_set_si(mp, i); }
1484 __gmp_expr(unsigned int i) { mpz_init_set_ui(mp, i); }
1486 __gmp_expr(signed short int s) { mpz_init_set_si(mp, s); }
1487 __gmp_expr(unsigned short int s) { mpz_init_set_ui(mp, s); }
1489 __gmp_expr(signed long int l) { mpz_init_set_si(mp, l); }
1490 __gmp_expr(unsigned long int l) { mpz_init_set_ui(mp, l); }
1492 __gmp_expr(float f) { mpz_init_set_d(mp, f); }
1493 __gmp_expr(double d) { mpz_init_set_d(mp, d); }
1494 // __gmp_expr(long double ld) { mpz_init_set_d(mp, ld); }
1496 explicit __gmp_expr(const char *s, int base = 0)
1498 if (mpz_init_set_str (mp, s, base) != 0)
1501 throw std::invalid_argument ("mpz_set_str");
1504 explicit __gmp_expr(const std::string &s, int base = 0)
1506 if (mpz_init_set_str(mp, s.c_str(), base) != 0)
1509 throw std::invalid_argument ("mpz_set_str");
1513 explicit __gmp_expr(mpz_srcptr z) { mpz_init_set(mp, z); }
1515 ~__gmp_expr() { mpz_clear(mp); }
1517 void swap(__gmp_expr& z) __GMPXX_NOEXCEPT { std::swap(*mp, *z.mp); }
1519 // assignment operators
1520 __gmp_expr & operator=(const __gmp_expr &z)
1521 { mpz_set(mp, z.mp); return *this; }
1522 #if __GMPXX_USE_CXX11
1523 __gmp_expr & operator=(__gmp_expr &&z) noexcept
1524 { swap(z); return *this; }
1526 template <class T, class U>
1527 __gmp_expr<value_type, value_type> & operator=(const __gmp_expr<T, U> &expr)
1528 { __gmp_set_expr(mp, expr); return *this; }
1530 __gmp_expr & operator=(signed char c) { mpz_set_si(mp, c); return *this; }
1531 __gmp_expr & operator=(unsigned char c) { mpz_set_ui(mp, c); return *this; }
1533 __gmp_expr & operator=(signed int i) { mpz_set_si(mp, i); return *this; }
1534 __gmp_expr & operator=(unsigned int i) { mpz_set_ui(mp, i); return *this; }
1536 __gmp_expr & operator=(signed short int s)
1537 { mpz_set_si(mp, s); return *this; }
1538 __gmp_expr & operator=(unsigned short int s)
1539 { mpz_set_ui(mp, s); return *this; }
1541 __gmp_expr & operator=(signed long int l)
1542 { mpz_set_si(mp, l); return *this; }
1543 __gmp_expr & operator=(unsigned long int l)
1544 { mpz_set_ui(mp, l); return *this; }
1546 __gmp_expr & operator=(float f) { mpz_set_d(mp, f); return *this; }
1547 __gmp_expr & operator=(double d) { mpz_set_d(mp, d); return *this; }
1548 // __gmp_expr & operator=(long double ld)
1549 // { mpz_set_ld(mp, ld); return *this; }
1551 __gmp_expr & operator=(const char *s)
1553 if (mpz_set_str (mp, s, 0) != 0)
1554 throw std::invalid_argument ("mpz_set_str");
1557 __gmp_expr & operator=(const std::string &s)
1559 if (mpz_set_str(mp, s.c_str(), 0) != 0)
1560 throw std::invalid_argument ("mpz_set_str");
1564 // string input/output functions
1565 int set_str(const char *s, int base)
1566 { return mpz_set_str(mp, s, base); }
1567 int set_str(const std::string &s, int base)
1568 { return mpz_set_str(mp, s.c_str(), base); }
1569 std::string get_str(int base = 10) const
1571 __gmp_alloc_cstring temp(mpz_get_str(0, base, mp));
1572 return std::string(temp.str);
1575 // conversion functions
1576 mpz_srcptr __get_mp() const { return mp; }
1577 mpz_ptr __get_mp() { return mp; }
1578 mpz_srcptr get_mpz_t() const { return mp; }
1579 mpz_ptr get_mpz_t() { return mp; }
1581 signed long int get_si() const { return mpz_get_si(mp); }
1582 unsigned long int get_ui() const { return mpz_get_ui(mp); }
1583 double get_d() const { return mpz_get_d(mp); }
1585 // bool fits_schar_p() const { return mpz_fits_schar_p(mp); }
1586 // bool fits_uchar_p() const { return mpz_fits_uchar_p(mp); }
1587 bool fits_sint_p() const { return mpz_fits_sint_p(mp); }
1588 bool fits_uint_p() const { return mpz_fits_uint_p(mp); }
1589 bool fits_sshort_p() const { return mpz_fits_sshort_p(mp); }
1590 bool fits_ushort_p() const { return mpz_fits_ushort_p(mp); }
1591 bool fits_slong_p() const { return mpz_fits_slong_p(mp); }
1592 bool fits_ulong_p() const { return mpz_fits_ulong_p(mp); }
1593 // bool fits_float_p() const { return mpz_fits_float_p(mp); }
1594 // bool fits_double_p() const { return mpz_fits_double_p(mp); }
1595 // bool fits_ldouble_p() const { return mpz_fits_ldouble_p(mp); }
1597 #if __GMPXX_USE_CXX11
1598 explicit operator bool() const { return mp->_mp_size != 0; }
1602 __GMP_DECLARE_COMPOUND_OPERATOR(operator+=)
1603 __GMP_DECLARE_COMPOUND_OPERATOR(operator-=)
1604 __GMP_DECLARE_COMPOUND_OPERATOR(operator*=)
1605 __GMP_DECLARE_COMPOUND_OPERATOR(operator/=)
1606 __GMP_DECLARE_COMPOUND_OPERATOR(operator%=)
1608 __GMP_DECLARE_COMPOUND_OPERATOR(operator&=)
1609 __GMP_DECLARE_COMPOUND_OPERATOR(operator|=)
1610 __GMP_DECLARE_COMPOUND_OPERATOR(operator^=)
1612 __GMP_DECLARE_COMPOUND_OPERATOR_UI(operator<<=)
1613 __GMP_DECLARE_COMPOUND_OPERATOR_UI(operator>>=)
1615 __GMP_DECLARE_INCREMENT_OPERATOR(operator++)
1616 __GMP_DECLARE_INCREMENT_OPERATOR(operator--)
1619 typedef __gmp_expr<mpz_t, mpz_t> mpz_class;
1622 /**************** mpq_class -- wrapper for mpq_t ****************/
1625 class __gmp_expr<mpq_t, mpq_t>
1628 typedef mpq_t value_type;
1631 mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); }
1632 void canonicalize() { mpq_canonicalize(mp); }
1634 // constructors and destructor
1635 __gmp_expr() { mpq_init(mp); }
1637 __gmp_expr(const __gmp_expr &q)
1639 mpz_init_set(mpq_numref(mp), mpq_numref(q.mp));
1640 mpz_init_set(mpq_denref(mp), mpq_denref(q.mp));
1642 #if __GMPXX_USE_CXX11
1643 __gmp_expr(__gmp_expr &&q)
1644 { *mp = *q.mp; mpq_init(q.mp); }
1647 __gmp_expr(const __gmp_expr<mpz_t, T> &expr)
1648 { mpq_init(mp); __gmp_set_expr(mp, expr); }
1650 __gmp_expr(const __gmp_expr<mpq_t, T> &expr)
1651 { mpq_init(mp); __gmp_set_expr(mp, expr); }
1652 template <class T, class U>
1653 explicit __gmp_expr(const __gmp_expr<T, U> &expr)
1654 { mpq_init(mp); __gmp_set_expr(mp, expr); }
1656 __gmp_expr(signed char c) { mpq_init(mp); mpq_set_si(mp, c, 1); }
1657 __gmp_expr(unsigned char c) { mpq_init(mp); mpq_set_ui(mp, c, 1); }
1659 __gmp_expr(signed int i) { mpq_init(mp); mpq_set_si(mp, i, 1); }
1660 __gmp_expr(unsigned int i) { mpq_init(mp); mpq_set_ui(mp, i, 1); }
1662 __gmp_expr(signed short int s) { mpq_init(mp); mpq_set_si(mp, s, 1); }
1663 __gmp_expr(unsigned short int s) { mpq_init(mp); mpq_set_ui(mp, s, 1); }
1665 __gmp_expr(signed long int l) { mpq_init(mp); mpq_set_si(mp, l, 1); }
1666 __gmp_expr(unsigned long int l) { mpq_init(mp); mpq_set_ui(mp, l, 1); }
1668 __gmp_expr(float f) { mpq_init(mp); mpq_set_d(mp, f); }
1669 __gmp_expr(double d) { mpq_init(mp); mpq_set_d(mp, d); }
1670 // __gmp_expr(long double ld) { mpq_init(mp); mpq_set_ld(mp, ld); }
1672 explicit __gmp_expr(const char *s, int base = 0)
1675 // If s is the literal 0, we meant to call another constructor.
1676 // If s just happens to evaluate to 0, we would crash, so whatever.
1679 // Don't turn mpq_class(0,0) into 0
1680 mpz_set_si(mpq_denref(mp), base);
1682 else if (mpq_set_str(mp, s, base) != 0)
1685 throw std::invalid_argument ("mpq_set_str");
1688 explicit __gmp_expr(const std::string &s, int base = 0)
1691 if (mpq_set_str (mp, s.c_str(), base) != 0)
1694 throw std::invalid_argument ("mpq_set_str");
1697 explicit __gmp_expr(mpq_srcptr q)
1699 mpz_init_set(mpq_numref(mp), mpq_numref(q));
1700 mpz_init_set(mpq_denref(mp), mpq_denref(q));
1703 __gmp_expr(const mpz_class &num, const mpz_class &den)
1705 mpz_init_set(mpq_numref(mp), num.get_mpz_t());
1706 mpz_init_set(mpq_denref(mp), den.get_mpz_t());
1709 ~__gmp_expr() { mpq_clear(mp); }
1711 void swap(__gmp_expr& q) __GMPXX_NOEXCEPT { std::swap(*mp, *q.mp); }
1713 // assignment operators
1714 __gmp_expr & operator=(const __gmp_expr &q)
1715 { mpq_set(mp, q.mp); return *this; }
1716 #if __GMPXX_USE_CXX11
1717 __gmp_expr & operator=(__gmp_expr &&q) noexcept
1718 { swap(q); return *this; }
1719 __gmp_expr & operator=(mpz_class &&z) noexcept
1720 { get_num() = std::move(z); get_den() = 1u; return *this; }
1722 template <class T, class U>
1723 __gmp_expr<value_type, value_type> & operator=(const __gmp_expr<T, U> &expr)
1724 { __gmp_set_expr(mp, expr); return *this; }
1726 __gmp_expr & operator=(signed char c)
1727 { mpq_set_si(mp, c, 1); return *this; }
1728 __gmp_expr & operator=(unsigned char c)
1729 { mpq_set_ui(mp, c, 1); return *this; }
1731 __gmp_expr & operator=(signed int i) { mpq_set_si(mp, i, 1); return *this; }
1732 __gmp_expr & operator=(unsigned int i)
1733 { mpq_set_ui(mp, i, 1); return *this; }
1735 __gmp_expr & operator=(signed short int s)
1736 { mpq_set_si(mp, s, 1); return *this; }
1737 __gmp_expr & operator=(unsigned short int s)
1738 { mpq_set_ui(mp, s, 1); return *this; }
1740 __gmp_expr & operator=(signed long int l)
1741 { mpq_set_si(mp, l, 1); return *this; }
1742 __gmp_expr & operator=(unsigned long int l)
1743 { mpq_set_ui(mp, l, 1); return *this; }
1745 __gmp_expr & operator=(float f) { mpq_set_d(mp, f); return *this; }
1746 __gmp_expr & operator=(double d) { mpq_set_d(mp, d); return *this; }
1747 // __gmp_expr & operator=(long double ld)
1748 // { mpq_set_ld(mp, ld); return *this; }
1750 __gmp_expr & operator=(const char *s)
1752 if (mpq_set_str (mp, s, 0) != 0)
1753 throw std::invalid_argument ("mpq_set_str");
1756 __gmp_expr & operator=(const std::string &s)
1758 if (mpq_set_str(mp, s.c_str(), 0) != 0)
1759 throw std::invalid_argument ("mpq_set_str");
1763 // string input/output functions
1764 int set_str(const char *s, int base)
1765 { return mpq_set_str(mp, s, base); }
1766 int set_str(const std::string &s, int base)
1767 { return mpq_set_str(mp, s.c_str(), base); }
1768 std::string get_str(int base = 10) const
1770 __gmp_alloc_cstring temp(mpq_get_str(0, base, mp));
1771 return std::string(temp.str);
1774 // conversion functions
1776 // casting a reference to an mpz_t to mpz_class & is a dirty hack,
1777 // but works because the internal representation of mpz_class is
1779 const mpz_class & get_num() const
1780 { return reinterpret_cast<const mpz_class &>(*mpq_numref(mp)); }
1781 mpz_class & get_num()
1782 { return reinterpret_cast<mpz_class &>(*mpq_numref(mp)); }
1783 const mpz_class & get_den() const
1784 { return reinterpret_cast<const mpz_class &>(*mpq_denref(mp)); }
1785 mpz_class & get_den()
1786 { return reinterpret_cast<mpz_class &>(*mpq_denref(mp)); }
1788 mpq_srcptr __get_mp() const { return mp; }
1789 mpq_ptr __get_mp() { return mp; }
1790 mpq_srcptr get_mpq_t() const { return mp; }
1791 mpq_ptr get_mpq_t() { return mp; }
1793 mpz_srcptr get_num_mpz_t() const { return mpq_numref(mp); }
1794 mpz_ptr get_num_mpz_t() { return mpq_numref(mp); }
1795 mpz_srcptr get_den_mpz_t() const { return mpq_denref(mp); }
1796 mpz_ptr get_den_mpz_t() { return mpq_denref(mp); }
1798 double get_d() const { return mpq_get_d(mp); }
1800 #if __GMPXX_USE_CXX11
1801 explicit operator bool() const { return mpq_numref(mp)->_mp_size != 0; }
1804 // compound assignments
1805 __GMP_DECLARE_COMPOUND_OPERATOR(operator+=)
1806 __GMP_DECLARE_COMPOUND_OPERATOR(operator-=)
1807 __GMP_DECLARE_COMPOUND_OPERATOR(operator*=)
1808 __GMP_DECLARE_COMPOUND_OPERATOR(operator/=)
1810 __GMP_DECLARE_COMPOUND_OPERATOR_UI(operator<<=)
1811 __GMP_DECLARE_COMPOUND_OPERATOR_UI(operator>>=)
1813 __GMP_DECLARE_INCREMENT_OPERATOR(operator++)
1814 __GMP_DECLARE_INCREMENT_OPERATOR(operator--)
1817 typedef __gmp_expr<mpq_t, mpq_t> mpq_class;
1820 /**************** mpf_class -- wrapper for mpf_t ****************/
1823 class __gmp_expr<mpf_t, mpf_t>
1826 typedef mpf_t value_type;
1829 mp_bitcnt_t get_prec() const { return mpf_get_prec(mp); }
1831 void set_prec(mp_bitcnt_t prec) { mpf_set_prec(mp, prec); }
1832 void set_prec_raw(mp_bitcnt_t prec) { mpf_set_prec_raw(mp, prec); }
1834 // constructors and destructor
1835 __gmp_expr() { mpf_init(mp); }
1837 __gmp_expr(const __gmp_expr &f)
1838 { mpf_init2(mp, f.get_prec()); mpf_set(mp, f.mp); }
1839 #if __GMPXX_USE_CXX11
1840 __gmp_expr(__gmp_expr &&f)
1841 { *mp = *f.mp; mpf_init2(f.mp, get_prec()); }
1843 __gmp_expr(const __gmp_expr &f, mp_bitcnt_t prec)
1844 { mpf_init2(mp, prec); mpf_set(mp, f.mp); }
1845 template <class T, class U>
1846 __gmp_expr(const __gmp_expr<T, U> &expr)
1847 { mpf_init2(mp, expr.get_prec()); __gmp_set_expr(mp, expr); }
1848 template <class T, class U>
1849 __gmp_expr(const __gmp_expr<T, U> &expr, mp_bitcnt_t prec)
1850 { mpf_init2(mp, prec); __gmp_set_expr(mp, expr); }
1852 __gmp_expr(signed char c) { mpf_init_set_si(mp, c); }
1853 __gmp_expr(signed char c, mp_bitcnt_t prec)
1854 { mpf_init2(mp, prec); mpf_set_si(mp, c); }
1855 __gmp_expr(unsigned char c) { mpf_init_set_ui(mp, c); }
1856 __gmp_expr(unsigned char c, mp_bitcnt_t prec)
1857 { mpf_init2(mp, prec); mpf_set_ui(mp, c); }
1859 __gmp_expr(signed int i) { mpf_init_set_si(mp, i); }
1860 __gmp_expr(signed int i, mp_bitcnt_t prec)
1861 { mpf_init2(mp, prec); mpf_set_si(mp, i); }
1862 __gmp_expr(unsigned int i) { mpf_init_set_ui(mp, i); }
1863 __gmp_expr(unsigned int i, mp_bitcnt_t prec)
1864 { mpf_init2(mp, prec); mpf_set_ui(mp, i); }
1866 __gmp_expr(signed short int s) { mpf_init_set_si(mp, s); }
1867 __gmp_expr(signed short int s, mp_bitcnt_t prec)
1868 { mpf_init2(mp, prec); mpf_set_si(mp, s); }
1869 __gmp_expr(unsigned short int s) { mpf_init_set_ui(mp, s); }
1870 __gmp_expr(unsigned short int s, mp_bitcnt_t prec)
1871 { mpf_init2(mp, prec); mpf_set_ui(mp, s); }
1873 __gmp_expr(signed long int l) { mpf_init_set_si(mp, l); }
1874 __gmp_expr(signed long int l, mp_bitcnt_t prec)
1875 { mpf_init2(mp, prec); mpf_set_si(mp, l); }
1876 __gmp_expr(unsigned long int l) { mpf_init_set_ui(mp, l); }
1877 __gmp_expr(unsigned long int l, mp_bitcnt_t prec)
1878 { mpf_init2(mp, prec); mpf_set_ui(mp, l); }
1880 __gmp_expr(float f) { mpf_init_set_d(mp, f); }
1881 __gmp_expr(float f, mp_bitcnt_t prec)
1882 { mpf_init2(mp, prec); mpf_set_d(mp, f); }
1883 __gmp_expr(double d) { mpf_init_set_d(mp, d); }
1884 __gmp_expr(double d, mp_bitcnt_t prec)
1885 { mpf_init2(mp, prec); mpf_set_d(mp, d); }
1886 // __gmp_expr(long double ld) { mpf_init_set_d(mp, ld); }
1887 // __gmp_expr(long double ld, mp_bitcnt_t prec)
1888 // { mpf_init2(mp, prec); mpf_set_d(mp, ld); }
1890 explicit __gmp_expr(const char *s)
1892 if (mpf_init_set_str (mp, s, 0) != 0)
1895 throw std::invalid_argument ("mpf_set_str");
1898 __gmp_expr(const char *s, mp_bitcnt_t prec, int base = 0)
1900 mpf_init2(mp, prec);
1901 if (mpf_set_str(mp, s, base) != 0)
1904 throw std::invalid_argument ("mpf_set_str");
1907 explicit __gmp_expr(const std::string &s)
1909 if (mpf_init_set_str(mp, s.c_str(), 0) != 0)
1912 throw std::invalid_argument ("mpf_set_str");
1915 __gmp_expr(const std::string &s, mp_bitcnt_t prec, int base = 0)
1917 mpf_init2(mp, prec);
1918 if (mpf_set_str(mp, s.c_str(), base) != 0)
1921 throw std::invalid_argument ("mpf_set_str");
1925 explicit __gmp_expr(mpf_srcptr f)
1926 { mpf_init2(mp, mpf_get_prec(f)); mpf_set(mp, f); }
1927 __gmp_expr(mpf_srcptr f, mp_bitcnt_t prec)
1928 { mpf_init2(mp, prec); mpf_set(mp, f); }
1930 ~__gmp_expr() { mpf_clear(mp); }
1932 void swap(__gmp_expr& f) __GMPXX_NOEXCEPT { std::swap(*mp, *f.mp); }
1934 // assignment operators
1935 __gmp_expr & operator=(const __gmp_expr &f)
1936 { mpf_set(mp, f.mp); return *this; }
1937 #if __GMPXX_USE_CXX11
1938 __gmp_expr & operator=(__gmp_expr &&f) noexcept
1939 { swap(f); return *this; }
1941 template <class T, class U>
1942 __gmp_expr<value_type, value_type> & operator=(const __gmp_expr<T, U> &expr)
1943 { __gmp_set_expr(mp, expr); return *this; }
1945 __gmp_expr & operator=(signed char c) { mpf_set_si(mp, c); return *this; }
1946 __gmp_expr & operator=(unsigned char c) { mpf_set_ui(mp, c); return *this; }
1948 __gmp_expr & operator=(signed int i) { mpf_set_si(mp, i); return *this; }
1949 __gmp_expr & operator=(unsigned int i) { mpf_set_ui(mp, i); return *this; }
1951 __gmp_expr & operator=(signed short int s)
1952 { mpf_set_si(mp, s); return *this; }
1953 __gmp_expr & operator=(unsigned short int s)
1954 { mpf_set_ui(mp, s); return *this; }
1956 __gmp_expr & operator=(signed long int l)
1957 { mpf_set_si(mp, l); return *this; }
1958 __gmp_expr & operator=(unsigned long int l)
1959 { mpf_set_ui(mp, l); return *this; }
1961 __gmp_expr & operator=(float f) { mpf_set_d(mp, f); return *this; }
1962 __gmp_expr & operator=(double d) { mpf_set_d(mp, d); return *this; }
1963 // __gmp_expr & operator=(long double ld)
1964 // { mpf_set_ld(mp, ld); return *this; }
1966 __gmp_expr & operator=(const char *s)
1968 if (mpf_set_str (mp, s, 0) != 0)
1969 throw std::invalid_argument ("mpf_set_str");
1972 __gmp_expr & operator=(const std::string &s)
1974 if (mpf_set_str(mp, s.c_str(), 0) != 0)
1975 throw std::invalid_argument ("mpf_set_str");
1979 // string input/output functions
1980 int set_str(const char *s, int base)
1981 { return mpf_set_str(mp, s, base); }
1982 int set_str(const std::string &s, int base)
1983 { return mpf_set_str(mp, s.c_str(), base); }
1984 std::string get_str(mp_exp_t &expo, int base = 10, size_t size = 0) const
1986 __gmp_alloc_cstring temp(mpf_get_str(0, &expo, base, size, mp));
1987 return std::string(temp.str);
1990 // conversion functions
1991 mpf_srcptr __get_mp() const { return mp; }
1992 mpf_ptr __get_mp() { return mp; }
1993 mpf_srcptr get_mpf_t() const { return mp; }
1994 mpf_ptr get_mpf_t() { return mp; }
1996 signed long int get_si() const { return mpf_get_si(mp); }
1997 unsigned long int get_ui() const { return mpf_get_ui(mp); }
1998 double get_d() const { return mpf_get_d(mp); }
2000 // bool fits_schar_p() const { return mpf_fits_schar_p(mp); }
2001 // bool fits_uchar_p() const { return mpf_fits_uchar_p(mp); }
2002 bool fits_sint_p() const { return mpf_fits_sint_p(mp); }
2003 bool fits_uint_p() const { return mpf_fits_uint_p(mp); }
2004 bool fits_sshort_p() const { return mpf_fits_sshort_p(mp); }
2005 bool fits_ushort_p() const { return mpf_fits_ushort_p(mp); }
2006 bool fits_slong_p() const { return mpf_fits_slong_p(mp); }
2007 bool fits_ulong_p() const { return mpf_fits_ulong_p(mp); }
2008 // bool fits_float_p() const { return mpf_fits_float_p(mp); }
2009 // bool fits_double_p() const { return mpf_fits_double_p(mp); }
2010 // bool fits_ldouble_p() const { return mpf_fits_ldouble_p(mp); }
2012 #if __GMPXX_USE_CXX11
2013 explicit operator bool() const { return mp->_mp_size != 0; }
2016 // compound assignments
2017 __GMP_DECLARE_COMPOUND_OPERATOR(operator+=)
2018 __GMP_DECLARE_COMPOUND_OPERATOR(operator-=)
2019 __GMP_DECLARE_COMPOUND_OPERATOR(operator*=)
2020 __GMP_DECLARE_COMPOUND_OPERATOR(operator/=)
2022 __GMP_DECLARE_COMPOUND_OPERATOR_UI(operator<<=)
2023 __GMP_DECLARE_COMPOUND_OPERATOR_UI(operator>>=)
2025 __GMP_DECLARE_INCREMENT_OPERATOR(operator++)
2026 __GMP_DECLARE_INCREMENT_OPERATOR(operator--)
2029 typedef __gmp_expr<mpf_t, mpf_t> mpf_class;
2033 /**************** User-defined literals ****************/
2035 #if __GMPXX_USE_CXX11
2036 inline mpz_class operator"" _mpz(const char* s)
2038 return mpz_class(s);
2041 inline mpq_class operator"" _mpq(const char* s)
2048 inline mpf_class operator"" _mpf(const char* s)
2050 return mpf_class(s);
2054 /**************** I/O operators ****************/
2056 // these should (and will) be provided separately
2058 template <class T, class U>
2059 inline std::ostream & operator<<
2060 (std::ostream &o, const __gmp_expr<T, U> &expr)
2062 __gmp_expr<T, T> const& temp(expr);
2063 return o << temp.__get_mp();
2067 inline std::istream & operator>>(std::istream &i, __gmp_expr<T, T> &expr)
2069 return i >> expr.__get_mp();
2073 // you might want to uncomment this
2074 inline std::istream & operator>>(std::istream &i, mpq_class &q)
2083 /**************** Functions for type conversion ****************/
2085 inline void __gmp_set_expr(mpz_ptr z, const mpz_class &w)
2087 mpz_set(z, w.get_mpz_t());
2091 inline void __gmp_set_expr(mpz_ptr z, const __gmp_expr<mpz_t, T> &expr)
2097 inline void __gmp_set_expr(mpz_ptr z, const __gmp_expr<mpq_t, T> &expr)
2099 mpq_class const& temp(expr);
2100 mpz_set_q(z, temp.get_mpq_t());
2104 inline void __gmp_set_expr(mpz_ptr z, const __gmp_expr<mpf_t, T> &expr)
2106 mpf_class const& temp(expr);
2107 mpz_set_f(z, temp.get_mpf_t());
2110 inline void __gmp_set_expr(mpq_ptr q, const mpz_class &z)
2112 mpq_set_z(q, z.get_mpz_t());
2116 inline void __gmp_set_expr(mpq_ptr q, const __gmp_expr<mpz_t, T> &expr)
2118 __gmp_set_expr(mpq_numref(q), expr);
2119 mpz_set_ui(mpq_denref(q), 1);
2122 inline void __gmp_set_expr(mpq_ptr q, const mpq_class &r)
2124 mpq_set(q, r.get_mpq_t());
2128 inline void __gmp_set_expr(mpq_ptr q, const __gmp_expr<mpq_t, T> &expr)
2134 inline void __gmp_set_expr(mpq_ptr q, const __gmp_expr<mpf_t, T> &expr)
2136 mpf_class const& temp(expr);
2137 mpq_set_f(q, temp.get_mpf_t());
2141 inline void __gmp_set_expr(mpf_ptr f, const __gmp_expr<mpz_t, T> &expr)
2143 mpz_class const& temp(expr);
2144 mpf_set_z(f, temp.get_mpz_t());
2148 inline void __gmp_set_expr(mpf_ptr f, const __gmp_expr<mpq_t, T> &expr)
2150 mpq_class const& temp(expr);
2151 mpf_set_q(f, temp.get_mpq_t());
2154 inline void __gmp_set_expr(mpf_ptr f, const mpf_class &g)
2156 mpf_set(f, g.get_mpf_t());
2160 inline void __gmp_set_expr(mpf_ptr f, const __gmp_expr<mpf_t, T> &expr)
2166 /* Temporary objects */
2171 __gmp_expr<T, T> val;
2173 template<class U, class V>
2174 __gmp_temp(U const& u, V) : val (u) {}
2175 typename __gmp_resolve_expr<T>::srcptr_type
2176 __get_mp() const { return val.__get_mp(); }
2180 class __gmp_temp <mpf_t>
2185 __gmp_temp(U const& u, mpf_ptr res) : val (u, mpf_get_prec(res)) {}
2186 mpf_srcptr __get_mp() const { return val.__get_mp(); }
2189 /**************** Specializations of __gmp_expr ****************/
2190 /* The eval() method of __gmp_expr<T, U> evaluates the corresponding
2191 expression and assigns the result to its argument, which is either an
2192 mpz_t, mpq_t, or mpf_t as specified by the T argument.
2193 Compound expressions are evaluated recursively (temporaries are created
2194 to hold intermediate values), while for simple expressions the eval()
2195 method of the appropriate function object (available as the Op argument
2196 of either __gmp_unary_expr<T, Op> or __gmp_binary_expr<T, U, Op>) is
2200 /**************** Unary expressions ****************/
2202 - simple: argument is mp*_class, that is, __gmp_expr<T, T>
2203 - compound: argument is __gmp_expr<T, U> (with U not equal to T) */
2206 // simple expressions
2208 template <class T, class Op>
2209 class __gmp_expr<T, __gmp_unary_expr<__gmp_expr<T, T>, Op> >
2212 typedef __gmp_expr<T, T> val_type;
2214 __gmp_unary_expr<val_type, Op> expr;
2216 explicit __gmp_expr(const val_type &val) : expr(val) { }
2217 void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
2218 { Op::eval(p, expr.val.__get_mp()); }
2219 const val_type & get_val() const { return expr.val; }
2220 mp_bitcnt_t get_prec() const { return expr.val.get_prec(); }
2224 // compound expressions
2226 template <class T, class U, class Op>
2227 class __gmp_expr<T, __gmp_unary_expr<__gmp_expr<T, U>, Op> >
2230 typedef __gmp_expr<T, U> val_type;
2232 __gmp_unary_expr<val_type, Op> expr;
2234 explicit __gmp_expr(const val_type &val) : expr(val) { }
2235 void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
2236 { expr.val.eval(p); Op::eval(p, p); }
2237 const val_type & get_val() const { return expr.val; }
2238 mp_bitcnt_t get_prec() const { return expr.val.get_prec(); }
2242 /**************** Binary expressions ****************/
2244 - arguments are both mp*_class
2245 - one argument is mp*_class, one is a built-in type
2247 - one is mp*_class, one is __gmp_expr<T, U>
2248 - one is __gmp_expr<T, U>, one is built-in
2249 - both arguments are __gmp_expr<...> */
2252 // simple expressions
2254 template <class T, class Op>
2256 <T, __gmp_binary_expr<__gmp_expr<T, T>, __gmp_expr<T, T>, Op> >
2259 typedef __gmp_expr<T, T> val1_type;
2260 typedef __gmp_expr<T, T> val2_type;
2262 __gmp_binary_expr<val1_type, val2_type, Op> expr;
2264 __gmp_expr(const val1_type &val1, const val2_type &val2)
2265 : expr(val1, val2) { }
2266 void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
2267 { Op::eval(p, expr.val1.__get_mp(), expr.val2.__get_mp()); }
2268 const val1_type & get_val1() const { return expr.val1; }
2269 const val2_type & get_val2() const { return expr.val2; }
2270 mp_bitcnt_t get_prec() const
2272 mp_bitcnt_t prec1 = expr.val1.get_prec(),
2273 prec2 = expr.val2.get_prec();
2274 return (prec1 > prec2) ? prec1 : prec2;
2279 // simple expressions, T is a built-in numerical type
2281 template <class T, class U, class Op>
2282 class __gmp_expr<T, __gmp_binary_expr<__gmp_expr<T, T>, U, Op> >
2285 typedef __gmp_expr<T, T> val1_type;
2286 typedef U val2_type;
2288 __gmp_binary_expr<val1_type, val2_type, Op> expr;
2290 __gmp_expr(const val1_type &val1, const val2_type &val2)
2291 : expr(val1, val2) { }
2292 void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
2293 { Op::eval(p, expr.val1.__get_mp(), expr.val2); }
2294 const val1_type & get_val1() const { return expr.val1; }
2295 const val2_type & get_val2() const { return expr.val2; }
2296 mp_bitcnt_t get_prec() const { return expr.val1.get_prec(); }
2299 template <class T, class U, class Op>
2300 class __gmp_expr<T, __gmp_binary_expr<U, __gmp_expr<T, T>, Op> >
2303 typedef U val1_type;
2304 typedef __gmp_expr<T, T> val2_type;
2306 __gmp_binary_expr<val1_type, val2_type, Op> expr;
2308 __gmp_expr(const val1_type &val1, const val2_type &val2)
2309 : expr(val1, val2) { }
2310 void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
2311 { Op::eval(p, expr.val1, expr.val2.__get_mp()); }
2312 const val1_type & get_val1() const { return expr.val1; }
2313 const val2_type & get_val2() const { return expr.val2; }
2314 mp_bitcnt_t get_prec() const { return expr.val2.get_prec(); }
2318 // compound expressions, one argument is a subexpression
2320 template <class T, class U, class V, class Op>
2322 <T, __gmp_binary_expr<__gmp_expr<T, T>, __gmp_expr<U, V>, Op> >
2325 typedef __gmp_expr<T, T> val1_type;
2326 typedef __gmp_expr<U, V> val2_type;
2328 __gmp_binary_expr<val1_type, val2_type, Op> expr;
2330 __gmp_expr(const val1_type &val1, const val2_type &val2)
2331 : expr(val1, val2) { }
2332 void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
2334 if(p != expr.val1.__get_mp())
2336 __gmp_set_expr(p, expr.val2);
2337 Op::eval(p, expr.val1.__get_mp(), p);
2341 __gmp_temp<T> temp(expr.val2, p);
2342 Op::eval(p, expr.val1.__get_mp(), temp.__get_mp());
2345 const val1_type & get_val1() const { return expr.val1; }
2346 const val2_type & get_val2() const { return expr.val2; }
2347 mp_bitcnt_t get_prec() const
2349 mp_bitcnt_t prec1 = expr.val1.get_prec(),
2350 prec2 = expr.val2.get_prec();
2351 return (prec1 > prec2) ? prec1 : prec2;
2355 template <class T, class U, class V, class Op>
2357 <T, __gmp_binary_expr<__gmp_expr<U, V>, __gmp_expr<T, T>, Op> >
2360 typedef __gmp_expr<U, V> val1_type;
2361 typedef __gmp_expr<T, T> val2_type;
2363 __gmp_binary_expr<val1_type, val2_type, Op> expr;
2365 __gmp_expr(const val1_type &val1, const val2_type &val2)
2366 : expr(val1, val2) { }
2367 void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
2369 if(p != expr.val2.__get_mp())
2371 __gmp_set_expr(p, expr.val1);
2372 Op::eval(p, p, expr.val2.__get_mp());
2376 __gmp_temp<T> temp(expr.val1, p);
2377 Op::eval(p, temp.__get_mp(), expr.val2.__get_mp());
2380 const val1_type & get_val1() const { return expr.val1; }
2381 const val2_type & get_val2() const { return expr.val2; }
2382 mp_bitcnt_t get_prec() const
2384 mp_bitcnt_t prec1 = expr.val1.get_prec(),
2385 prec2 = expr.val2.get_prec();
2386 return (prec1 > prec2) ? prec1 : prec2;
2390 template <class T, class U, class Op>
2392 <T, __gmp_binary_expr<__gmp_expr<T, T>, __gmp_expr<T, U>, Op> >
2395 typedef __gmp_expr<T, T> val1_type;
2396 typedef __gmp_expr<T, U> val2_type;
2398 __gmp_binary_expr<val1_type, val2_type, Op> expr;
2400 __gmp_expr(const val1_type &val1, const val2_type &val2)
2401 : expr(val1, val2) { }
2402 void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
2404 if(p != expr.val1.__get_mp())
2406 __gmp_set_expr(p, expr.val2);
2407 Op::eval(p, expr.val1.__get_mp(), p);
2411 __gmp_temp<T> temp(expr.val2, p);
2412 Op::eval(p, expr.val1.__get_mp(), temp.__get_mp());
2415 const val1_type & get_val1() const { return expr.val1; }
2416 const val2_type & get_val2() const { return expr.val2; }
2417 mp_bitcnt_t get_prec() const
2419 mp_bitcnt_t prec1 = expr.val1.get_prec(),
2420 prec2 = expr.val2.get_prec();
2421 return (prec1 > prec2) ? prec1 : prec2;
2425 template <class T, class U, class Op>
2427 <T, __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<T, T>, Op> >
2430 typedef __gmp_expr<T, U> val1_type;
2431 typedef __gmp_expr<T, T> val2_type;
2433 __gmp_binary_expr<val1_type, val2_type, Op> expr;
2435 __gmp_expr(const val1_type &val1, const val2_type &val2)
2436 : expr(val1, val2) { }
2437 void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
2439 if(p != expr.val2.__get_mp())
2441 __gmp_set_expr(p, expr.val1);
2442 Op::eval(p, p, expr.val2.__get_mp());
2446 __gmp_temp<T> temp(expr.val1, p);
2447 Op::eval(p, temp.__get_mp(), expr.val2.__get_mp());
2450 const val1_type & get_val1() const { return expr.val1; }
2451 const val2_type & get_val2() const { return expr.val2; }
2452 mp_bitcnt_t get_prec() const
2454 mp_bitcnt_t prec1 = expr.val1.get_prec(),
2455 prec2 = expr.val2.get_prec();
2456 return (prec1 > prec2) ? prec1 : prec2;
2461 // one argument is a subexpression, one is a built-in
2463 template <class T, class U, class V, class Op>
2464 class __gmp_expr<T, __gmp_binary_expr<__gmp_expr<T, U>, V, Op> >
2467 typedef __gmp_expr<T, U> val1_type;
2468 typedef V val2_type;
2470 __gmp_binary_expr<val1_type, val2_type, Op> expr;
2472 __gmp_expr(const val1_type &val1, const val2_type &val2)
2473 : expr(val1, val2) { }
2474 void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
2477 Op::eval(p, p, expr.val2);
2479 const val1_type & get_val1() const { return expr.val1; }
2480 const val2_type & get_val2() const { return expr.val2; }
2481 mp_bitcnt_t get_prec() const { return expr.val1.get_prec(); }
2484 template <class T, class U, class V, class Op>
2485 class __gmp_expr<T, __gmp_binary_expr<U, __gmp_expr<T, V>, Op> >
2488 typedef U val1_type;
2489 typedef __gmp_expr<T, V> val2_type;
2491 __gmp_binary_expr<val1_type, val2_type, Op> expr;
2493 __gmp_expr(const val1_type &val1, const val2_type &val2)
2494 : expr(val1, val2) { }
2495 void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
2498 Op::eval(p, expr.val1, p);
2500 const val1_type & get_val1() const { return expr.val1; }
2501 const val2_type & get_val2() const { return expr.val2; }
2502 mp_bitcnt_t get_prec() const { return expr.val2.get_prec(); }
2506 // both arguments are subexpressions
2508 template <class T, class U, class V, class W, class Op>
2510 <T, __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<V, W>, Op> >
2513 typedef __gmp_expr<T, U> val1_type;
2514 typedef __gmp_expr<V, W> val2_type;
2516 __gmp_binary_expr<val1_type, val2_type, Op> expr;
2518 __gmp_expr(const val1_type &val1, const val2_type &val2)
2519 : expr(val1, val2) { }
2520 void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
2522 __gmp_temp<T> temp2(expr.val2, p);
2524 Op::eval(p, p, temp2.__get_mp());
2526 const val1_type & get_val1() const { return expr.val1; }
2527 const val2_type & get_val2() const { return expr.val2; }
2528 mp_bitcnt_t get_prec() const
2530 mp_bitcnt_t prec1 = expr.val1.get_prec(),
2531 prec2 = expr.val2.get_prec();
2532 return (prec1 > prec2) ? prec1 : prec2;
2536 template <class T, class U, class V, class W, class Op>
2538 <T, __gmp_binary_expr<__gmp_expr<U, V>, __gmp_expr<T, W>, Op> >
2541 typedef __gmp_expr<U, V> val1_type;
2542 typedef __gmp_expr<T, W> val2_type;
2544 __gmp_binary_expr<val1_type, val2_type, Op> expr;
2546 __gmp_expr(const val1_type &val1, const val2_type &val2)
2547 : expr(val1, val2) { }
2548 void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
2550 __gmp_temp<T> temp1(expr.val1, p);
2552 Op::eval(p, temp1.__get_mp(), p);
2554 const val1_type & get_val1() const { return expr.val1; }
2555 const val2_type & get_val2() const { return expr.val2; }
2556 mp_bitcnt_t get_prec() const
2558 mp_bitcnt_t prec1 = expr.val1.get_prec(),
2559 prec2 = expr.val2.get_prec();
2560 return (prec1 > prec2) ? prec1 : prec2;
2564 template <class T, class U, class V, class Op>
2566 <T, __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<T, V>, Op> >
2569 typedef __gmp_expr<T, U> val1_type;
2570 typedef __gmp_expr<T, V> val2_type;
2572 __gmp_binary_expr<val1_type, val2_type, Op> expr;
2574 __gmp_expr(const val1_type &val1, const val2_type &val2)
2575 : expr(val1, val2) { }
2576 void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
2578 __gmp_temp<T> temp2(expr.val2, p);
2580 Op::eval(p, p, temp2.__get_mp());
2582 const val1_type & get_val1() const { return expr.val1; }
2583 const val2_type & get_val2() const { return expr.val2; }
2584 mp_bitcnt_t get_prec() const
2586 mp_bitcnt_t prec1 = expr.val1.get_prec(),
2587 prec2 = expr.val2.get_prec();
2588 return (prec1 > prec2) ? prec1 : prec2;
2593 /**************** Special cases ****************/
2595 /* Some operations (i.e., add and subtract) with mixed mpz/mpq arguments
2596 can be done directly without first converting the mpz to mpq.
2597 Appropriate specializations of __gmp_expr are required. */
2600 #define __GMPZQ_DEFINE_EXPR(eval_fun) \
2603 class __gmp_expr<mpq_t, __gmp_binary_expr<mpz_class, mpq_class, eval_fun> > \
2606 typedef mpz_class val1_type; \
2607 typedef mpq_class val2_type; \
2609 __gmp_binary_expr<val1_type, val2_type, eval_fun> expr; \
2611 __gmp_expr(const val1_type &val1, const val2_type &val2) \
2612 : expr(val1, val2) { } \
2613 void eval(mpq_ptr q) const \
2614 { eval_fun::eval(q, expr.val1.get_mpz_t(), expr.val2.get_mpq_t()); } \
2615 const val1_type & get_val1() const { return expr.val1; } \
2616 const val2_type & get_val2() const { return expr.val2; } \
2617 mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); } \
2621 class __gmp_expr<mpq_t, __gmp_binary_expr<mpq_class, mpz_class, eval_fun> > \
2624 typedef mpq_class val1_type; \
2625 typedef mpz_class val2_type; \
2627 __gmp_binary_expr<val1_type, val2_type, eval_fun> expr; \
2629 __gmp_expr(const val1_type &val1, const val2_type &val2) \
2630 : expr(val1, val2) { } \
2631 void eval(mpq_ptr q) const \
2632 { eval_fun::eval(q, expr.val1.get_mpq_t(), expr.val2.get_mpz_t()); } \
2633 const val1_type & get_val1() const { return expr.val1; } \
2634 const val2_type & get_val2() const { return expr.val2; } \
2635 mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); } \
2638 template <class T> \
2640 <mpq_t, __gmp_binary_expr<mpz_class, __gmp_expr<mpq_t, T>, eval_fun> > \
2643 typedef mpz_class val1_type; \
2644 typedef __gmp_expr<mpq_t, T> val2_type; \
2646 __gmp_binary_expr<val1_type, val2_type, eval_fun> expr; \
2648 __gmp_expr(const val1_type &val1, const val2_type &val2) \
2649 : expr(val1, val2) { } \
2650 void eval(mpq_ptr q) const \
2652 mpq_class temp(expr.val2); \
2653 eval_fun::eval(q, expr.val1.get_mpz_t(), temp.get_mpq_t()); \
2655 const val1_type & get_val1() const { return expr.val1; } \
2656 const val2_type & get_val2() const { return expr.val2; } \
2657 mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); } \
2660 template <class T> \
2662 <mpq_t, __gmp_binary_expr<mpq_class, __gmp_expr<mpz_t, T>, eval_fun> > \
2665 typedef mpq_class val1_type; \
2666 typedef __gmp_expr<mpz_t, T> val2_type; \
2668 __gmp_binary_expr<val1_type, val2_type, eval_fun> expr; \
2670 __gmp_expr(const val1_type &val1, const val2_type &val2) \
2671 : expr(val1, val2) { } \
2672 void eval(mpq_ptr q) const \
2674 mpz_class temp(expr.val2); \
2675 eval_fun::eval(q, expr.val1.get_mpq_t(), temp.get_mpz_t()); \
2677 const val1_type & get_val1() const { return expr.val1; } \
2678 const val2_type & get_val2() const { return expr.val2; } \
2679 mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); } \
2682 template <class T> \
2684 <mpq_t, __gmp_binary_expr<__gmp_expr<mpz_t, T>, mpq_class, eval_fun> > \
2687 typedef __gmp_expr<mpz_t, T> val1_type; \
2688 typedef mpq_class val2_type; \
2690 __gmp_binary_expr<val1_type, val2_type, eval_fun> expr; \
2692 __gmp_expr(const val1_type &val1, const val2_type &val2) \
2693 : expr(val1, val2) { } \
2694 void eval(mpq_ptr q) const \
2696 mpz_class temp(expr.val1); \
2697 eval_fun::eval(q, temp.get_mpz_t(), expr.val2.get_mpq_t()); \
2699 const val1_type & get_val1() const { return expr.val1; } \
2700 const val2_type & get_val2() const { return expr.val2; } \
2701 mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); } \
2704 template <class T> \
2706 <mpq_t, __gmp_binary_expr<__gmp_expr<mpq_t, T>, mpz_class, eval_fun> > \
2709 typedef __gmp_expr<mpq_t, T> val1_type; \
2710 typedef mpz_class val2_type; \
2712 __gmp_binary_expr<val1_type, val2_type, eval_fun> expr; \
2714 __gmp_expr(const val1_type &val1, const val2_type &val2) \
2715 : expr(val1, val2) { } \
2716 void eval(mpq_ptr q) const \
2718 mpq_class temp(expr.val1); \
2719 eval_fun::eval(q, temp.get_mpq_t(), expr.val2.get_mpz_t()); \
2721 const val1_type & get_val1() const { return expr.val1; } \
2722 const val2_type & get_val2() const { return expr.val2; } \
2723 mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); } \
2726 template <class T, class U> \
2727 class __gmp_expr<mpq_t, __gmp_binary_expr \
2728 <__gmp_expr<mpz_t, T>, __gmp_expr<mpq_t, U>, eval_fun> > \
2731 typedef __gmp_expr<mpz_t, T> val1_type; \
2732 typedef __gmp_expr<mpq_t, U> val2_type; \
2734 __gmp_binary_expr<val1_type, val2_type, eval_fun> expr; \
2736 __gmp_expr(const val1_type &val1, const val2_type &val2) \
2737 : expr(val1, val2) { } \
2738 void eval(mpq_ptr q) const \
2740 mpz_class temp1(expr.val1); \
2741 expr.val2.eval(q); \
2742 eval_fun::eval(q, temp1.get_mpz_t(), q); \
2744 const val1_type & get_val1() const { return expr.val1; } \
2745 const val2_type & get_val2() const { return expr.val2; } \
2746 mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); } \
2749 template <class T, class U> \
2750 class __gmp_expr<mpq_t, __gmp_binary_expr \
2751 <__gmp_expr<mpq_t, T>, __gmp_expr<mpz_t, U>, eval_fun> > \
2754 typedef __gmp_expr<mpq_t, T> val1_type; \
2755 typedef __gmp_expr<mpz_t, U> val2_type; \
2757 __gmp_binary_expr<val1_type, val2_type, eval_fun> expr; \
2759 __gmp_expr(const val1_type &val1, const val2_type &val2) \
2760 : expr(val1, val2) { } \
2761 void eval(mpq_ptr q) const \
2763 mpz_class temp2(expr.val2); \
2764 expr.val1.eval(q); \
2765 eval_fun::eval(q, q, temp2.get_mpz_t()); \
2767 const val1_type & get_val1() const { return expr.val1; } \
2768 const val2_type & get_val2() const { return expr.val2; } \
2769 mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); } \
2773 __GMPZQ_DEFINE_EXPR(__gmp_binary_plus)
2774 __GMPZQ_DEFINE_EXPR(__gmp_binary_minus)
2778 /**************** Macros for defining functions ****************/
2779 /* Results of operators and functions are instances of __gmp_expr<T, U>.
2780 T determines the numerical type of the expression: it can be either
2781 mpz_t, mpq_t, or mpf_t. When the arguments of a binary
2782 expression have different numerical types, __gmp_resolve_expr is used
2783 to determine the "larger" type.
2784 U is either __gmp_unary_expr<V, Op> or __gmp_binary_expr<V, W, Op>,
2785 where V and W are the arguments' types -- they can in turn be
2786 expressions, thus allowing to build compound expressions to any
2787 degree of complexity.
2788 Op is a function object that must have an eval() method accepting
2789 appropriate arguments.
2790 Actual evaluation of a __gmp_expr<T, U> object is done when it gets
2791 assigned to an mp*_class ("lazy" evaluation): this is done by calling
2792 its eval() method. */
2795 // non-member unary operators and functions
2797 #define __GMP_DEFINE_UNARY_FUNCTION(fun, eval_fun) \
2799 template <class T, class U> \
2800 inline __gmp_expr<T, __gmp_unary_expr<__gmp_expr<T, U>, eval_fun> > \
2801 fun(const __gmp_expr<T, U> &expr) \
2803 return __gmp_expr<T, __gmp_unary_expr<__gmp_expr<T, U>, eval_fun> >(expr); \
2806 #define __GMP_DEFINE_UNARY_TYPE_FUNCTION(type, fun, eval_fun) \
2808 template <class T, class U> \
2809 inline type fun(const __gmp_expr<T, U> &expr) \
2811 __gmp_expr<T, T> const& temp(expr); \
2812 return eval_fun::eval(temp.__get_mp()); \
2816 // non-member binary operators and functions
2818 #define __GMPP_DEFINE_BINARY_FUNCTION(fun, eval_fun) \
2820 template <class T, class U, class V, class W> \
2821 inline __gmp_expr<typename __gmp_resolve_expr<T, V>::value_type, \
2822 __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<V, W>, eval_fun> > \
2823 fun(const __gmp_expr<T, U> &expr1, const __gmp_expr<V, W> &expr2) \
2825 return __gmp_expr<typename __gmp_resolve_expr<T, V>::value_type, \
2826 __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<V, W>, eval_fun> > \
2830 #define __GMPNN_DEFINE_BINARY_FUNCTION(fun, eval_fun, type, bigtype) \
2832 template <class T, class U> \
2834 <T, __gmp_binary_expr<__gmp_expr<T, U>, bigtype, eval_fun> > \
2835 fun(const __gmp_expr<T, U> &expr, type t) \
2838 <T, __gmp_binary_expr<__gmp_expr<T, U>, bigtype, eval_fun> >(expr, t); \
2841 template <class T, class U> \
2843 <T, __gmp_binary_expr<bigtype, __gmp_expr<T, U>, eval_fun> > \
2844 fun(type t, const __gmp_expr<T, U> &expr) \
2847 <T, __gmp_binary_expr<bigtype, __gmp_expr<T, U>, eval_fun> >(t, expr); \
2850 #define __GMPNS_DEFINE_BINARY_FUNCTION(fun, eval_fun, type) \
2851 __GMPNN_DEFINE_BINARY_FUNCTION(fun, eval_fun, type, signed long int)
2853 #define __GMPNU_DEFINE_BINARY_FUNCTION(fun, eval_fun, type) \
2854 __GMPNN_DEFINE_BINARY_FUNCTION(fun, eval_fun, type, unsigned long int)
2856 #define __GMPND_DEFINE_BINARY_FUNCTION(fun, eval_fun, type) \
2857 __GMPNN_DEFINE_BINARY_FUNCTION(fun, eval_fun, type, double)
2859 #define __GMPNLD_DEFINE_BINARY_FUNCTION(fun, eval_fun, type) \
2860 __GMPNN_DEFINE_BINARY_FUNCTION(fun, eval_fun, type, long double)
2862 #define __GMPN_DEFINE_BINARY_FUNCTION(fun, eval_fun) \
2863 __GMPNS_DEFINE_BINARY_FUNCTION(fun, eval_fun, signed char) \
2864 __GMPNU_DEFINE_BINARY_FUNCTION(fun, eval_fun, unsigned char) \
2865 __GMPNS_DEFINE_BINARY_FUNCTION(fun, eval_fun, signed int) \
2866 __GMPNU_DEFINE_BINARY_FUNCTION(fun, eval_fun, unsigned int) \
2867 __GMPNS_DEFINE_BINARY_FUNCTION(fun, eval_fun, signed short int) \
2868 __GMPNU_DEFINE_BINARY_FUNCTION(fun, eval_fun, unsigned short int) \
2869 __GMPNS_DEFINE_BINARY_FUNCTION(fun, eval_fun, signed long int) \
2870 __GMPNU_DEFINE_BINARY_FUNCTION(fun, eval_fun, unsigned long int) \
2871 __GMPND_DEFINE_BINARY_FUNCTION(fun, eval_fun, float) \
2872 __GMPND_DEFINE_BINARY_FUNCTION(fun, eval_fun, double) \
2873 /* __GMPNLD_DEFINE_BINARY_FUNCTION(fun, eval_fun, long double) */
2875 #define __GMP_DEFINE_BINARY_FUNCTION(fun, eval_fun) \
2876 __GMPP_DEFINE_BINARY_FUNCTION(fun, eval_fun) \
2877 __GMPN_DEFINE_BINARY_FUNCTION(fun, eval_fun)
2880 #define __GMP_DEFINE_BINARY_FUNCTION_UI(fun, eval_fun) \
2882 template <class T, class U> \
2884 <T, __gmp_binary_expr<__gmp_expr<T, U>, mp_bitcnt_t, eval_fun> > \
2885 fun(const __gmp_expr<T, U> &expr, mp_bitcnt_t l) \
2887 return __gmp_expr<T, __gmp_binary_expr \
2888 <__gmp_expr<T, U>, mp_bitcnt_t, eval_fun> >(expr, l); \
2892 #define __GMPP_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun) \
2894 template <class T, class U, class V, class W> \
2895 inline type fun(const __gmp_expr<T, U> &expr1, \
2896 const __gmp_expr<V, W> &expr2) \
2898 typedef typename __gmp_resolve_expr<T, V>::value_type eval_type; \
2899 __gmp_expr<eval_type, eval_type> const& temp1(expr1); \
2900 __gmp_expr<eval_type, eval_type> const& temp2(expr2); \
2901 return eval_fun::eval(temp1.__get_mp(), temp2.__get_mp()); \
2904 #define __GMPNN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, \
2907 template <class T, class U> \
2908 inline type fun(const __gmp_expr<T, U> &expr, type2 t) \
2910 __gmp_expr<T, T> const& temp(expr); \
2911 return eval_fun::eval(temp.__get_mp(), static_cast<bigtype>(t)); \
2914 template <class T, class U> \
2915 inline type fun(type2 t, const __gmp_expr<T, U> &expr) \
2917 __gmp_expr<T, T> const& temp(expr); \
2918 return eval_fun::eval(static_cast<bigtype>(t), temp.__get_mp()); \
2921 #define __GMPNS_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, type2) \
2922 __GMPNN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, \
2923 type2, signed long int)
2925 #define __GMPNU_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, type2) \
2926 __GMPNN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, \
2927 type2, unsigned long int)
2929 #define __GMPND_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, type2) \
2930 __GMPNN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, type2, double)
2932 #define __GMPNLD_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, type2) \
2933 __GMPNN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, type2, long double)
2935 #define __GMPN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun) \
2936 __GMPNS_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, signed char) \
2937 __GMPNU_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, unsigned char) \
2938 __GMPNS_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, signed int) \
2939 __GMPNU_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, unsigned int) \
2940 __GMPNS_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, signed short int) \
2941 __GMPNU_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, unsigned short int) \
2942 __GMPNS_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, signed long int) \
2943 __GMPNU_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, unsigned long int) \
2944 __GMPND_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, float) \
2945 __GMPND_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, double) \
2946 /* __GMPNLD_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, long double) */
2948 #define __GMP_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun) \
2949 __GMPP_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun) \
2950 __GMPN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun)
2955 #define __GMPP_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun) \
2957 template <class T, class U> \
2958 inline type##_class & type##_class::fun(const __gmp_expr<T, U> &expr) \
2960 __gmp_set_expr(mp, __gmp_expr<type##_t, __gmp_binary_expr \
2961 <type##_class, __gmp_expr<T, U>, eval_fun> >(*this, expr)); \
2965 #define __GMPNN_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, \
2968 inline type##_class & type##_class::fun(type2 t) \
2970 __gmp_set_expr(mp, __gmp_expr<type##_t, __gmp_binary_expr \
2971 <type##_class, bigtype, eval_fun> >(*this, t)); \
2975 #define __GMPNS_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, type2) \
2976 __GMPNN_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, \
2977 type2, signed long int)
2979 #define __GMPNU_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, type2) \
2980 __GMPNN_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, \
2981 type2, unsigned long int)
2983 #define __GMPND_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, type2) \
2984 __GMPNN_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, type2, double)
2986 #define __GMPNLD_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, type2) \
2987 __GMPNN_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, type2, long double)
2989 #define __GMPN_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun) \
2990 __GMPNS_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, signed char) \
2991 __GMPNU_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, unsigned char) \
2992 __GMPNS_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, signed int) \
2993 __GMPNU_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, unsigned int) \
2994 __GMPNS_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, signed short int) \
2995 __GMPNU_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, unsigned short int) \
2996 __GMPNS_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, signed long int) \
2997 __GMPNU_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, unsigned long int) \
2998 __GMPND_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, float) \
2999 __GMPND_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, double) \
3000 /* __GMPNLD_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, long double) */
3002 #define __GMP_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun) \
3003 __GMPP_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun) \
3004 __GMPN_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun)
3006 #define __GMPZ_DEFINE_COMPOUND_OPERATOR(fun, eval_fun) \
3007 __GMP_DEFINE_COMPOUND_OPERATOR(mpz, fun, eval_fun)
3009 #define __GMPQ_DEFINE_COMPOUND_OPERATOR(fun, eval_fun) \
3010 __GMP_DEFINE_COMPOUND_OPERATOR(mpq, fun, eval_fun)
3012 #define __GMPF_DEFINE_COMPOUND_OPERATOR(fun, eval_fun) \
3013 __GMP_DEFINE_COMPOUND_OPERATOR(mpf, fun, eval_fun)
3017 #define __GMP_DEFINE_COMPOUND_OPERATOR_UI(type, fun, eval_fun) \
3019 inline type##_class & type##_class::fun(mp_bitcnt_t l) \
3021 __gmp_set_expr(mp, __gmp_expr<type##_t, __gmp_binary_expr \
3022 <type##_class, mp_bitcnt_t, eval_fun> >(*this, l)); \
3026 #define __GMPZ_DEFINE_COMPOUND_OPERATOR_UI(fun, eval_fun) \
3027 __GMP_DEFINE_COMPOUND_OPERATOR_UI(mpz, fun, eval_fun)
3029 #define __GMPQ_DEFINE_COMPOUND_OPERATOR_UI(fun, eval_fun) \
3030 __GMP_DEFINE_COMPOUND_OPERATOR_UI(mpq, fun, eval_fun)
3032 #define __GMPF_DEFINE_COMPOUND_OPERATOR_UI(fun, eval_fun) \
3033 __GMP_DEFINE_COMPOUND_OPERATOR_UI(mpf, fun, eval_fun)
3037 #define __GMP_DEFINE_INCREMENT_OPERATOR(type, fun, eval_fun) \
3039 inline type##_class & type##_class::fun() \
3041 eval_fun::eval(mp); \
3045 inline type##_class type##_class::fun(int) \
3047 type##_class temp(*this); \
3048 eval_fun::eval(mp); \
3052 #define __GMPZ_DEFINE_INCREMENT_OPERATOR(fun, eval_fun) \
3053 __GMP_DEFINE_INCREMENT_OPERATOR(mpz, fun, eval_fun)
3055 #define __GMPQ_DEFINE_INCREMENT_OPERATOR(fun, eval_fun) \
3056 __GMP_DEFINE_INCREMENT_OPERATOR(mpq, fun, eval_fun)
3058 #define __GMPF_DEFINE_INCREMENT_OPERATOR(fun, eval_fun) \
3059 __GMP_DEFINE_INCREMENT_OPERATOR(mpf, fun, eval_fun)
3063 /**************** Arithmetic operators and functions ****************/
3065 // non-member operators and functions
3067 __GMP_DEFINE_UNARY_FUNCTION(operator+, __gmp_unary_plus)
3068 __GMP_DEFINE_UNARY_FUNCTION(operator-, __gmp_unary_minus)
3069 __GMP_DEFINE_UNARY_FUNCTION(operator~, __gmp_unary_com)
3071 __GMP_DEFINE_BINARY_FUNCTION(operator+, __gmp_binary_plus)
3072 __GMP_DEFINE_BINARY_FUNCTION(operator-, __gmp_binary_minus)
3073 __GMP_DEFINE_BINARY_FUNCTION(operator*, __gmp_binary_multiplies)
3074 __GMP_DEFINE_BINARY_FUNCTION(operator/, __gmp_binary_divides)
3075 __GMP_DEFINE_BINARY_FUNCTION(operator%, __gmp_binary_modulus)
3076 __GMP_DEFINE_BINARY_FUNCTION(operator&, __gmp_binary_and)
3077 __GMP_DEFINE_BINARY_FUNCTION(operator|, __gmp_binary_ior)
3078 __GMP_DEFINE_BINARY_FUNCTION(operator^, __gmp_binary_xor)
3080 __GMP_DEFINE_BINARY_FUNCTION_UI(operator<<, __gmp_binary_lshift)
3081 __GMP_DEFINE_BINARY_FUNCTION_UI(operator>>, __gmp_binary_rshift)
3083 __GMP_DEFINE_BINARY_TYPE_FUNCTION(bool, operator==, __gmp_binary_equal)
3084 __GMP_DEFINE_BINARY_TYPE_FUNCTION(bool, operator!=, ! __gmp_binary_equal)
3085 __GMP_DEFINE_BINARY_TYPE_FUNCTION(bool, operator<, __gmp_binary_less)
3086 __GMP_DEFINE_BINARY_TYPE_FUNCTION(bool, operator<=, ! __gmp_binary_greater)
3087 __GMP_DEFINE_BINARY_TYPE_FUNCTION(bool, operator>, __gmp_binary_greater)
3088 __GMP_DEFINE_BINARY_TYPE_FUNCTION(bool, operator>=, ! __gmp_binary_less)
3090 __GMP_DEFINE_UNARY_FUNCTION(abs, __gmp_abs_function)
3091 __GMP_DEFINE_UNARY_FUNCTION(trunc, __gmp_trunc_function)
3092 __GMP_DEFINE_UNARY_FUNCTION(floor, __gmp_floor_function)
3093 __GMP_DEFINE_UNARY_FUNCTION(ceil, __gmp_ceil_function)
3094 __GMP_DEFINE_UNARY_FUNCTION(sqrt, __gmp_sqrt_function)
3095 __GMP_DEFINE_BINARY_FUNCTION(hypot, __gmp_hypot_function)
3097 __GMP_DEFINE_UNARY_TYPE_FUNCTION(int, sgn, __gmp_sgn_function)
3098 __GMP_DEFINE_BINARY_TYPE_FUNCTION(int, cmp, __gmp_cmp_function)
3101 void swap(__gmp_expr<T, T>& x, __gmp_expr<T, T>& y) __GMPXX_NOEXCEPT
3104 // member operators for mpz_class
3106 __GMPZ_DEFINE_COMPOUND_OPERATOR(operator+=, __gmp_binary_plus)
3107 __GMPZ_DEFINE_COMPOUND_OPERATOR(operator-=, __gmp_binary_minus)
3108 __GMPZ_DEFINE_COMPOUND_OPERATOR(operator*=, __gmp_binary_multiplies)
3109 __GMPZ_DEFINE_COMPOUND_OPERATOR(operator/=, __gmp_binary_divides)
3110 __GMPZ_DEFINE_COMPOUND_OPERATOR(operator%=, __gmp_binary_modulus)
3112 __GMPZ_DEFINE_COMPOUND_OPERATOR(operator&=, __gmp_binary_and)
3113 __GMPZ_DEFINE_COMPOUND_OPERATOR(operator|=, __gmp_binary_ior)
3114 __GMPZ_DEFINE_COMPOUND_OPERATOR(operator^=, __gmp_binary_xor)
3116 __GMPZ_DEFINE_COMPOUND_OPERATOR_UI(operator<<=, __gmp_binary_lshift)
3117 __GMPZ_DEFINE_COMPOUND_OPERATOR_UI(operator>>=, __gmp_binary_rshift)
3119 __GMPZ_DEFINE_INCREMENT_OPERATOR(operator++, __gmp_unary_increment)
3120 __GMPZ_DEFINE_INCREMENT_OPERATOR(operator--, __gmp_unary_decrement)
3122 // member operators for mpq_class
3124 __GMPQ_DEFINE_COMPOUND_OPERATOR(operator+=, __gmp_binary_plus)
3125 __GMPQ_DEFINE_COMPOUND_OPERATOR(operator-=, __gmp_binary_minus)
3126 __GMPQ_DEFINE_COMPOUND_OPERATOR(operator*=, __gmp_binary_multiplies)
3127 __GMPQ_DEFINE_COMPOUND_OPERATOR(operator/=, __gmp_binary_divides)
3129 __GMPQ_DEFINE_COMPOUND_OPERATOR_UI(operator<<=, __gmp_binary_lshift)
3130 __GMPQ_DEFINE_COMPOUND_OPERATOR_UI(operator>>=, __gmp_binary_rshift)
3132 __GMPQ_DEFINE_INCREMENT_OPERATOR(operator++, __gmp_unary_increment)
3133 __GMPQ_DEFINE_INCREMENT_OPERATOR(operator--, __gmp_unary_decrement)
3135 // member operators for mpf_class
3137 __GMPF_DEFINE_COMPOUND_OPERATOR(operator+=, __gmp_binary_plus)
3138 __GMPF_DEFINE_COMPOUND_OPERATOR(operator-=, __gmp_binary_minus)
3139 __GMPF_DEFINE_COMPOUND_OPERATOR(operator*=, __gmp_binary_multiplies)
3140 __GMPF_DEFINE_COMPOUND_OPERATOR(operator/=, __gmp_binary_divides)
3142 __GMPF_DEFINE_COMPOUND_OPERATOR_UI(operator<<=, __gmp_binary_lshift)
3143 __GMPF_DEFINE_COMPOUND_OPERATOR_UI(operator>>=, __gmp_binary_rshift)
3145 __GMPF_DEFINE_INCREMENT_OPERATOR(operator++, __gmp_unary_increment)
3146 __GMPF_DEFINE_INCREMENT_OPERATOR(operator--, __gmp_unary_decrement)
3150 /**************** Class wrapper for gmp_randstate_t ****************/
3152 class __gmp_urandomb_value { };
3153 class __gmp_urandomm_value { };
3156 class __gmp_expr<mpz_t, __gmp_urandomb_value>
3159 __gmp_randstate_struct *state;
3162 __gmp_expr(gmp_randstate_t s, mp_bitcnt_t l) : state(s), bits(l) { }
3163 void eval(mpz_ptr z) const { __gmp_rand_function::eval(z, state, bits); }
3164 mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); }
3168 class __gmp_expr<mpz_t, __gmp_urandomm_value>
3171 __gmp_randstate_struct *state;
3174 __gmp_expr(gmp_randstate_t s, const mpz_class &z) : state(s), range(z) { }
3175 void eval(mpz_ptr z) const
3176 { __gmp_rand_function::eval(z, state, range.get_mpz_t()); }
3177 mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); }
3181 class __gmp_expr<mpf_t, __gmp_urandomb_value>
3184 __gmp_randstate_struct *state;
3187 __gmp_expr(gmp_randstate_t s, mp_bitcnt_t l) : state(s), bits(l) { }
3188 void eval(mpf_ptr f) const
3190 __gmp_rand_function::eval(f, state,
3191 (bits>0) ? bits : mpf_get_prec(f));
3193 mp_bitcnt_t get_prec() const
3196 return mpf_get_default_prec();
3203 typedef void __gmp_randinit_default_t (gmp_randstate_t);
3204 typedef void __gmp_randinit_lc_2exp_t (gmp_randstate_t, mpz_srcptr, unsigned long int, mp_bitcnt_t);
3205 typedef int __gmp_randinit_lc_2exp_size_t (gmp_randstate_t, mp_bitcnt_t);
3211 gmp_randstate_t state;
3213 // copy construction and assignment not allowed
3214 gmp_randclass(const gmp_randclass &);
3215 void operator=(const gmp_randclass &);
3217 // constructors and destructor
3218 gmp_randclass(gmp_randalg_t alg, unsigned long int size)
3222 case GMP_RAND_ALG_LC: // no other cases for now
3224 gmp_randinit(state, alg, size);
3229 // gmp_randinit_default
3230 gmp_randclass(__gmp_randinit_default_t* f) { f(state); }
3232 // gmp_randinit_lc_2exp
3233 gmp_randclass(__gmp_randinit_lc_2exp_t* f,
3234 mpz_class z, unsigned long int l1, mp_bitcnt_t l2)
3235 { f(state, z.get_mpz_t(), l1, l2); }
3237 // gmp_randinit_lc_2exp_size
3238 gmp_randclass(__gmp_randinit_lc_2exp_size_t* f,
3241 if (f (state, size) == 0)
3242 throw std::length_error ("gmp_randinit_lc_2exp_size");
3245 ~gmp_randclass() { gmp_randclear(state); }
3248 void seed(); // choose a random seed some way (?)
3249 void seed(unsigned long int s) { gmp_randseed_ui(state, s); }
3250 void seed(const mpz_class &z) { gmp_randseed(state, z.get_mpz_t()); }
3252 // get random number
3253 __gmp_expr<mpz_t, __gmp_urandomb_value> get_z_bits(mp_bitcnt_t l)
3254 { return __gmp_expr<mpz_t, __gmp_urandomb_value>(state, l); }
3255 __gmp_expr<mpz_t, __gmp_urandomb_value> get_z_bits(const mpz_class &z)
3256 { return get_z_bits(z.get_ui()); }
3257 // FIXME: z.get_bitcnt_t() ?
3259 __gmp_expr<mpz_t, __gmp_urandomm_value> get_z_range(const mpz_class &z)
3260 { return __gmp_expr<mpz_t, __gmp_urandomm_value>(state, z); }
3262 __gmp_expr<mpf_t, __gmp_urandomb_value> get_f(mp_bitcnt_t prec = 0)
3263 { return __gmp_expr<mpf_t, __gmp_urandomb_value>(state, prec); }
3267 /**************** Specialize std::numeric_limits ****************/
3270 template <> class numeric_limits<mpz_class>
3273 static const bool is_specialized = true;
3274 static mpz_class min() { return mpz_class(); }
3275 static mpz_class max() { return mpz_class(); }
3276 static mpz_class lowest() { return mpz_class(); }
3277 static const int digits = 0;
3278 static const int digits10 = 0;
3279 static const int max_digits10 = 0;
3280 static const bool is_signed = true;
3281 static const bool is_integer = true;
3282 static const bool is_exact = true;
3283 static const int radix = 2;
3284 static mpz_class epsilon() { return mpz_class(); }
3285 static mpz_class round_error() { return mpz_class(); }
3286 static const int min_exponent = 0;
3287 static const int min_exponent10 = 0;
3288 static const int max_exponent = 0;
3289 static const int max_exponent10 = 0;
3290 static const bool has_infinity = false;
3291 static const bool has_quiet_NaN = false;
3292 static const bool has_signaling_NaN = false;
3293 static const float_denorm_style has_denorm = denorm_absent;
3294 static const bool has_denorm_loss = false;
3295 static mpz_class infinity() { return mpz_class(); }
3296 static mpz_class quiet_NaN() { return mpz_class(); }
3297 static mpz_class signaling_NaN() { return mpz_class(); }
3298 static mpz_class denorm_min() { return mpz_class(); }
3299 static const bool is_iec559 = false;
3300 static const bool is_bounded = false;
3301 static const bool is_modulo = false;
3302 static const bool traps = false;
3303 static const bool tinyness_before = false;
3304 static const float_round_style round_style = round_toward_zero;
3307 template <> class numeric_limits<mpq_class>
3310 static const bool is_specialized = true;
3311 static mpq_class min() { return mpq_class(); }
3312 static mpq_class max() { return mpq_class(); }
3313 static mpq_class lowest() { return mpq_class(); }
3314 static const int digits = 0;
3315 static const int digits10 = 0;
3316 static const int max_digits10 = 0;
3317 static const bool is_signed = true;
3318 static const bool is_integer = false;
3319 static const bool is_exact = true;
3320 static const int radix = 2;
3321 static mpq_class epsilon() { return mpq_class(); }
3322 static mpq_class round_error() { return mpq_class(); }
3323 static const int min_exponent = 0;
3324 static const int min_exponent10 = 0;
3325 static const int max_exponent = 0;
3326 static const int max_exponent10 = 0;
3327 static const bool has_infinity = false;
3328 static const bool has_quiet_NaN = false;
3329 static const bool has_signaling_NaN = false;
3330 static const float_denorm_style has_denorm = denorm_absent;
3331 static const bool has_denorm_loss = false;
3332 static mpq_class infinity() { return mpq_class(); }
3333 static mpq_class quiet_NaN() { return mpq_class(); }
3334 static mpq_class signaling_NaN() { return mpq_class(); }
3335 static mpq_class denorm_min() { return mpq_class(); }
3336 static const bool is_iec559 = false;
3337 static const bool is_bounded = false;
3338 static const bool is_modulo = false;
3339 static const bool traps = false;
3340 static const bool tinyness_before = false;
3341 static const float_round_style round_style = round_toward_zero;
3344 template <> class numeric_limits<mpf_class>
3347 static const bool is_specialized = true;
3348 static mpf_class min() { return mpf_class(); }
3349 static mpf_class max() { return mpf_class(); }
3350 static mpf_class lowest() { return mpf_class(); }
3351 static const int digits = 0;
3352 static const int digits10 = 0;
3353 static const int max_digits10 = 0;
3354 static const bool is_signed = true;
3355 static const bool is_integer = false;
3356 static const bool is_exact = false;
3357 static const int radix = 2;
3358 static mpf_class epsilon() { return mpf_class(); }
3359 static mpf_class round_error() { return mpf_class(); }
3360 static const int min_exponent = 0;
3361 static const int min_exponent10 = 0;
3362 static const int max_exponent = 0;
3363 static const int max_exponent10 = 0;
3364 static const bool has_infinity = false;
3365 static const bool has_quiet_NaN = false;
3366 static const bool has_signaling_NaN = false;
3367 static const float_denorm_style has_denorm = denorm_absent;
3368 static const bool has_denorm_loss = false;
3369 static mpf_class infinity() { return mpf_class(); }
3370 static mpf_class quiet_NaN() { return mpf_class(); }
3371 static mpf_class signaling_NaN() { return mpf_class(); }
3372 static mpf_class denorm_min() { return mpf_class(); }
3373 static const bool is_iec559 = false;
3374 static const bool is_bounded = false;
3375 static const bool is_modulo = false;
3376 static const bool traps = false;
3377 static const bool tinyness_before = false;
3378 static const float_round_style round_style = round_indeterminate;
3383 /**************** #undef all private macros ****************/
3385 #undef __GMPP_DECLARE_COMPOUND_OPERATOR
3386 #undef __GMPN_DECLARE_COMPOUND_OPERATOR
3387 #undef __GMP_DECLARE_COMPOUND_OPERATOR
3388 #undef __GMP_DECLARE_COMPOUND_OPERATOR_UI
3389 #undef __GMP_DECLARE_INCREMENT_OPERATOR
3391 #undef __GMPZQ_DEFINE_EXPR
3393 #undef __GMP_DEFINE_UNARY_FUNCTION
3394 #undef __GMP_DEFINE_UNARY_TYPE_FUNCTION
3396 #undef __GMPP_DEFINE_BINARY_FUNCTION
3397 #undef __GMPNN_DEFINE_BINARY_FUNCTION
3398 #undef __GMPNS_DEFINE_BINARY_FUNCTION
3399 #undef __GMPNU_DEFINE_BINARY_FUNCTION
3400 #undef __GMPND_DEFINE_BINARY_FUNCTION
3401 #undef __GMPNLD_DEFINE_BINARY_FUNCTION
3402 #undef __GMPN_DEFINE_BINARY_FUNCTION
3403 #undef __GMP_DEFINE_BINARY_FUNCTION
3405 #undef __GMP_DEFINE_BINARY_FUNCTION_UI
3407 #undef __GMPP_DEFINE_BINARY_TYPE_FUNCTION
3408 #undef __GMPNN_DEFINE_BINARY_TYPE_FUNCTION
3409 #undef __GMPNS_DEFINE_BINARY_TYPE_FUNCTION
3410 #undef __GMPNU_DEFINE_BINARY_TYPE_FUNCTION
3411 #undef __GMPND_DEFINE_BINARY_TYPE_FUNCTION
3412 #undef __GMPNLD_DEFINE_BINARY_TYPE_FUNCTION
3413 #undef __GMPN_DEFINE_BINARY_TYPE_FUNCTION
3414 #undef __GMP_DEFINE_BINARY_TYPE_FUNCTION
3416 #undef __GMPZ_DEFINE_COMPOUND_OPERATOR
3418 #undef __GMPP_DEFINE_COMPOUND_OPERATOR
3419 #undef __GMPNN_DEFINE_COMPOUND_OPERATOR
3420 #undef __GMPNS_DEFINE_COMPOUND_OPERATOR
3421 #undef __GMPNU_DEFINE_COMPOUND_OPERATOR
3422 #undef __GMPND_DEFINE_COMPOUND_OPERATOR
3423 #undef __GMPNLD_DEFINE_COMPOUND_OPERATOR
3424 #undef __GMPN_DEFINE_COMPOUND_OPERATOR
3425 #undef __GMP_DEFINE_COMPOUND_OPERATOR
3427 #undef __GMPQ_DEFINE_COMPOUND_OPERATOR
3428 #undef __GMPF_DEFINE_COMPOUND_OPERATOR
3430 #undef __GMP_DEFINE_COMPOUND_OPERATOR_UI
3431 #undef __GMPZ_DEFINE_COMPOUND_OPERATOR_UI
3432 #undef __GMPQ_DEFINE_COMPOUND_OPERATOR_UI
3433 #undef __GMPF_DEFINE_COMPOUND_OPERATOR_UI
3435 #undef __GMP_DEFINE_INCREMENT_OPERATOR
3436 #undef __GMPZ_DEFINE_INCREMENT_OPERATOR
3437 #undef __GMPQ_DEFINE_INCREMENT_OPERATOR
3438 #undef __GMPF_DEFINE_INCREMENT_OPERATOR
3440 #undef __GMPXX_CONSTANT
3442 #endif /* __GMP_PLUSPLUS__ */