beta-0.89.2
[luatex.git] / source / libs / gmp / gmp-src / gmpxx.h
blob58e87005442b2c8de5bc015ff18862c0da33796d
1 /* gmpxx.h -- C++ class wrapper for GMP types. -*- C++ -*-
3 Copyright 2001-2003, 2006, 2008, 2011, 2012 Free Software Foundation, Inc.
5 This file is part of the GNU MP Library.
7 The GNU MP Library is free software; you can redistribute it and/or modify
8 it under the terms of either:
10 * the GNU Lesser General Public License as published by the Free
11 Software Foundation; either version 3 of the License, or (at your
12 option) any later version.
16 * the GNU General Public License as published by the Free Software
17 Foundation; either version 2 of the License, or (at your option) any
18 later version.
20 or both in parallel, as here.
22 The GNU MP Library is distributed in the hope that it will be useful, but
23 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
24 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
25 for more details.
27 You should have received copies of the GNU General Public License and the
28 GNU Lesser General Public License along with the GNU MP Library. If not,
29 see https://www.gnu.org/licenses/. */
31 #ifndef __GMP_PLUSPLUS__
32 #define __GMP_PLUSPLUS__
34 #include <iosfwd>
36 #include <cstring> /* for strlen */
37 #include <limits> /* numeric_limits */
38 #include <utility>
39 #include <algorithm> /* swap */
40 #include <string>
41 #include <stdexcept>
42 #include <cfloat>
43 #include <gmp.h>
45 // wrapper for gcc's __builtin_constant_p
46 // __builtin_constant_p has been in gcc since forever,
47 // but g++-3.4 miscompiles it.
48 #if __GMP_GNUC_PREREQ(4, 2)
49 #define __GMPXX_CONSTANT(X) __builtin_constant_p(X)
50 #else
51 #define __GMPXX_CONSTANT(X) false
52 #endif
53 #define __GMPXX_CONSTANT_TRUE(X) (__GMPXX_CONSTANT(X) && (X))
55 // Use C++11 features
56 #ifndef __GMPXX_USE_CXX11
57 #if __cplusplus >= 201103L
58 #define __GMPXX_USE_CXX11 1
59 #else
60 #define __GMPXX_USE_CXX11 0
61 #endif
62 #endif
64 #if __GMPXX_USE_CXX11
65 #define __GMPXX_NOEXCEPT noexcept
66 #include <type_traits> // for common_type
67 #else
68 #define __GMPXX_NOEXCEPT
69 #endif
71 // Max allocations for plain types when converted to GMP types
72 #if GMP_NAIL_BITS != 0 && ! defined _LONG_LONG_LIMB
73 #define __GMPZ_ULI_LIMBS 2
74 #else
75 #define __GMPZ_ULI_LIMBS 1
76 #endif
78 #define __GMPXX_BITS_TO_LIMBS(n) (((n) + (GMP_NUMB_BITS - 1)) / GMP_NUMB_BITS)
79 #define __GMPZ_DBL_LIMBS __GMPXX_BITS_TO_LIMBS(DBL_MAX_EXP)+1
80 #define __GMPQ_NUM_DBL_LIMBS __GMPZ_DBL_LIMBS
81 #define __GMPQ_DEN_DBL_LIMBS __GMPXX_BITS_TO_LIMBS(DBL_MANT_DIG+1-DBL_MIN_EXP)+1
82 // The final +1s are a security margin. The current implementation of
83 // mpq_set_d seems to need it for the denominator.
85 inline void __mpz_set_ui_safe(mpz_ptr p, unsigned long l)
87 p->_mp_size = (l != 0);
88 p->_mp_d[0] = l & GMP_NUMB_MASK;
89 #if __GMPZ_ULI_LIMBS > 1
90 l >>= GMP_NUMB_BITS;
91 p->_mp_d[1] = l;
92 p->_mp_size += (l != 0);
93 #endif
96 inline void __mpz_set_si_safe(mpz_ptr p, long l)
98 if(l < 0)
100 __mpz_set_ui_safe(p, -static_cast<unsigned long>(l));
101 mpz_neg(p, p);
103 else
104 __mpz_set_ui_safe(p, l);
105 // Note: we know the high bit of l is 0 so we could do slightly better
108 // Fake temporary variables
109 #define __GMPXX_TMPZ_UI \
110 mpz_t temp; \
111 mp_limb_t limbs[__GMPZ_ULI_LIMBS]; \
112 temp->_mp_d = limbs; \
113 __mpz_set_ui_safe (temp, l)
114 #define __GMPXX_TMPZ_SI \
115 mpz_t temp; \
116 mp_limb_t limbs[__GMPZ_ULI_LIMBS]; \
117 temp->_mp_d = limbs; \
118 __mpz_set_si_safe (temp, l)
119 #define __GMPXX_TMPZ_D \
120 mpz_t temp; \
121 mp_limb_t limbs[__GMPZ_DBL_LIMBS]; \
122 temp->_mp_d = limbs; \
123 temp->_mp_alloc = __GMPZ_DBL_LIMBS; \
124 mpz_set_d (temp, d)
126 #define __GMPXX_TMPQ_UI \
127 mpq_t temp; \
128 mp_limb_t limbs[__GMPZ_ULI_LIMBS+1]; \
129 mpq_numref(temp)->_mp_d = limbs; \
130 __mpz_set_ui_safe (mpq_numref(temp), l); \
131 mpq_denref(temp)->_mp_d = limbs + __GMPZ_ULI_LIMBS; \
132 mpq_denref(temp)->_mp_size = 1; \
133 mpq_denref(temp)->_mp_d[0] = 1
134 #define __GMPXX_TMPQ_SI \
135 mpq_t temp; \
136 mp_limb_t limbs[__GMPZ_ULI_LIMBS+1]; \
137 mpq_numref(temp)->_mp_d = limbs; \
138 __mpz_set_si_safe (mpq_numref(temp), l); \
139 mpq_denref(temp)->_mp_d = limbs + __GMPZ_ULI_LIMBS; \
140 mpq_denref(temp)->_mp_size = 1; \
141 mpq_denref(temp)->_mp_d[0] = 1
142 #define __GMPXX_TMPQ_D \
143 mpq_t temp; \
144 mp_limb_t limbs[__GMPQ_NUM_DBL_LIMBS + __GMPQ_DEN_DBL_LIMBS]; \
145 mpq_numref(temp)->_mp_d = limbs; \
146 mpq_numref(temp)->_mp_alloc = __GMPQ_NUM_DBL_LIMBS; \
147 mpq_denref(temp)->_mp_d = limbs + __GMPQ_NUM_DBL_LIMBS; \
148 mpq_denref(temp)->_mp_alloc = __GMPQ_DEN_DBL_LIMBS; \
149 mpq_set_d (temp, d)
151 inline unsigned long __gmpxx_abs_ui (signed long l)
153 return l >= 0 ? static_cast<unsigned long>(l)
154 : -static_cast<unsigned long>(l);
157 /**************** Function objects ****************/
158 /* Any evaluation of a __gmp_expr ends up calling one of these functions
159 all intermediate functions being inline, the evaluation should optimize
160 to a direct call to the relevant function, thus yielding no overhead
161 over the C interface. */
163 struct __gmp_unary_plus
165 static void eval(mpz_ptr z, mpz_srcptr w) { mpz_set(z, w); }
166 static void eval(mpq_ptr q, mpq_srcptr r) { mpq_set(q, r); }
167 static void eval(mpf_ptr f, mpf_srcptr g) { mpf_set(f, g); }
170 struct __gmp_unary_minus
172 static void eval(mpz_ptr z, mpz_srcptr w) { mpz_neg(z, w); }
173 static void eval(mpq_ptr q, mpq_srcptr r) { mpq_neg(q, r); }
174 static void eval(mpf_ptr f, mpf_srcptr g) { mpf_neg(f, g); }
177 struct __gmp_unary_com
179 static void eval(mpz_ptr z, mpz_srcptr w) { mpz_com(z, w); }
182 struct __gmp_binary_plus
184 static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v)
185 { mpz_add(z, w, v); }
187 static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l)
189 // Ideally, those checks should happen earlier so that the tree
190 // generated for a+0+b would just be sum(a,b).
191 if (__GMPXX_CONSTANT(l) && l == 0)
193 if (z != w) mpz_set(z, w);
195 else
196 mpz_add_ui(z, w, l);
198 static void eval(mpz_ptr z, unsigned long int l, mpz_srcptr w)
199 { eval(z, w, l); }
200 static void eval(mpz_ptr z, mpz_srcptr w, signed long int l)
202 if (l >= 0)
203 eval(z, w, static_cast<unsigned long>(l));
204 else
205 mpz_sub_ui(z, w, -static_cast<unsigned long>(l));
207 static void eval(mpz_ptr z, signed long int l, mpz_srcptr w)
208 { eval(z, w, l); }
209 static void eval(mpz_ptr z, mpz_srcptr w, double d)
210 { __GMPXX_TMPZ_D; mpz_add (z, w, temp); }
211 static void eval(mpz_ptr z, double d, mpz_srcptr w)
212 { eval(z, w, d); }
214 static void eval(mpq_ptr q, mpq_srcptr r, mpq_srcptr s)
215 { mpq_add(q, r, s); }
217 static void eval(mpq_ptr q, mpq_srcptr r, unsigned long int l)
219 if (__GMPXX_CONSTANT(l) && l == 0)
221 if (q != r) mpq_set(q, r);
223 else
225 if (q == r)
226 mpz_addmul_ui(mpq_numref(q), mpq_denref(q), l);
227 else
229 mpz_mul_ui(mpq_numref(q), mpq_denref(r), l);
230 mpz_add(mpq_numref(q), mpq_numref(q), mpq_numref(r));
231 mpz_set(mpq_denref(q), mpq_denref(r));
235 static void eval(mpq_ptr q, unsigned long int l, mpq_srcptr r)
236 { eval(q, r, l); }
237 static inline void eval(mpq_ptr q, mpq_srcptr r, signed long int l);
238 // defined after __gmp_binary_minus
239 static void eval(mpq_ptr q, signed long int l, mpq_srcptr r)
240 { eval(q, r, l); }
241 static void eval(mpq_ptr q, mpq_srcptr r, double d)
242 { __GMPXX_TMPQ_D; mpq_add (q, r, temp); }
243 static void eval(mpq_ptr q, double d, mpq_srcptr r)
244 { eval(q, r, d); }
246 static void eval(mpq_ptr q, mpq_srcptr r, mpz_srcptr z)
248 if (q == r)
249 mpz_addmul(mpq_numref(q), mpq_denref(q), z);
250 else
252 mpz_mul(mpq_numref(q), mpq_denref(r), z);
253 mpz_add(mpq_numref(q), mpq_numref(q), mpq_numref(r));
254 mpz_set(mpq_denref(q), mpq_denref(r));
257 static void eval(mpq_ptr q, mpz_srcptr z, mpq_srcptr r)
258 { eval(q, r, z); }
260 static void eval(mpf_ptr f, mpf_srcptr g, mpf_srcptr h)
261 { mpf_add(f, g, h); }
263 static void eval(mpf_ptr f, mpf_srcptr g, unsigned long int l)
264 { mpf_add_ui(f, g, l); }
265 static void eval(mpf_ptr f, unsigned long int l, mpf_srcptr g)
266 { mpf_add_ui(f, g, l); }
267 static void eval(mpf_ptr f, mpf_srcptr g, signed long int l)
269 if (l >= 0)
270 mpf_add_ui(f, g, l);
271 else
272 mpf_sub_ui(f, g, -static_cast<unsigned long>(l));
274 static void eval(mpf_ptr f, signed long int l, mpf_srcptr g)
275 { eval(f, g, l); }
276 static void eval(mpf_ptr f, mpf_srcptr g, double d)
278 mpf_t temp;
279 mpf_init2(temp, 8*sizeof(double));
280 mpf_set_d(temp, d);
281 mpf_add(f, g, temp);
282 mpf_clear(temp);
284 static void eval(mpf_ptr f, double d, mpf_srcptr g)
285 { eval(f, g, d); }
288 struct __gmp_binary_minus
290 static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v)
291 { mpz_sub(z, w, v); }
293 static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l)
295 if (__GMPXX_CONSTANT(l) && l == 0)
297 if (z != w) mpz_set(z, w);
299 else
300 mpz_sub_ui(z, w, l);
302 static void eval(mpz_ptr z, unsigned long int l, mpz_srcptr w)
304 if (__GMPXX_CONSTANT(l) && l == 0)
306 mpz_neg(z, w);
308 else
309 mpz_ui_sub(z, l, w);
311 static void eval(mpz_ptr z, mpz_srcptr w, signed long int l)
313 if (l >= 0)
314 eval(z, w, static_cast<unsigned long>(l));
315 else
316 mpz_add_ui(z, w, -static_cast<unsigned long>(l));
318 static void eval(mpz_ptr z, signed long int l, mpz_srcptr w)
320 if (l >= 0)
321 eval(z, static_cast<unsigned long>(l), w);
322 else
324 mpz_add_ui(z, w, -static_cast<unsigned long>(l));
325 mpz_neg(z, z);
328 static void eval(mpz_ptr z, mpz_srcptr w, double d)
329 { __GMPXX_TMPZ_D; mpz_sub (z, w, temp); }
330 static void eval(mpz_ptr z, double d, mpz_srcptr w)
331 { __GMPXX_TMPZ_D; mpz_sub (z, temp, w); }
333 static void eval(mpq_ptr q, mpq_srcptr r, mpq_srcptr s)
334 { mpq_sub(q, r, s); }
336 static void eval(mpq_ptr q, mpq_srcptr r, unsigned long int l)
338 if (__GMPXX_CONSTANT(l) && l == 0)
340 if (q != r) mpq_set(q, r);
342 else
344 if (q == r)
345 mpz_submul_ui(mpq_numref(q), mpq_denref(q), l);
346 else
348 mpz_mul_ui(mpq_numref(q), mpq_denref(r), l);
349 mpz_sub(mpq_numref(q), mpq_numref(r), mpq_numref(q));
350 mpz_set(mpq_denref(q), mpq_denref(r));
354 static void eval(mpq_ptr q, unsigned long int l, mpq_srcptr r)
355 { eval(q, r, l); mpq_neg(q, q); }
356 static void eval(mpq_ptr q, mpq_srcptr r, signed long int l)
358 if (l >= 0)
359 eval(q, r, static_cast<unsigned long>(l));
360 else
361 __gmp_binary_plus::eval(q, r, -static_cast<unsigned long>(l));
363 static void eval(mpq_ptr q, signed long int l, mpq_srcptr r)
364 { eval(q, r, l); mpq_neg(q, q); }
365 static void eval(mpq_ptr q, mpq_srcptr r, double d)
366 { __GMPXX_TMPQ_D; mpq_sub (q, r, temp); }
367 static void eval(mpq_ptr q, double d, mpq_srcptr r)
368 { __GMPXX_TMPQ_D; mpq_sub (q, temp, r); }
370 static void eval(mpq_ptr q, mpq_srcptr r, mpz_srcptr z)
372 if (q == r)
373 mpz_submul(mpq_numref(q), mpq_denref(q), z);
374 else
376 mpz_mul(mpq_numref(q), mpq_denref(r), z);
377 mpz_sub(mpq_numref(q), mpq_numref(r), mpq_numref(q));
378 mpz_set(mpq_denref(q), mpq_denref(r));
381 static void eval(mpq_ptr q, mpz_srcptr z, mpq_srcptr r)
382 { eval(q, r, z); mpq_neg(q, q); }
384 static void eval(mpf_ptr f, mpf_srcptr g, mpf_srcptr h)
385 { mpf_sub(f, g, h); }
387 static void eval(mpf_ptr f, mpf_srcptr g, unsigned long int l)
388 { mpf_sub_ui(f, g, l); }
389 static void eval(mpf_ptr f, unsigned long int l, mpf_srcptr g)
390 { mpf_ui_sub(f, l, g); }
391 static void eval(mpf_ptr f, mpf_srcptr g, signed long int l)
393 if (l >= 0)
394 mpf_sub_ui(f, g, l);
395 else
396 mpf_add_ui(f, g, -static_cast<unsigned long>(l));
398 static void eval(mpf_ptr f, signed long int l, mpf_srcptr g)
400 if (l >= 0)
401 mpf_sub_ui(f, g, l);
402 else
403 mpf_add_ui(f, g, -static_cast<unsigned long>(l));
404 mpf_neg(f, f);
406 static void eval(mpf_ptr f, mpf_srcptr g, double d)
408 mpf_t temp;
409 mpf_init2(temp, 8*sizeof(double));
410 mpf_set_d(temp, d);
411 mpf_sub(f, g, temp);
412 mpf_clear(temp);
414 static void eval(mpf_ptr f, double d, mpf_srcptr g)
416 mpf_t temp;
417 mpf_init2(temp, 8*sizeof(double));
418 mpf_set_d(temp, d);
419 mpf_sub(f, temp, g);
420 mpf_clear(temp);
424 // defined here so it can reference __gmp_binary_minus
425 inline void
426 __gmp_binary_plus::eval(mpq_ptr q, mpq_srcptr r, signed long int l)
428 if (l >= 0)
429 eval(q, r, static_cast<unsigned long>(l));
430 else
431 __gmp_binary_minus::eval(q, r, -static_cast<unsigned long>(l));
434 struct __gmp_binary_lshift
436 static void eval(mpz_ptr z, mpz_srcptr w, mp_bitcnt_t l)
438 if (__GMPXX_CONSTANT(l) && (l == 0))
440 if (z != w) mpz_set(z, w);
442 else
443 mpz_mul_2exp(z, w, l);
445 static void eval(mpq_ptr q, mpq_srcptr r, mp_bitcnt_t l)
447 if (__GMPXX_CONSTANT(l) && (l == 0))
449 if (q != r) mpq_set(q, r);
451 else
452 mpq_mul_2exp(q, r, l);
454 static void eval(mpf_ptr f, mpf_srcptr g, mp_bitcnt_t l)
455 { mpf_mul_2exp(f, g, l); }
458 struct __gmp_binary_rshift
460 static void eval(mpz_ptr z, mpz_srcptr w, mp_bitcnt_t l)
462 if (__GMPXX_CONSTANT(l) && (l == 0))
464 if (z != w) mpz_set(z, w);
466 else
467 mpz_fdiv_q_2exp(z, w, l);
469 static void eval(mpq_ptr q, mpq_srcptr r, mp_bitcnt_t l)
471 if (__GMPXX_CONSTANT(l) && (l == 0))
473 if (q != r) mpq_set(q, r);
475 else
476 mpq_div_2exp(q, r, l);
478 static void eval(mpf_ptr f, mpf_srcptr g, mp_bitcnt_t l)
479 { mpf_div_2exp(f, g, l); }
482 struct __gmp_binary_multiplies
484 static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v)
485 { mpz_mul(z, w, v); }
487 static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l)
489 // gcc-3.3 doesn't have __builtin_ctzl. Don't bother optimizing for old gcc.
490 #if __GMP_GNUC_PREREQ(3, 4)
491 if (__GMPXX_CONSTANT(l) && (l & (l-1)) == 0)
493 if (l == 0)
495 z->_mp_size = 0;
497 else
499 __gmp_binary_lshift::eval(z, w, __builtin_ctzl(l));
502 else
503 #endif
504 mpz_mul_ui(z, w, l);
506 static void eval(mpz_ptr z, unsigned long int l, mpz_srcptr w)
507 { eval(z, w, l); }
508 static void eval(mpz_ptr z, mpz_srcptr w, signed long int l)
510 if (__GMPXX_CONSTANT_TRUE(l >= 0))
511 eval(z, w, static_cast<unsigned long>(l));
512 else if (__GMPXX_CONSTANT_TRUE(l <= 0))
514 eval(z, w, -static_cast<unsigned long>(l));
515 mpz_neg(z, z);
517 else
518 mpz_mul_si (z, w, l);
520 static void eval(mpz_ptr z, signed long int l, mpz_srcptr w)
521 { eval(z, w, l); }
522 static void eval(mpz_ptr z, mpz_srcptr w, double d)
523 { __GMPXX_TMPZ_D; mpz_mul (z, w, temp); }
524 static void eval(mpz_ptr z, double d, mpz_srcptr w)
525 { eval(z, w, d); }
527 static void eval(mpq_ptr q, mpq_srcptr r, mpq_srcptr s)
528 { mpq_mul(q, r, s); }
530 static void eval(mpq_ptr q, mpq_srcptr r, unsigned long int l)
532 #if __GMP_GNUC_PREREQ(3, 4)
533 if (__GMPXX_CONSTANT(l) && (l & (l-1)) == 0)
535 if (l == 0)
537 mpq_set_ui(q, 0, 1);
539 else
541 __gmp_binary_lshift::eval(q, r, __builtin_ctzl(l));
544 else
545 #endif
547 __GMPXX_TMPQ_UI;
548 mpq_mul (q, r, temp);
551 static void eval(mpq_ptr q, unsigned long int l, mpq_srcptr r)
552 { eval(q, r, l); }
553 static void eval(mpq_ptr q, mpq_srcptr r, signed long int l)
555 if (__GMPXX_CONSTANT_TRUE(l >= 0))
556 eval(q, r, static_cast<unsigned long>(l));
557 else if (__GMPXX_CONSTANT_TRUE(l <= 0))
559 eval(q, r, -static_cast<unsigned long>(l));
560 mpq_neg(q, q);
562 else
564 __GMPXX_TMPQ_SI;
565 mpq_mul (q, r, temp);
568 static void eval(mpq_ptr q, signed long int l, mpq_srcptr r)
569 { eval(q, r, l); }
570 static void eval(mpq_ptr q, mpq_srcptr r, double d)
571 { __GMPXX_TMPQ_D; mpq_mul (q, r, temp); }
572 static void eval(mpq_ptr q, double d, mpq_srcptr r)
573 { eval(q, r, d); }
575 static void eval(mpf_ptr f, mpf_srcptr g, mpf_srcptr h)
576 { mpf_mul(f, g, h); }
578 static void eval(mpf_ptr f, mpf_srcptr g, unsigned long int l)
579 { mpf_mul_ui(f, g, l); }
580 static void eval(mpf_ptr f, unsigned long int l, mpf_srcptr g)
581 { mpf_mul_ui(f, g, l); }
582 static void eval(mpf_ptr f, mpf_srcptr g, signed long int l)
584 if (l >= 0)
585 mpf_mul_ui(f, g, l);
586 else
588 mpf_mul_ui(f, g, -static_cast<unsigned long>(l));
589 mpf_neg(f, f);
592 static void eval(mpf_ptr f, signed long int l, mpf_srcptr g)
593 { eval(f, g, l); }
594 static void eval(mpf_ptr f, mpf_srcptr g, double d)
596 mpf_t temp;
597 mpf_init2(temp, 8*sizeof(double));
598 mpf_set_d(temp, d);
599 mpf_mul(f, g, temp);
600 mpf_clear(temp);
602 static void eval(mpf_ptr f, double d, mpf_srcptr g)
603 { eval(f, g, d); }
606 struct __gmp_binary_divides
608 static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v)
609 { mpz_tdiv_q(z, w, v); }
611 static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l)
613 #if __GMP_GNUC_PREREQ(3, 4)
614 // Don't optimize division by 0...
615 if (__GMPXX_CONSTANT(l) && (l & (l-1)) == 0 && l != 0)
617 if (l == 1)
619 if (z != w) mpz_set(z, w);
621 else
622 mpz_tdiv_q_2exp(z, w, __builtin_ctzl(l));
623 // warning: do not use rshift (fdiv)
625 else
626 #endif
627 mpz_tdiv_q_ui(z, w, l);
629 static void eval(mpz_ptr z, unsigned long int l, mpz_srcptr w)
631 if (mpz_sgn(w) >= 0)
633 if (mpz_fits_ulong_p(w))
634 mpz_set_ui(z, l / mpz_get_ui(w));
635 else
636 mpz_set_ui(z, 0);
638 else
640 mpz_neg(z, w);
641 if (mpz_fits_ulong_p(z))
643 mpz_set_ui(z, l / mpz_get_ui(z));
644 mpz_neg(z, z);
646 else
647 mpz_set_ui(z, 0);
650 static void eval(mpz_ptr z, mpz_srcptr w, signed long int l)
652 if (l >= 0)
653 eval(z, w, static_cast<unsigned long>(l));
654 else
656 eval(z, w, -static_cast<unsigned long>(l));
657 mpz_neg(z, z);
660 static void eval(mpz_ptr z, signed long int l, mpz_srcptr w)
662 if (mpz_fits_slong_p(w))
663 mpz_set_si(z, l / mpz_get_si(w));
664 else
666 /* if w is bigger than a long then the quotient must be zero, unless
667 l==LONG_MIN and w==-LONG_MIN in which case the quotient is -1 */
668 mpz_set_si (z, (mpz_cmpabs_ui (w, __gmpxx_abs_ui(l)) == 0 ? -1 : 0));
671 static void eval(mpz_ptr z, mpz_srcptr w, double d)
672 { __GMPXX_TMPZ_D; mpz_tdiv_q (z, w, temp); }
673 static void eval(mpz_ptr z, double d, mpz_srcptr w)
674 { __GMPXX_TMPZ_D; mpz_tdiv_q (z, temp, w); }
676 static void eval(mpq_ptr q, mpq_srcptr r, mpq_srcptr s)
677 { mpq_div(q, r, s); }
679 static void eval(mpq_ptr q, mpq_srcptr r, unsigned long int l)
681 #if __GMP_GNUC_PREREQ(3, 4)
682 if (__GMPXX_CONSTANT(l) && (l & (l-1)) == 0 && l != 0)
683 __gmp_binary_rshift::eval(q, r, __builtin_ctzl(l));
684 else
685 #endif
687 __GMPXX_TMPQ_UI;
688 mpq_div (q, r, temp);
691 static void eval(mpq_ptr q, unsigned long int l, mpq_srcptr r)
692 { __GMPXX_TMPQ_UI; mpq_div (q, temp, r); }
693 static void eval(mpq_ptr q, mpq_srcptr r, signed long int l)
695 if (__GMPXX_CONSTANT_TRUE(l >= 0))
696 eval(q, r, static_cast<unsigned long>(l));
697 else if (__GMPXX_CONSTANT_TRUE(l <= 0))
699 eval(q, r, -static_cast<unsigned long>(l));
700 mpq_neg(q, q);
702 else
704 __GMPXX_TMPQ_SI;
705 mpq_div (q, r, temp);
708 static void eval(mpq_ptr q, signed long int l, mpq_srcptr r)
709 { __GMPXX_TMPQ_SI; mpq_div (q, temp, r); }
710 static void eval(mpq_ptr q, mpq_srcptr r, double d)
711 { __GMPXX_TMPQ_D; mpq_div (q, r, temp); }
712 static void eval(mpq_ptr q, double d, mpq_srcptr r)
713 { __GMPXX_TMPQ_D; mpq_div (q, temp, r); }
715 static void eval(mpf_ptr f, mpf_srcptr g, mpf_srcptr h)
716 { mpf_div(f, g, h); }
718 static void eval(mpf_ptr f, mpf_srcptr g, unsigned long int l)
719 { mpf_div_ui(f, g, l); }
720 static void eval(mpf_ptr f, unsigned long int l, mpf_srcptr g)
721 { mpf_ui_div(f, l, g); }
722 static void eval(mpf_ptr f, mpf_srcptr g, signed long int l)
724 if (l >= 0)
725 mpf_div_ui(f, g, l);
726 else
728 mpf_div_ui(f, g, -static_cast<unsigned long>(l));
729 mpf_neg(f, f);
732 static void eval(mpf_ptr f, signed long int l, mpf_srcptr g)
734 if (l >= 0)
735 mpf_ui_div(f, l, g);
736 else
738 mpf_ui_div(f, -static_cast<unsigned long>(l), g);
739 mpf_neg(f, f);
742 static void eval(mpf_ptr f, mpf_srcptr g, double d)
744 mpf_t temp;
745 mpf_init2(temp, 8*sizeof(double));
746 mpf_set_d(temp, d);
747 mpf_div(f, g, temp);
748 mpf_clear(temp);
750 static void eval(mpf_ptr f, double d, mpf_srcptr g)
752 mpf_t temp;
753 mpf_init2(temp, 8*sizeof(double));
754 mpf_set_d(temp, d);
755 mpf_div(f, temp, g);
756 mpf_clear(temp);
760 struct __gmp_binary_modulus
762 static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v)
763 { mpz_tdiv_r(z, w, v); }
765 static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l)
766 { mpz_tdiv_r_ui(z, w, l); }
767 static void eval(mpz_ptr z, unsigned long int l, mpz_srcptr w)
769 if (mpz_sgn(w) >= 0)
771 if (mpz_fits_ulong_p(w))
772 mpz_set_ui(z, l % mpz_get_ui(w));
773 else
774 mpz_set_ui(z, l);
776 else
778 mpz_neg(z, w);
779 if (mpz_fits_ulong_p(z))
780 mpz_set_ui(z, l % mpz_get_ui(z));
781 else
782 mpz_set_ui(z, l);
785 static void eval(mpz_ptr z, mpz_srcptr w, signed long int l)
787 mpz_tdiv_r_ui (z, w, __gmpxx_abs_ui(l));
789 static void eval(mpz_ptr z, signed long int l, mpz_srcptr w)
791 if (mpz_fits_slong_p(w))
792 mpz_set_si(z, l % mpz_get_si(w));
793 else
795 /* if w is bigger than a long then the remainder is l unchanged,
796 unless l==LONG_MIN and w==-LONG_MIN in which case it's 0 */
797 mpz_set_si (z, mpz_cmpabs_ui (w, __gmpxx_abs_ui(l)) == 0 ? 0 : l);
800 static void eval(mpz_ptr z, mpz_srcptr w, double d)
801 { __GMPXX_TMPZ_D; mpz_tdiv_r (z, w, temp); }
802 static void eval(mpz_ptr z, double d, mpz_srcptr w)
803 { __GMPXX_TMPZ_D; mpz_tdiv_r (z, temp, w); }
806 struct __gmp_binary_and
808 static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v)
809 { mpz_and(z, w, v); }
811 static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l)
812 { __GMPXX_TMPZ_UI; mpz_and (z, w, temp); }
813 static void eval(mpz_ptr z, unsigned long int l, mpz_srcptr w)
814 { eval(z, w, l); }
815 static void eval(mpz_ptr z, mpz_srcptr w, signed long int l)
816 { __GMPXX_TMPZ_SI; mpz_and (z, w, temp); }
817 static void eval(mpz_ptr z, signed long int l, mpz_srcptr w)
818 { eval(z, w, l); }
819 static void eval(mpz_ptr z, mpz_srcptr w, double d)
820 { __GMPXX_TMPZ_D; mpz_and (z, w, temp); }
821 static void eval(mpz_ptr z, double d, mpz_srcptr w)
822 { eval(z, w, d); }
825 struct __gmp_binary_ior
827 static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v)
828 { mpz_ior(z, w, v); }
829 static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l)
830 { __GMPXX_TMPZ_UI; mpz_ior (z, w, temp); }
831 static void eval(mpz_ptr z, unsigned long int l, mpz_srcptr w)
832 { eval(z, w, l); }
833 static void eval(mpz_ptr z, mpz_srcptr w, signed long int l)
834 { __GMPXX_TMPZ_SI; mpz_ior (z, w, temp); }
835 static void eval(mpz_ptr z, signed long int l, mpz_srcptr w)
836 { eval(z, w, l); }
837 static void eval(mpz_ptr z, mpz_srcptr w, double d)
838 { __GMPXX_TMPZ_D; mpz_ior (z, w, temp); }
839 static void eval(mpz_ptr z, double d, mpz_srcptr w)
840 { eval(z, w, d); }
843 struct __gmp_binary_xor
845 static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v)
846 { mpz_xor(z, w, v); }
847 static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l)
848 { __GMPXX_TMPZ_UI; mpz_xor (z, w, temp); }
849 static void eval(mpz_ptr z, unsigned long int l, mpz_srcptr w)
850 { eval(z, w, l); }
851 static void eval(mpz_ptr z, mpz_srcptr w, signed long int l)
852 { __GMPXX_TMPZ_SI; mpz_xor (z, w, temp); }
853 static void eval(mpz_ptr z, signed long int l, mpz_srcptr w)
854 { eval(z, w, l); }
855 static void eval(mpz_ptr z, mpz_srcptr w, double d)
856 { __GMPXX_TMPZ_D; mpz_xor (z, w, temp); }
857 static void eval(mpz_ptr z, double d, mpz_srcptr w)
858 { eval(z, w, d); }
861 struct __gmp_cmp_function
863 static int eval(mpz_srcptr z, mpz_srcptr w) { return mpz_cmp(z, w); }
865 static int eval(mpz_srcptr z, unsigned long int l)
866 { return mpz_cmp_ui(z, l); }
867 static int eval(unsigned long int l, mpz_srcptr z)
868 { return -mpz_cmp_ui(z, l); }
869 static int eval(mpz_srcptr z, signed long int l)
870 { return mpz_cmp_si(z, l); }
871 static int eval(signed long int l, mpz_srcptr z)
872 { return -mpz_cmp_si(z, l); }
873 static int eval(mpz_srcptr z, double d)
874 { return mpz_cmp_d(z, d); }
875 static int eval(double d, mpz_srcptr z)
876 { return -mpz_cmp_d(z, d); }
878 static int eval(mpq_srcptr q, mpq_srcptr r) { return mpq_cmp(q, r); }
880 static int eval(mpq_srcptr q, unsigned long int l)
881 { return mpq_cmp_ui(q, l, 1); }
882 static int eval(unsigned long int l, mpq_srcptr q)
883 { return -mpq_cmp_ui(q, l, 1); }
884 static int eval(mpq_srcptr q, signed long int l)
885 { return mpq_cmp_si(q, l, 1); }
886 static int eval(signed long int l, mpq_srcptr q)
887 { return -mpq_cmp_si(q, l, 1); }
888 static int eval(mpq_srcptr q, double d)
889 { __GMPXX_TMPQ_D; return mpq_cmp (q, temp); }
890 static int eval(double d, mpq_srcptr q)
891 { __GMPXX_TMPQ_D; return mpq_cmp (temp, q); }
892 static int eval(mpq_srcptr q, mpz_srcptr z)
893 { return mpq_cmp_z(q, z); }
894 static int eval(mpz_srcptr z, mpq_srcptr q)
895 { return -mpq_cmp_z(q, z); }
897 static int eval(mpf_srcptr f, mpf_srcptr g) { return mpf_cmp(f, g); }
899 static int eval(mpf_srcptr f, unsigned long int l)
900 { return mpf_cmp_ui(f, l); }
901 static int eval(unsigned long int l, mpf_srcptr f)
902 { return -mpf_cmp_ui(f, l); }
903 static int eval(mpf_srcptr f, signed long int l)
904 { return mpf_cmp_si(f, l); }
905 static int eval(signed long int l, mpf_srcptr f)
906 { return -mpf_cmp_si(f, l); }
907 static int eval(mpf_srcptr f, double d)
908 { return mpf_cmp_d(f, d); }
909 static int eval(double d, mpf_srcptr f)
910 { return -mpf_cmp_d(f, d); }
911 static int eval(mpf_srcptr f, mpz_srcptr z)
912 { return mpf_cmp_z(f, z); }
913 static int eval(mpz_srcptr z, mpf_srcptr f)
914 { return -mpf_cmp_z(f, z); }
915 static int eval(mpf_srcptr f, mpq_srcptr q)
917 mpf_t qf;
918 mpf_init(qf); /* Should we use the precision of f? */
919 mpf_set_q(qf, q);
920 int ret = eval(f, qf);
921 mpf_clear(qf);
922 return ret;
924 static int eval(mpq_srcptr q, mpf_srcptr f)
925 { return -eval(f, q); }
928 struct __gmp_binary_equal
930 static bool eval(mpz_srcptr z, mpz_srcptr w) { return mpz_cmp(z, w) == 0; }
932 static bool eval(mpz_srcptr z, unsigned long int l)
933 { return mpz_cmp_ui(z, l) == 0; }
934 static bool eval(unsigned long int l, mpz_srcptr z)
935 { return eval(z, l); }
936 static bool eval(mpz_srcptr z, signed long int l)
937 { return mpz_cmp_si(z, l) == 0; }
938 static bool eval(signed long int l, mpz_srcptr z)
939 { return eval(z, l); }
940 static bool eval(mpz_srcptr z, double d)
941 { return mpz_cmp_d(z, d) == 0; }
942 static bool eval(double d, mpz_srcptr z)
943 { return eval(z, d); }
945 static bool eval(mpq_srcptr q, mpq_srcptr r)
946 { return mpq_equal(q, r) != 0; }
948 static bool eval(mpq_srcptr q, unsigned long int l)
949 { return mpq_cmp_ui(q, l, 1) == 0; }
950 static bool eval(unsigned long int l, mpq_srcptr q)
951 { return eval(q, l); }
952 static bool eval(mpq_srcptr q, signed long int l)
953 { return mpq_cmp_si(q, l, 1) == 0; }
954 static bool eval(signed long int l, mpq_srcptr q)
955 { return eval(q, l); }
956 static bool eval(mpq_srcptr q, double d)
957 { __GMPXX_TMPQ_D; return mpq_equal (q, temp) != 0; }
958 static bool eval(double d, mpq_srcptr q)
959 { return eval(q, d); }
960 static bool eval(mpq_srcptr q, mpz_srcptr z)
961 { return mpq_cmp_z(q, z) == 0; }
962 static bool eval(mpz_srcptr z, mpq_srcptr q)
963 { return eval(q, z); }
965 static bool eval(mpf_srcptr f, mpf_srcptr g) { return mpf_cmp(f, g) == 0; }
967 static bool eval(mpf_srcptr f, unsigned long int l)
968 { return mpf_cmp_ui(f, l) == 0; }
969 static bool eval(unsigned long int l, mpf_srcptr f)
970 { return eval(f, l); }
971 static bool eval(mpf_srcptr f, signed long int l)
972 { return mpf_cmp_si(f, l) == 0; }
973 static bool eval(signed long int l, mpf_srcptr f)
974 { return eval(f, l); }
975 static bool eval(mpf_srcptr f, double d)
976 { return mpf_cmp_d(f, d) == 0; }
977 static bool eval(double d, mpf_srcptr f)
978 { return eval(f, d); }
979 static bool eval(mpf_srcptr f, mpz_srcptr z)
980 { return mpf_cmp_z(f, z) == 0; }
981 static bool eval(mpz_srcptr z, mpf_srcptr f)
982 { return eval(f, z); }
983 static bool eval(mpf_srcptr f, mpq_srcptr q)
984 { return __gmp_cmp_function::eval(f, q) == 0; }
985 static bool eval(mpq_srcptr q, mpf_srcptr f)
986 { return eval(f, q); }
989 struct __gmp_binary_less
991 static bool eval(mpz_srcptr z, mpz_srcptr w) { return mpz_cmp(z, w) < 0; }
993 static bool eval(mpz_srcptr z, unsigned long int l)
994 { return mpz_cmp_ui(z, l) < 0; }
995 static bool eval(unsigned long int l, mpz_srcptr z)
996 { return mpz_cmp_ui(z, l) > 0; }
997 static bool eval(mpz_srcptr z, signed long int l)
998 { return mpz_cmp_si(z, l) < 0; }
999 static bool eval(signed long int l, mpz_srcptr z)
1000 { return mpz_cmp_si(z, l) > 0; }
1001 static bool eval(mpz_srcptr z, double d)
1002 { return mpz_cmp_d(z, d) < 0; }
1003 static bool eval(double d, mpz_srcptr z)
1004 { return mpz_cmp_d(z, d) > 0; }
1006 static bool eval(mpq_srcptr q, mpq_srcptr r) { return mpq_cmp(q, r) < 0; }
1008 static bool eval(mpq_srcptr q, unsigned long int l)
1009 { return mpq_cmp_ui(q, l, 1) < 0; }
1010 static bool eval(unsigned long int l, mpq_srcptr q)
1011 { return mpq_cmp_ui(q, l, 1) > 0; }
1012 static bool eval(mpq_srcptr q, signed long int l)
1013 { return mpq_cmp_si(q, l, 1) < 0; }
1014 static bool eval(signed long int l, mpq_srcptr q)
1015 { return mpq_cmp_si(q, l, 1) > 0; }
1016 static bool eval(mpq_srcptr q, double d)
1017 { __GMPXX_TMPQ_D; return mpq_cmp (q, temp) < 0; }
1018 static bool eval(double d, mpq_srcptr q)
1019 { __GMPXX_TMPQ_D; return mpq_cmp (temp, q) < 0; }
1020 static bool eval(mpq_srcptr q, mpz_srcptr z)
1021 { return mpq_cmp_z(q, z) < 0; }
1022 static bool eval(mpz_srcptr z, mpq_srcptr q)
1023 { return mpq_cmp_z(q, z) > 0; }
1025 static bool eval(mpf_srcptr f, mpf_srcptr g) { return mpf_cmp(f, g) < 0; }
1027 static bool eval(mpf_srcptr f, unsigned long int l)
1028 { return mpf_cmp_ui(f, l) < 0; }
1029 static bool eval(unsigned long int l, mpf_srcptr f)
1030 { return mpf_cmp_ui(f, l) > 0; }
1031 static bool eval(mpf_srcptr f, signed long int l)
1032 { return mpf_cmp_si(f, l) < 0; }
1033 static bool eval(signed long int l, mpf_srcptr f)
1034 { return mpf_cmp_si(f, l) > 0; }
1035 static bool eval(mpf_srcptr f, double d)
1036 { return mpf_cmp_d(f, d) < 0; }
1037 static bool eval(double d, mpf_srcptr f)
1038 { return mpf_cmp_d(f, d) > 0; }
1039 static bool eval(mpf_srcptr f, mpz_srcptr z)
1040 { return mpf_cmp_z(f, z) < 0; }
1041 static bool eval(mpz_srcptr z, mpf_srcptr f)
1042 { return mpf_cmp_z(f, z) > 0; }
1043 static bool eval(mpf_srcptr f, mpq_srcptr q)
1044 { return __gmp_cmp_function::eval(f, q) < 0; }
1045 static bool eval(mpq_srcptr q, mpf_srcptr f)
1046 { return __gmp_cmp_function::eval(q, f) < 0; }
1049 struct __gmp_binary_greater
1051 template <class T, class U>
1052 static inline bool eval(T t, U u) { return __gmp_binary_less::eval(u, t); }
1055 struct __gmp_unary_increment
1057 static void eval(mpz_ptr z) { mpz_add_ui(z, z, 1); }
1058 static void eval(mpq_ptr q)
1059 { mpz_add(mpq_numref(q), mpq_numref(q), mpq_denref(q)); }
1060 static void eval(mpf_ptr f) { mpf_add_ui(f, f, 1); }
1063 struct __gmp_unary_decrement
1065 static void eval(mpz_ptr z) { mpz_sub_ui(z, z, 1); }
1066 static void eval(mpq_ptr q)
1067 { mpz_sub(mpq_numref(q), mpq_numref(q), mpq_denref(q)); }
1068 static void eval(mpf_ptr f) { mpf_sub_ui(f, f, 1); }
1071 struct __gmp_abs_function
1073 static void eval(mpz_ptr z, mpz_srcptr w) { mpz_abs(z, w); }
1074 static void eval(mpq_ptr q, mpq_srcptr r) { mpq_abs(q, r); }
1075 static void eval(mpf_ptr f, mpf_srcptr g) { mpf_abs(f, g); }
1078 struct __gmp_trunc_function
1080 static void eval(mpf_ptr f, mpf_srcptr g) { mpf_trunc(f, g); }
1083 struct __gmp_floor_function
1085 static void eval(mpf_ptr f, mpf_srcptr g) { mpf_floor(f, g); }
1088 struct __gmp_ceil_function
1090 static void eval(mpf_ptr f, mpf_srcptr g) { mpf_ceil(f, g); }
1093 struct __gmp_sqrt_function
1095 static void eval(mpz_ptr z, mpz_srcptr w) { mpz_sqrt(z, w); }
1096 static void eval(mpf_ptr f, mpf_srcptr g) { mpf_sqrt(f, g); }
1099 struct __gmp_hypot_function
1101 static void eval(mpf_ptr f, mpf_srcptr g, mpf_srcptr h)
1103 mpf_t temp;
1104 mpf_init2(temp, mpf_get_prec(f));
1105 mpf_mul(temp, g, g);
1106 mpf_mul(f, h, h);
1107 mpf_add(f, f, temp);
1108 mpf_sqrt(f, f);
1109 mpf_clear(temp);
1112 static void eval(mpf_ptr f, mpf_srcptr g, unsigned long int l)
1114 mpf_t temp;
1115 mpf_init2(temp, mpf_get_prec(f));
1116 mpf_mul(temp, g, g);
1117 mpf_set_ui(f, l);
1118 mpf_mul_ui(f, f, l);
1119 mpf_add(f, f, temp);
1120 mpf_clear(temp);
1121 mpf_sqrt(f, f);
1123 static void eval(mpf_ptr f, unsigned long int l, mpf_srcptr g)
1124 { eval(f, g, l); }
1125 static void eval(mpf_ptr f, mpf_srcptr g, signed long int l)
1126 { eval(f, g, __gmpxx_abs_ui(l)); }
1127 static void eval(mpf_ptr f, signed long int l, mpf_srcptr g)
1128 { eval(f, g, l); }
1129 static void eval(mpf_ptr f, mpf_srcptr g, double d)
1131 mpf_t temp;
1132 mpf_init2(temp, mpf_get_prec(f));
1133 mpf_mul(temp, g, g);
1134 mpf_set_d(f, d);
1135 mpf_mul(f, f, f);
1136 mpf_add(f, f, temp);
1137 mpf_sqrt(f, f);
1138 mpf_clear(temp);
1140 static void eval(mpf_ptr f, double d, mpf_srcptr g)
1141 { eval(f, g, d); }
1144 struct __gmp_sgn_function
1146 static int eval(mpz_srcptr z) { return mpz_sgn(z); }
1147 static int eval(mpq_srcptr q) { return mpq_sgn(q); }
1148 static int eval(mpf_srcptr f) { return mpf_sgn(f); }
1151 struct __gmp_gcd_function
1153 static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v)
1154 { mpz_gcd(z, w, v); }
1155 static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l)
1156 { mpz_gcd_ui(z, w, l); }
1157 static void eval(mpz_ptr z, unsigned long int l, mpz_srcptr w)
1158 { eval(z, w, l); }
1159 static void eval(mpz_ptr z, mpz_srcptr w, signed long int l)
1160 { eval(z, w, __gmpxx_abs_ui(l)); }
1161 static void eval(mpz_ptr z, signed long int l, mpz_srcptr w)
1162 { eval(z, w, l); }
1163 static void eval(mpz_ptr z, mpz_srcptr w, double d)
1164 { __GMPXX_TMPZ_D; mpz_gcd (z, w, temp); }
1165 static void eval(mpz_ptr z, double d, mpz_srcptr w)
1166 { eval(z, w, d); }
1169 struct __gmp_lcm_function
1171 static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v)
1172 { mpz_lcm(z, w, v); }
1173 static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l)
1174 { mpz_lcm_ui(z, w, l); }
1175 static void eval(mpz_ptr z, unsigned long int l, mpz_srcptr w)
1176 { eval(z, w, l); }
1177 static void eval(mpz_ptr z, mpz_srcptr w, signed long int l)
1178 { eval(z, w, __gmpxx_abs_ui(l)); }
1179 static void eval(mpz_ptr z, signed long int l, mpz_srcptr w)
1180 { eval(z, w, l); }
1181 static void eval(mpz_ptr z, mpz_srcptr w, double d)
1182 { __GMPXX_TMPZ_D; mpz_lcm (z, w, temp); }
1183 static void eval(mpz_ptr z, double d, mpz_srcptr w)
1184 { eval(z, w, d); }
1187 struct __gmp_rand_function
1189 static void eval(mpz_ptr z, gmp_randstate_t s, mp_bitcnt_t l)
1190 { mpz_urandomb(z, s, l); }
1191 static void eval(mpz_ptr z, gmp_randstate_t s, mpz_srcptr w)
1192 { mpz_urandomm(z, s, w); }
1193 static void eval(mpf_ptr f, gmp_randstate_t s, mp_bitcnt_t prec)
1194 { mpf_urandomb(f, s, prec); }
1198 /**************** Auxiliary classes ****************/
1200 /* this is much the same as gmp_allocated_string in gmp-impl.h
1201 since gmp-impl.h is not publicly available, I redefine it here
1202 I use a different name to avoid possible clashes */
1204 extern "C" {
1205 typedef void (*__gmp_freefunc_t) (void *, size_t);
1207 struct __gmp_alloc_cstring
1209 char *str;
1210 __gmp_alloc_cstring(char *s) { str = s; }
1211 ~__gmp_alloc_cstring()
1213 __gmp_freefunc_t freefunc;
1214 mp_get_memory_functions (NULL, NULL, &freefunc);
1215 (*freefunc) (str, std::strlen(str)+1);
1220 // general expression template class
1221 template <class T, class U>
1222 class __gmp_expr;
1225 // templates for resolving expression types
1226 template <class T>
1227 struct __gmp_resolve_ref
1229 typedef T ref_type;
1232 template <class T, class U>
1233 struct __gmp_resolve_ref<__gmp_expr<T, U> >
1235 typedef const __gmp_expr<T, U> & ref_type;
1239 template <class T, class U = T>
1240 struct __gmp_resolve_expr;
1242 template <>
1243 struct __gmp_resolve_expr<mpz_t>
1245 typedef mpz_t value_type;
1246 typedef mpz_ptr ptr_type;
1247 typedef mpz_srcptr srcptr_type;
1250 template <>
1251 struct __gmp_resolve_expr<mpq_t>
1253 typedef mpq_t value_type;
1254 typedef mpq_ptr ptr_type;
1255 typedef mpq_srcptr srcptr_type;
1258 template <>
1259 struct __gmp_resolve_expr<mpf_t>
1261 typedef mpf_t value_type;
1262 typedef mpf_ptr ptr_type;
1263 typedef mpf_srcptr srcptr_type;
1266 template <>
1267 struct __gmp_resolve_expr<mpz_t, mpq_t>
1269 typedef mpq_t value_type;
1272 template <>
1273 struct __gmp_resolve_expr<mpq_t, mpz_t>
1275 typedef mpq_t value_type;
1278 template <>
1279 struct __gmp_resolve_expr<mpz_t, mpf_t>
1281 typedef mpf_t value_type;
1284 template <>
1285 struct __gmp_resolve_expr<mpf_t, mpz_t>
1287 typedef mpf_t value_type;
1290 template <>
1291 struct __gmp_resolve_expr<mpq_t, mpf_t>
1293 typedef mpf_t value_type;
1296 template <>
1297 struct __gmp_resolve_expr<mpf_t, mpq_t>
1299 typedef mpf_t value_type;
1302 #if __GMPXX_USE_CXX11
1303 namespace std {
1304 template <class T, class U, class V, class W>
1305 struct common_type <__gmp_expr<T, U>, __gmp_expr<V, W> >
1307 private:
1308 typedef typename __gmp_resolve_expr<T, V>::value_type X;
1309 public:
1310 typedef __gmp_expr<X, X> type;
1313 template <class T, class U>
1314 struct common_type <__gmp_expr<T, U> >
1316 typedef __gmp_expr<T, T> type;
1319 #define __GMPXX_DECLARE_COMMON_TYPE(typ) \
1320 template <class T, class U> \
1321 struct common_type <__gmp_expr<T, U>, typ > \
1323 typedef __gmp_expr<T, T> type; \
1324 }; \
1326 template <class T, class U> \
1327 struct common_type <typ, __gmp_expr<T, U> > \
1329 typedef __gmp_expr<T, T> type; \
1332 __GMPXX_DECLARE_COMMON_TYPE(signed char);
1333 __GMPXX_DECLARE_COMMON_TYPE(unsigned char);
1334 __GMPXX_DECLARE_COMMON_TYPE(signed int);
1335 __GMPXX_DECLARE_COMMON_TYPE(unsigned int);
1336 __GMPXX_DECLARE_COMMON_TYPE(signed short int);
1337 __GMPXX_DECLARE_COMMON_TYPE(unsigned short int);
1338 __GMPXX_DECLARE_COMMON_TYPE(signed long int);
1339 __GMPXX_DECLARE_COMMON_TYPE(unsigned long int);
1340 __GMPXX_DECLARE_COMMON_TYPE(float);
1341 __GMPXX_DECLARE_COMMON_TYPE(double);
1342 #undef __GMPXX_DECLARE_COMMON_TYPE
1344 #endif
1346 // classes for evaluating unary and binary expressions
1347 template <class T, class Op>
1348 struct __gmp_unary_expr
1350 typename __gmp_resolve_ref<T>::ref_type val;
1352 __gmp_unary_expr(const T &v) : val(v) { }
1353 private:
1354 __gmp_unary_expr();
1357 template <class T, class U, class Op>
1358 struct __gmp_binary_expr
1360 typename __gmp_resolve_ref<T>::ref_type val1;
1361 typename __gmp_resolve_ref<U>::ref_type val2;
1363 __gmp_binary_expr(const T &v1, const U &v2) : val1(v1), val2(v2) { }
1364 private:
1365 __gmp_binary_expr();
1370 /**************** Macros for in-class declarations ****************/
1371 /* This is just repetitive code that is easier to maintain if it's written
1372 only once */
1374 #define __GMPP_DECLARE_COMPOUND_OPERATOR(fun) \
1375 template <class T, class U> \
1376 __gmp_expr<value_type, value_type> & fun(const __gmp_expr<T, U> &);
1378 #define __GMPN_DECLARE_COMPOUND_OPERATOR(fun) \
1379 __gmp_expr & fun(signed char); \
1380 __gmp_expr & fun(unsigned char); \
1381 __gmp_expr & fun(signed int); \
1382 __gmp_expr & fun(unsigned int); \
1383 __gmp_expr & fun(signed short int); \
1384 __gmp_expr & fun(unsigned short int); \
1385 __gmp_expr & fun(signed long int); \
1386 __gmp_expr & fun(unsigned long int); \
1387 __gmp_expr & fun(float); \
1388 __gmp_expr & fun(double); \
1389 /* __gmp_expr & fun(long double); */
1391 #define __GMP_DECLARE_COMPOUND_OPERATOR(fun) \
1392 __GMPP_DECLARE_COMPOUND_OPERATOR(fun) \
1393 __GMPN_DECLARE_COMPOUND_OPERATOR(fun)
1395 #define __GMP_DECLARE_COMPOUND_OPERATOR_UI(fun) \
1396 __gmp_expr & fun(mp_bitcnt_t);
1398 #define __GMP_DECLARE_INCREMENT_OPERATOR(fun) \
1399 inline __gmp_expr & fun(); \
1400 inline __gmp_expr fun(int);
1402 #define __GMPXX_DEFINE_ARITHMETIC_CONSTRUCTORS \
1403 __gmp_expr(signed char c) { init_si(c); } \
1404 __gmp_expr(unsigned char c) { init_ui(c); } \
1405 __gmp_expr(signed int i) { init_si(i); } \
1406 __gmp_expr(unsigned int i) { init_ui(i); } \
1407 __gmp_expr(signed short int s) { init_si(s); } \
1408 __gmp_expr(unsigned short int s) { init_ui(s); } \
1409 __gmp_expr(signed long int l) { init_si(l); } \
1410 __gmp_expr(unsigned long int l) { init_ui(l); } \
1411 __gmp_expr(float f) { init_d(f); } \
1412 __gmp_expr(double d) { init_d(d); }
1414 #define __GMPXX_DEFINE_ARITHMETIC_ASSIGNMENTS \
1415 __gmp_expr & operator=(signed char c) { assign_si(c); return *this; } \
1416 __gmp_expr & operator=(unsigned char c) { assign_ui(c); return *this; } \
1417 __gmp_expr & operator=(signed int i) { assign_si(i); return *this; } \
1418 __gmp_expr & operator=(unsigned int i) { assign_ui(i); return *this; } \
1419 __gmp_expr & operator=(signed short int s) { assign_si(s); return *this; } \
1420 __gmp_expr & operator=(unsigned short int s) { assign_ui(s); return *this; } \
1421 __gmp_expr & operator=(signed long int l) { assign_si(l); return *this; } \
1422 __gmp_expr & operator=(unsigned long int l) { assign_ui(l); return *this; } \
1423 __gmp_expr & operator=(float f) { assign_d(f); return *this; } \
1424 __gmp_expr & operator=(double d) { assign_d(d); return *this; }
1426 /**************** mpz_class -- wrapper for mpz_t ****************/
1428 template <>
1429 class __gmp_expr<mpz_t, mpz_t>
1431 private:
1432 typedef mpz_t value_type;
1433 value_type mp;
1435 // Helper functions used for all arithmetic types
1436 void assign_ui(unsigned long l)
1438 if (__GMPXX_CONSTANT_TRUE(l == 0))
1439 mp->_mp_size = 0;
1440 else
1441 mpz_set_ui(mp, l);
1443 void assign_si(signed long l)
1445 if (__GMPXX_CONSTANT_TRUE(l >= 0))
1446 assign_ui(l);
1447 else if (__GMPXX_CONSTANT_TRUE(l <= 0))
1449 assign_ui(-static_cast<unsigned long>(l));
1450 mpz_neg(mp, mp);
1452 else
1453 mpz_set_si(mp, l);
1455 void assign_d (double d)
1457 mpz_set_d (mp, d);
1460 void init_ui(unsigned long l)
1462 if (__GMPXX_CONSTANT_TRUE(l == 0))
1463 mpz_init(mp);
1464 else
1465 mpz_init_set_ui(mp, l);
1467 void init_si(signed long l)
1469 if (__GMPXX_CONSTANT_TRUE(l >= 0))
1470 init_ui(l);
1471 else if (__GMPXX_CONSTANT_TRUE(l <= 0))
1473 init_ui(-static_cast<unsigned long>(l));
1474 mpz_neg(mp, mp);
1476 else
1477 mpz_init_set_si(mp, l);
1479 void init_d (double d)
1481 mpz_init_set_d (mp, d);
1484 public:
1485 mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); }
1487 // constructors and destructor
1488 __gmp_expr() { mpz_init(mp); }
1490 __gmp_expr(const __gmp_expr &z) { mpz_init_set(mp, z.mp); }
1491 #if __GMPXX_USE_CXX11
1492 __gmp_expr(__gmp_expr &&z)
1493 { *mp = *z.mp; mpz_init(z.mp); }
1494 #endif
1495 template <class T>
1496 __gmp_expr(const __gmp_expr<mpz_t, T> &expr)
1497 { mpz_init(mp); __gmp_set_expr(mp, expr); }
1498 template <class T, class U>
1499 explicit __gmp_expr(const __gmp_expr<T, U> &expr)
1500 { mpz_init(mp); __gmp_set_expr(mp, expr); }
1502 __GMPXX_DEFINE_ARITHMETIC_CONSTRUCTORS
1504 explicit __gmp_expr(const char *s, int base = 0)
1506 if (mpz_init_set_str (mp, s, base) != 0)
1508 mpz_clear (mp);
1509 throw std::invalid_argument ("mpz_set_str");
1512 explicit __gmp_expr(const std::string &s, int base = 0)
1514 if (mpz_init_set_str(mp, s.c_str(), base) != 0)
1516 mpz_clear (mp);
1517 throw std::invalid_argument ("mpz_set_str");
1521 explicit __gmp_expr(mpz_srcptr z) { mpz_init_set(mp, z); }
1523 ~__gmp_expr() { mpz_clear(mp); }
1525 void swap(__gmp_expr& z) __GMPXX_NOEXCEPT { std::swap(*mp, *z.mp); }
1527 // assignment operators
1528 __gmp_expr & operator=(const __gmp_expr &z)
1529 { mpz_set(mp, z.mp); return *this; }
1530 #if __GMPXX_USE_CXX11
1531 __gmp_expr & operator=(__gmp_expr &&z) noexcept
1532 { swap(z); return *this; }
1533 #endif
1534 template <class T, class U>
1535 __gmp_expr<value_type, value_type> & operator=(const __gmp_expr<T, U> &expr)
1536 { __gmp_set_expr(mp, expr); return *this; }
1538 __GMPXX_DEFINE_ARITHMETIC_ASSIGNMENTS
1540 __gmp_expr & operator=(const char *s)
1542 if (mpz_set_str (mp, s, 0) != 0)
1543 throw std::invalid_argument ("mpz_set_str");
1544 return *this;
1546 __gmp_expr & operator=(const std::string &s)
1548 if (mpz_set_str(mp, s.c_str(), 0) != 0)
1549 throw std::invalid_argument ("mpz_set_str");
1550 return *this;
1553 // string input/output functions
1554 int set_str(const char *s, int base)
1555 { return mpz_set_str(mp, s, base); }
1556 int set_str(const std::string &s, int base)
1557 { return mpz_set_str(mp, s.c_str(), base); }
1558 std::string get_str(int base = 10) const
1560 __gmp_alloc_cstring temp(mpz_get_str(0, base, mp));
1561 return std::string(temp.str);
1564 // conversion functions
1565 mpz_srcptr __get_mp() const { return mp; }
1566 mpz_ptr __get_mp() { return mp; }
1567 mpz_srcptr get_mpz_t() const { return mp; }
1568 mpz_ptr get_mpz_t() { return mp; }
1570 signed long int get_si() const { return mpz_get_si(mp); }
1571 unsigned long int get_ui() const { return mpz_get_ui(mp); }
1572 double get_d() const { return mpz_get_d(mp); }
1574 // bool fits_schar_p() const { return mpz_fits_schar_p(mp); }
1575 // bool fits_uchar_p() const { return mpz_fits_uchar_p(mp); }
1576 bool fits_sint_p() const { return mpz_fits_sint_p(mp); }
1577 bool fits_uint_p() const { return mpz_fits_uint_p(mp); }
1578 bool fits_sshort_p() const { return mpz_fits_sshort_p(mp); }
1579 bool fits_ushort_p() const { return mpz_fits_ushort_p(mp); }
1580 bool fits_slong_p() const { return mpz_fits_slong_p(mp); }
1581 bool fits_ulong_p() const { return mpz_fits_ulong_p(mp); }
1582 // bool fits_float_p() const { return mpz_fits_float_p(mp); }
1583 // bool fits_double_p() const { return mpz_fits_double_p(mp); }
1584 // bool fits_ldouble_p() const { return mpz_fits_ldouble_p(mp); }
1586 #if __GMPXX_USE_CXX11
1587 explicit operator bool() const { return mp->_mp_size != 0; }
1588 #endif
1590 // member operators
1591 __GMP_DECLARE_COMPOUND_OPERATOR(operator+=)
1592 __GMP_DECLARE_COMPOUND_OPERATOR(operator-=)
1593 __GMP_DECLARE_COMPOUND_OPERATOR(operator*=)
1594 __GMP_DECLARE_COMPOUND_OPERATOR(operator/=)
1595 __GMP_DECLARE_COMPOUND_OPERATOR(operator%=)
1597 __GMP_DECLARE_COMPOUND_OPERATOR(operator&=)
1598 __GMP_DECLARE_COMPOUND_OPERATOR(operator|=)
1599 __GMP_DECLARE_COMPOUND_OPERATOR(operator^=)
1601 __GMP_DECLARE_COMPOUND_OPERATOR_UI(operator<<=)
1602 __GMP_DECLARE_COMPOUND_OPERATOR_UI(operator>>=)
1604 __GMP_DECLARE_INCREMENT_OPERATOR(operator++)
1605 __GMP_DECLARE_INCREMENT_OPERATOR(operator--)
1608 typedef __gmp_expr<mpz_t, mpz_t> mpz_class;
1611 /**************** mpq_class -- wrapper for mpq_t ****************/
1613 template <>
1614 class __gmp_expr<mpq_t, mpq_t>
1616 private:
1617 typedef mpq_t value_type;
1618 value_type mp;
1620 // Helper functions used for all arithmetic types
1621 void assign_ui(unsigned long l) { mpq_set_ui(mp, l, 1); }
1622 void assign_si(signed long l)
1624 if (__GMPXX_CONSTANT_TRUE(l >= 0))
1625 assign_ui(l);
1626 else
1627 mpq_set_si(mp, l, 1);
1629 void assign_d (double d) { mpq_set_d (mp, d); }
1631 void init_ui(unsigned long l) { mpq_init(mp); get_num() = l; }
1632 void init_si(signed long l) { mpq_init(mp); get_num() = l; }
1633 void init_d (double d) { mpq_init(mp); assign_d (d); }
1635 public:
1636 mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); }
1637 void canonicalize() { mpq_canonicalize(mp); }
1639 // constructors and destructor
1640 __gmp_expr() { mpq_init(mp); }
1642 __gmp_expr(const __gmp_expr &q)
1644 mpz_init_set(mpq_numref(mp), mpq_numref(q.mp));
1645 mpz_init_set(mpq_denref(mp), mpq_denref(q.mp));
1647 #if __GMPXX_USE_CXX11
1648 __gmp_expr(__gmp_expr &&q)
1649 { *mp = *q.mp; mpq_init(q.mp); }
1650 #endif
1651 template <class T>
1652 __gmp_expr(const __gmp_expr<mpz_t, T> &expr)
1653 { mpq_init(mp); __gmp_set_expr(mp, expr); }
1654 template <class T>
1655 __gmp_expr(const __gmp_expr<mpq_t, T> &expr)
1656 { mpq_init(mp); __gmp_set_expr(mp, expr); }
1657 template <class T, class U>
1658 explicit __gmp_expr(const __gmp_expr<T, U> &expr)
1659 { mpq_init(mp); __gmp_set_expr(mp, expr); }
1661 __GMPXX_DEFINE_ARITHMETIC_CONSTRUCTORS
1663 explicit __gmp_expr(const char *s, int base = 0)
1665 mpq_init (mp);
1666 // If s is the literal 0, we meant to call another constructor.
1667 // If s just happens to evaluate to 0, we would crash, so whatever.
1668 if (s == 0)
1670 // Don't turn mpq_class(0,0) into 0
1671 mpz_set_si(mpq_denref(mp), base);
1673 else if (mpq_set_str(mp, s, base) != 0)
1675 mpq_clear (mp);
1676 throw std::invalid_argument ("mpq_set_str");
1679 explicit __gmp_expr(const std::string &s, int base = 0)
1681 mpq_init(mp);
1682 if (mpq_set_str (mp, s.c_str(), base) != 0)
1684 mpq_clear (mp);
1685 throw std::invalid_argument ("mpq_set_str");
1688 explicit __gmp_expr(mpq_srcptr q)
1690 mpz_init_set(mpq_numref(mp), mpq_numref(q));
1691 mpz_init_set(mpq_denref(mp), mpq_denref(q));
1694 __gmp_expr(const mpz_class &num, const mpz_class &den)
1696 mpz_init_set(mpq_numref(mp), num.get_mpz_t());
1697 mpz_init_set(mpq_denref(mp), den.get_mpz_t());
1700 ~__gmp_expr() { mpq_clear(mp); }
1702 void swap(__gmp_expr& q) __GMPXX_NOEXCEPT { std::swap(*mp, *q.mp); }
1704 // assignment operators
1705 __gmp_expr & operator=(const __gmp_expr &q)
1706 { mpq_set(mp, q.mp); return *this; }
1707 #if __GMPXX_USE_CXX11
1708 __gmp_expr & operator=(__gmp_expr &&q) noexcept
1709 { swap(q); return *this; }
1710 __gmp_expr & operator=(mpz_class &&z) noexcept
1711 { get_num() = std::move(z); get_den() = 1u; return *this; }
1712 #endif
1713 template <class T, class U>
1714 __gmp_expr<value_type, value_type> & operator=(const __gmp_expr<T, U> &expr)
1715 { __gmp_set_expr(mp, expr); return *this; }
1717 __GMPXX_DEFINE_ARITHMETIC_ASSIGNMENTS
1719 __gmp_expr & operator=(const char *s)
1721 if (mpq_set_str (mp, s, 0) != 0)
1722 throw std::invalid_argument ("mpq_set_str");
1723 return *this;
1725 __gmp_expr & operator=(const std::string &s)
1727 if (mpq_set_str(mp, s.c_str(), 0) != 0)
1728 throw std::invalid_argument ("mpq_set_str");
1729 return *this;
1732 // string input/output functions
1733 int set_str(const char *s, int base)
1734 { return mpq_set_str(mp, s, base); }
1735 int set_str(const std::string &s, int base)
1736 { return mpq_set_str(mp, s.c_str(), base); }
1737 std::string get_str(int base = 10) const
1739 __gmp_alloc_cstring temp(mpq_get_str(0, base, mp));
1740 return std::string(temp.str);
1743 // conversion functions
1745 // casting a reference to an mpz_t to mpz_class & is a dirty hack,
1746 // but works because the internal representation of mpz_class is
1747 // exactly an mpz_t
1748 const mpz_class & get_num() const
1749 { return reinterpret_cast<const mpz_class &>(*mpq_numref(mp)); }
1750 mpz_class & get_num()
1751 { return reinterpret_cast<mpz_class &>(*mpq_numref(mp)); }
1752 const mpz_class & get_den() const
1753 { return reinterpret_cast<const mpz_class &>(*mpq_denref(mp)); }
1754 mpz_class & get_den()
1755 { return reinterpret_cast<mpz_class &>(*mpq_denref(mp)); }
1757 mpq_srcptr __get_mp() const { return mp; }
1758 mpq_ptr __get_mp() { return mp; }
1759 mpq_srcptr get_mpq_t() const { return mp; }
1760 mpq_ptr get_mpq_t() { return mp; }
1762 mpz_srcptr get_num_mpz_t() const { return mpq_numref(mp); }
1763 mpz_ptr get_num_mpz_t() { return mpq_numref(mp); }
1764 mpz_srcptr get_den_mpz_t() const { return mpq_denref(mp); }
1765 mpz_ptr get_den_mpz_t() { return mpq_denref(mp); }
1767 double get_d() const { return mpq_get_d(mp); }
1769 #if __GMPXX_USE_CXX11
1770 explicit operator bool() const { return mpq_numref(mp)->_mp_size != 0; }
1771 #endif
1773 // compound assignments
1774 __GMP_DECLARE_COMPOUND_OPERATOR(operator+=)
1775 __GMP_DECLARE_COMPOUND_OPERATOR(operator-=)
1776 __GMP_DECLARE_COMPOUND_OPERATOR(operator*=)
1777 __GMP_DECLARE_COMPOUND_OPERATOR(operator/=)
1779 __GMP_DECLARE_COMPOUND_OPERATOR_UI(operator<<=)
1780 __GMP_DECLARE_COMPOUND_OPERATOR_UI(operator>>=)
1782 __GMP_DECLARE_INCREMENT_OPERATOR(operator++)
1783 __GMP_DECLARE_INCREMENT_OPERATOR(operator--)
1786 typedef __gmp_expr<mpq_t, mpq_t> mpq_class;
1789 /**************** mpf_class -- wrapper for mpf_t ****************/
1791 template <>
1792 class __gmp_expr<mpf_t, mpf_t>
1794 private:
1795 typedef mpf_t value_type;
1796 value_type mp;
1798 // Helper functions used for all arithmetic types
1799 void assign_ui(unsigned long l) { mpf_set_ui(mp, l); }
1800 void assign_si(signed long l)
1802 if (__GMPXX_CONSTANT_TRUE(l >= 0))
1803 assign_ui(l);
1804 else
1805 mpf_set_si(mp, l);
1807 void assign_d (double d) { mpf_set_d (mp, d); }
1809 void init_ui(unsigned long l)
1811 if (__GMPXX_CONSTANT_TRUE(l == 0))
1812 mpf_init(mp);
1813 else
1814 mpf_init_set_ui(mp, l);
1816 void init_si(signed long l)
1818 if (__GMPXX_CONSTANT_TRUE(l >= 0))
1819 init_ui(l);
1820 else
1821 mpf_init_set_si(mp, l);
1823 void init_d (double d) { mpf_init_set_d (mp, d); }
1825 public:
1826 mp_bitcnt_t get_prec() const { return mpf_get_prec(mp); }
1828 void set_prec(mp_bitcnt_t prec) { mpf_set_prec(mp, prec); }
1829 void set_prec_raw(mp_bitcnt_t prec) { mpf_set_prec_raw(mp, prec); }
1831 // constructors and destructor
1832 __gmp_expr() { mpf_init(mp); }
1834 __gmp_expr(const __gmp_expr &f)
1835 { mpf_init2(mp, f.get_prec()); mpf_set(mp, f.mp); }
1836 #if __GMPXX_USE_CXX11
1837 __gmp_expr(__gmp_expr &&f)
1838 { *mp = *f.mp; mpf_init2(f.mp, get_prec()); }
1839 #endif
1840 __gmp_expr(const __gmp_expr &f, mp_bitcnt_t prec)
1841 { mpf_init2(mp, prec); mpf_set(mp, f.mp); }
1842 template <class T, class U>
1843 __gmp_expr(const __gmp_expr<T, U> &expr)
1844 { mpf_init2(mp, expr.get_prec()); __gmp_set_expr(mp, expr); }
1845 template <class T, class U>
1846 __gmp_expr(const __gmp_expr<T, U> &expr, mp_bitcnt_t prec)
1847 { mpf_init2(mp, prec); __gmp_set_expr(mp, expr); }
1849 __GMPXX_DEFINE_ARITHMETIC_CONSTRUCTORS
1851 __gmp_expr(signed char c, mp_bitcnt_t prec)
1852 { mpf_init2(mp, prec); mpf_set_si(mp, c); }
1853 __gmp_expr(unsigned char c, mp_bitcnt_t prec)
1854 { mpf_init2(mp, prec); mpf_set_ui(mp, c); }
1856 __gmp_expr(signed int i, mp_bitcnt_t prec)
1857 { mpf_init2(mp, prec); mpf_set_si(mp, i); }
1858 __gmp_expr(unsigned int i, mp_bitcnt_t prec)
1859 { mpf_init2(mp, prec); mpf_set_ui(mp, i); }
1861 __gmp_expr(signed short int s, mp_bitcnt_t prec)
1862 { mpf_init2(mp, prec); mpf_set_si(mp, s); }
1863 __gmp_expr(unsigned short int s, mp_bitcnt_t prec)
1864 { mpf_init2(mp, prec); mpf_set_ui(mp, s); }
1866 __gmp_expr(signed long int l, mp_bitcnt_t prec)
1867 { mpf_init2(mp, prec); mpf_set_si(mp, l); }
1868 __gmp_expr(unsigned long int l, mp_bitcnt_t prec)
1869 { mpf_init2(mp, prec); mpf_set_ui(mp, l); }
1871 __gmp_expr(float f, mp_bitcnt_t prec)
1872 { mpf_init2(mp, prec); mpf_set_d(mp, f); }
1873 __gmp_expr(double d, mp_bitcnt_t prec)
1874 { mpf_init2(mp, prec); mpf_set_d(mp, d); }
1875 // __gmp_expr(long double ld) { mpf_init_set_d(mp, ld); }
1876 // __gmp_expr(long double ld, mp_bitcnt_t prec)
1877 // { mpf_init2(mp, prec); mpf_set_d(mp, ld); }
1879 explicit __gmp_expr(const char *s)
1881 if (mpf_init_set_str (mp, s, 0) != 0)
1883 mpf_clear (mp);
1884 throw std::invalid_argument ("mpf_set_str");
1887 __gmp_expr(const char *s, mp_bitcnt_t prec, int base = 0)
1889 mpf_init2(mp, prec);
1890 if (mpf_set_str(mp, s, base) != 0)
1892 mpf_clear (mp);
1893 throw std::invalid_argument ("mpf_set_str");
1896 explicit __gmp_expr(const std::string &s)
1898 if (mpf_init_set_str(mp, s.c_str(), 0) != 0)
1900 mpf_clear (mp);
1901 throw std::invalid_argument ("mpf_set_str");
1904 __gmp_expr(const std::string &s, mp_bitcnt_t prec, int base = 0)
1906 mpf_init2(mp, prec);
1907 if (mpf_set_str(mp, s.c_str(), base) != 0)
1909 mpf_clear (mp);
1910 throw std::invalid_argument ("mpf_set_str");
1914 explicit __gmp_expr(mpf_srcptr f)
1915 { mpf_init2(mp, mpf_get_prec(f)); mpf_set(mp, f); }
1916 __gmp_expr(mpf_srcptr f, mp_bitcnt_t prec)
1917 { mpf_init2(mp, prec); mpf_set(mp, f); }
1919 ~__gmp_expr() { mpf_clear(mp); }
1921 void swap(__gmp_expr& f) __GMPXX_NOEXCEPT { std::swap(*mp, *f.mp); }
1923 // assignment operators
1924 __gmp_expr & operator=(const __gmp_expr &f)
1925 { mpf_set(mp, f.mp); return *this; }
1926 #if __GMPXX_USE_CXX11
1927 __gmp_expr & operator=(__gmp_expr &&f) noexcept
1928 { swap(f); return *this; }
1929 #endif
1930 template <class T, class U>
1931 __gmp_expr<value_type, value_type> & operator=(const __gmp_expr<T, U> &expr)
1932 { __gmp_set_expr(mp, expr); return *this; }
1934 __GMPXX_DEFINE_ARITHMETIC_ASSIGNMENTS
1936 __gmp_expr & operator=(const char *s)
1938 if (mpf_set_str (mp, s, 0) != 0)
1939 throw std::invalid_argument ("mpf_set_str");
1940 return *this;
1942 __gmp_expr & operator=(const std::string &s)
1944 if (mpf_set_str(mp, s.c_str(), 0) != 0)
1945 throw std::invalid_argument ("mpf_set_str");
1946 return *this;
1949 // string input/output functions
1950 int set_str(const char *s, int base)
1951 { return mpf_set_str(mp, s, base); }
1952 int set_str(const std::string &s, int base)
1953 { return mpf_set_str(mp, s.c_str(), base); }
1954 std::string get_str(mp_exp_t &expo, int base = 10, size_t size = 0) const
1956 __gmp_alloc_cstring temp(mpf_get_str(0, &expo, base, size, mp));
1957 return std::string(temp.str);
1960 // conversion functions
1961 mpf_srcptr __get_mp() const { return mp; }
1962 mpf_ptr __get_mp() { return mp; }
1963 mpf_srcptr get_mpf_t() const { return mp; }
1964 mpf_ptr get_mpf_t() { return mp; }
1966 signed long int get_si() const { return mpf_get_si(mp); }
1967 unsigned long int get_ui() const { return mpf_get_ui(mp); }
1968 double get_d() const { return mpf_get_d(mp); }
1970 // bool fits_schar_p() const { return mpf_fits_schar_p(mp); }
1971 // bool fits_uchar_p() const { return mpf_fits_uchar_p(mp); }
1972 bool fits_sint_p() const { return mpf_fits_sint_p(mp); }
1973 bool fits_uint_p() const { return mpf_fits_uint_p(mp); }
1974 bool fits_sshort_p() const { return mpf_fits_sshort_p(mp); }
1975 bool fits_ushort_p() const { return mpf_fits_ushort_p(mp); }
1976 bool fits_slong_p() const { return mpf_fits_slong_p(mp); }
1977 bool fits_ulong_p() const { return mpf_fits_ulong_p(mp); }
1978 // bool fits_float_p() const { return mpf_fits_float_p(mp); }
1979 // bool fits_double_p() const { return mpf_fits_double_p(mp); }
1980 // bool fits_ldouble_p() const { return mpf_fits_ldouble_p(mp); }
1982 #if __GMPXX_USE_CXX11
1983 explicit operator bool() const { return mp->_mp_size != 0; }
1984 #endif
1986 // compound assignments
1987 __GMP_DECLARE_COMPOUND_OPERATOR(operator+=)
1988 __GMP_DECLARE_COMPOUND_OPERATOR(operator-=)
1989 __GMP_DECLARE_COMPOUND_OPERATOR(operator*=)
1990 __GMP_DECLARE_COMPOUND_OPERATOR(operator/=)
1992 __GMP_DECLARE_COMPOUND_OPERATOR_UI(operator<<=)
1993 __GMP_DECLARE_COMPOUND_OPERATOR_UI(operator>>=)
1995 __GMP_DECLARE_INCREMENT_OPERATOR(operator++)
1996 __GMP_DECLARE_INCREMENT_OPERATOR(operator--)
1999 typedef __gmp_expr<mpf_t, mpf_t> mpf_class;
2003 /**************** User-defined literals ****************/
2005 #if __GMPXX_USE_CXX11
2006 inline mpz_class operator"" _mpz(const char* s)
2008 return mpz_class(s);
2011 inline mpq_class operator"" _mpq(const char* s)
2013 mpq_class q;
2014 q.get_num() = s;
2015 return q;
2018 inline mpf_class operator"" _mpf(const char* s)
2020 return mpf_class(s);
2022 #endif
2024 /**************** I/O operators ****************/
2026 // these should (and will) be provided separately
2028 template <class T, class U>
2029 inline std::ostream & operator<<
2030 (std::ostream &o, const __gmp_expr<T, U> &expr)
2032 __gmp_expr<T, T> const& temp(expr);
2033 return o << temp.__get_mp();
2036 template <class T>
2037 inline std::istream & operator>>(std::istream &i, __gmp_expr<T, T> &expr)
2039 return i >> expr.__get_mp();
2043 // you might want to uncomment this
2044 inline std::istream & operator>>(std::istream &i, mpq_class &q)
2046 i >> q.get_mpq_t();
2047 q.canonicalize();
2048 return i;
2053 /**************** Functions for type conversion ****************/
2055 inline void __gmp_set_expr(mpz_ptr z, const mpz_class &w)
2057 mpz_set(z, w.get_mpz_t());
2060 template <class T>
2061 inline void __gmp_set_expr(mpz_ptr z, const __gmp_expr<mpz_t, T> &expr)
2063 expr.eval(z);
2066 template <class T>
2067 inline void __gmp_set_expr(mpz_ptr z, const __gmp_expr<mpq_t, T> &expr)
2069 mpq_class const& temp(expr);
2070 mpz_set_q(z, temp.get_mpq_t());
2073 template <class T>
2074 inline void __gmp_set_expr(mpz_ptr z, const __gmp_expr<mpf_t, T> &expr)
2076 mpf_class const& temp(expr);
2077 mpz_set_f(z, temp.get_mpf_t());
2080 inline void __gmp_set_expr(mpq_ptr q, const mpz_class &z)
2082 mpq_set_z(q, z.get_mpz_t());
2085 template <class T>
2086 inline void __gmp_set_expr(mpq_ptr q, const __gmp_expr<mpz_t, T> &expr)
2088 __gmp_set_expr(mpq_numref(q), expr);
2089 mpz_set_ui(mpq_denref(q), 1);
2092 inline void __gmp_set_expr(mpq_ptr q, const mpq_class &r)
2094 mpq_set(q, r.get_mpq_t());
2097 template <class T>
2098 inline void __gmp_set_expr(mpq_ptr q, const __gmp_expr<mpq_t, T> &expr)
2100 expr.eval(q);
2103 template <class T>
2104 inline void __gmp_set_expr(mpq_ptr q, const __gmp_expr<mpf_t, T> &expr)
2106 mpf_class const& temp(expr);
2107 mpq_set_f(q, temp.get_mpf_t());
2110 template <class T>
2111 inline void __gmp_set_expr(mpf_ptr f, const __gmp_expr<mpz_t, T> &expr)
2113 mpz_class const& temp(expr);
2114 mpf_set_z(f, temp.get_mpz_t());
2117 template <class T>
2118 inline void __gmp_set_expr(mpf_ptr f, const __gmp_expr<mpq_t, T> &expr)
2120 mpq_class const& temp(expr);
2121 mpf_set_q(f, temp.get_mpq_t());
2124 inline void __gmp_set_expr(mpf_ptr f, const mpf_class &g)
2126 mpf_set(f, g.get_mpf_t());
2129 template <class T>
2130 inline void __gmp_set_expr(mpf_ptr f, const __gmp_expr<mpf_t, T> &expr)
2132 expr.eval(f);
2136 /* Temporary objects */
2138 template <class T>
2139 class __gmp_temp
2141 __gmp_expr<T, T> val;
2142 public:
2143 template<class U, class V>
2144 __gmp_temp(U const& u, V) : val (u) {}
2145 typename __gmp_resolve_expr<T>::srcptr_type
2146 __get_mp() const { return val.__get_mp(); }
2149 template <>
2150 class __gmp_temp <mpf_t>
2152 mpf_class val;
2153 public:
2154 template<class U>
2155 __gmp_temp(U const& u, mpf_ptr res) : val (u, mpf_get_prec(res)) {}
2156 mpf_srcptr __get_mp() const { return val.__get_mp(); }
2159 /**************** Specializations of __gmp_expr ****************/
2160 /* The eval() method of __gmp_expr<T, U> evaluates the corresponding
2161 expression and assigns the result to its argument, which is either an
2162 mpz_t, mpq_t, or mpf_t as specified by the T argument.
2163 Compound expressions are evaluated recursively (temporaries are created
2164 to hold intermediate values), while for simple expressions the eval()
2165 method of the appropriate function object (available as the Op argument
2166 of either __gmp_unary_expr<T, Op> or __gmp_binary_expr<T, U, Op>) is
2167 called. */
2170 /**************** Unary expressions ****************/
2171 /* cases:
2172 - simple: argument is mp*_class, that is, __gmp_expr<T, T>
2173 - compound: argument is __gmp_expr<T, U> (with U not equal to T) */
2176 // simple expressions
2178 template <class T, class Op>
2179 class __gmp_expr<T, __gmp_unary_expr<__gmp_expr<T, T>, Op> >
2181 private:
2182 typedef __gmp_expr<T, T> val_type;
2184 __gmp_unary_expr<val_type, Op> expr;
2185 public:
2186 explicit __gmp_expr(const val_type &val) : expr(val) { }
2187 void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
2188 { Op::eval(p, expr.val.__get_mp()); }
2189 const val_type & get_val() const { return expr.val; }
2190 mp_bitcnt_t get_prec() const { return expr.val.get_prec(); }
2194 // simple expressions, U is a built-in numerical type
2196 template <class T, class U, class Op>
2197 class __gmp_expr<T, __gmp_unary_expr<U, Op> >
2199 private:
2200 typedef U val_type;
2202 __gmp_unary_expr<val_type, Op> expr;
2203 public:
2204 explicit __gmp_expr(const val_type &val) : expr(val) { }
2205 void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
2206 { Op::eval(p, expr.val); }
2207 const val_type & get_val() const { return expr.val; }
2208 mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); }
2212 // compound expressions
2214 template <class T, class U, class Op>
2215 class __gmp_expr<T, __gmp_unary_expr<__gmp_expr<T, U>, Op> >
2217 private:
2218 typedef __gmp_expr<T, U> val_type;
2220 __gmp_unary_expr<val_type, Op> expr;
2221 public:
2222 explicit __gmp_expr(const val_type &val) : expr(val) { }
2223 void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
2224 { expr.val.eval(p); Op::eval(p, p); }
2225 const val_type & get_val() const { return expr.val; }
2226 mp_bitcnt_t get_prec() const { return expr.val.get_prec(); }
2230 /**************** Binary expressions ****************/
2231 /* simple:
2232 - arguments are both mp*_class
2233 - one argument is mp*_class, one is a built-in type
2234 compound:
2235 - one is mp*_class, one is __gmp_expr<T, U>
2236 - one is __gmp_expr<T, U>, one is built-in
2237 - both arguments are __gmp_expr<...> */
2240 // simple expressions
2242 template <class T, class Op>
2243 class __gmp_expr
2244 <T, __gmp_binary_expr<__gmp_expr<T, T>, __gmp_expr<T, T>, Op> >
2246 private:
2247 typedef __gmp_expr<T, T> val1_type;
2248 typedef __gmp_expr<T, T> val2_type;
2250 __gmp_binary_expr<val1_type, val2_type, Op> expr;
2251 public:
2252 __gmp_expr(const val1_type &val1, const val2_type &val2)
2253 : expr(val1, val2) { }
2254 void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
2255 { Op::eval(p, expr.val1.__get_mp(), expr.val2.__get_mp()); }
2256 const val1_type & get_val1() const { return expr.val1; }
2257 const val2_type & get_val2() const { return expr.val2; }
2258 mp_bitcnt_t get_prec() const
2260 mp_bitcnt_t prec1 = expr.val1.get_prec(),
2261 prec2 = expr.val2.get_prec();
2262 return (prec1 > prec2) ? prec1 : prec2;
2267 // simple expressions, U is a built-in numerical type
2269 template <class T, class U, class Op>
2270 class __gmp_expr<T, __gmp_binary_expr<__gmp_expr<T, T>, U, Op> >
2272 private:
2273 typedef __gmp_expr<T, T> val1_type;
2274 typedef U val2_type;
2276 __gmp_binary_expr<val1_type, val2_type, Op> expr;
2277 public:
2278 __gmp_expr(const val1_type &val1, const val2_type &val2)
2279 : expr(val1, val2) { }
2280 void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
2281 { Op::eval(p, expr.val1.__get_mp(), expr.val2); }
2282 const val1_type & get_val1() const { return expr.val1; }
2283 const val2_type & get_val2() const { return expr.val2; }
2284 mp_bitcnt_t get_prec() const { return expr.val1.get_prec(); }
2287 template <class T, class U, class Op>
2288 class __gmp_expr<T, __gmp_binary_expr<U, __gmp_expr<T, T>, Op> >
2290 private:
2291 typedef U val1_type;
2292 typedef __gmp_expr<T, T> val2_type;
2294 __gmp_binary_expr<val1_type, val2_type, Op> expr;
2295 public:
2296 __gmp_expr(const val1_type &val1, const val2_type &val2)
2297 : expr(val1, val2) { }
2298 void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
2299 { Op::eval(p, expr.val1, expr.val2.__get_mp()); }
2300 const val1_type & get_val1() const { return expr.val1; }
2301 const val2_type & get_val2() const { return expr.val2; }
2302 mp_bitcnt_t get_prec() const { return expr.val2.get_prec(); }
2306 // compound expressions, one argument is a subexpression
2308 template <class T, class U, class V, class Op>
2309 class __gmp_expr
2310 <T, __gmp_binary_expr<__gmp_expr<T, T>, __gmp_expr<U, V>, Op> >
2312 private:
2313 typedef __gmp_expr<T, T> val1_type;
2314 typedef __gmp_expr<U, V> val2_type;
2316 __gmp_binary_expr<val1_type, val2_type, Op> expr;
2317 public:
2318 __gmp_expr(const val1_type &val1, const val2_type &val2)
2319 : expr(val1, val2) { }
2320 void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
2322 if(p != expr.val1.__get_mp())
2324 __gmp_set_expr(p, expr.val2);
2325 Op::eval(p, expr.val1.__get_mp(), p);
2327 else
2329 __gmp_temp<T> temp(expr.val2, p);
2330 Op::eval(p, expr.val1.__get_mp(), temp.__get_mp());
2333 const val1_type & get_val1() const { return expr.val1; }
2334 const val2_type & get_val2() const { return expr.val2; }
2335 mp_bitcnt_t get_prec() const
2337 mp_bitcnt_t prec1 = expr.val1.get_prec(),
2338 prec2 = expr.val2.get_prec();
2339 return (prec1 > prec2) ? prec1 : prec2;
2343 template <class T, class U, class V, class Op>
2344 class __gmp_expr
2345 <T, __gmp_binary_expr<__gmp_expr<U, V>, __gmp_expr<T, T>, Op> >
2347 private:
2348 typedef __gmp_expr<U, V> val1_type;
2349 typedef __gmp_expr<T, T> val2_type;
2351 __gmp_binary_expr<val1_type, val2_type, Op> expr;
2352 public:
2353 __gmp_expr(const val1_type &val1, const val2_type &val2)
2354 : expr(val1, val2) { }
2355 void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
2357 if(p != expr.val2.__get_mp())
2359 __gmp_set_expr(p, expr.val1);
2360 Op::eval(p, p, expr.val2.__get_mp());
2362 else
2364 __gmp_temp<T> temp(expr.val1, p);
2365 Op::eval(p, temp.__get_mp(), expr.val2.__get_mp());
2368 const val1_type & get_val1() const { return expr.val1; }
2369 const val2_type & get_val2() const { return expr.val2; }
2370 mp_bitcnt_t get_prec() const
2372 mp_bitcnt_t prec1 = expr.val1.get_prec(),
2373 prec2 = expr.val2.get_prec();
2374 return (prec1 > prec2) ? prec1 : prec2;
2378 template <class T, class U, class Op>
2379 class __gmp_expr
2380 <T, __gmp_binary_expr<__gmp_expr<T, T>, __gmp_expr<T, U>, Op> >
2382 private:
2383 typedef __gmp_expr<T, T> val1_type;
2384 typedef __gmp_expr<T, U> val2_type;
2386 __gmp_binary_expr<val1_type, val2_type, Op> expr;
2387 public:
2388 __gmp_expr(const val1_type &val1, const val2_type &val2)
2389 : expr(val1, val2) { }
2390 void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
2392 if(p != expr.val1.__get_mp())
2394 __gmp_set_expr(p, expr.val2);
2395 Op::eval(p, expr.val1.__get_mp(), p);
2397 else
2399 __gmp_temp<T> temp(expr.val2, p);
2400 Op::eval(p, expr.val1.__get_mp(), temp.__get_mp());
2403 const val1_type & get_val1() const { return expr.val1; }
2404 const val2_type & get_val2() const { return expr.val2; }
2405 mp_bitcnt_t get_prec() const
2407 mp_bitcnt_t prec1 = expr.val1.get_prec(),
2408 prec2 = expr.val2.get_prec();
2409 return (prec1 > prec2) ? prec1 : prec2;
2413 template <class T, class U, class Op>
2414 class __gmp_expr
2415 <T, __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<T, T>, Op> >
2417 private:
2418 typedef __gmp_expr<T, U> val1_type;
2419 typedef __gmp_expr<T, T> val2_type;
2421 __gmp_binary_expr<val1_type, val2_type, Op> expr;
2422 public:
2423 __gmp_expr(const val1_type &val1, const val2_type &val2)
2424 : expr(val1, val2) { }
2425 void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
2427 if(p != expr.val2.__get_mp())
2429 __gmp_set_expr(p, expr.val1);
2430 Op::eval(p, p, expr.val2.__get_mp());
2432 else
2434 __gmp_temp<T> temp(expr.val1, p);
2435 Op::eval(p, temp.__get_mp(), expr.val2.__get_mp());
2438 const val1_type & get_val1() const { return expr.val1; }
2439 const val2_type & get_val2() const { return expr.val2; }
2440 mp_bitcnt_t get_prec() const
2442 mp_bitcnt_t prec1 = expr.val1.get_prec(),
2443 prec2 = expr.val2.get_prec();
2444 return (prec1 > prec2) ? prec1 : prec2;
2449 // one argument is a subexpression, one is a built-in
2451 template <class T, class U, class V, class Op>
2452 class __gmp_expr<T, __gmp_binary_expr<__gmp_expr<T, U>, V, Op> >
2454 private:
2455 typedef __gmp_expr<T, U> val1_type;
2456 typedef V val2_type;
2458 __gmp_binary_expr<val1_type, val2_type, Op> expr;
2459 public:
2460 __gmp_expr(const val1_type &val1, const val2_type &val2)
2461 : expr(val1, val2) { }
2462 void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
2464 expr.val1.eval(p);
2465 Op::eval(p, p, expr.val2);
2467 const val1_type & get_val1() const { return expr.val1; }
2468 const val2_type & get_val2() const { return expr.val2; }
2469 mp_bitcnt_t get_prec() const { return expr.val1.get_prec(); }
2472 template <class T, class U, class V, class Op>
2473 class __gmp_expr<T, __gmp_binary_expr<U, __gmp_expr<T, V>, Op> >
2475 private:
2476 typedef U val1_type;
2477 typedef __gmp_expr<T, V> val2_type;
2479 __gmp_binary_expr<val1_type, val2_type, Op> expr;
2480 public:
2481 __gmp_expr(const val1_type &val1, const val2_type &val2)
2482 : expr(val1, val2) { }
2483 void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
2485 expr.val2.eval(p);
2486 Op::eval(p, expr.val1, p);
2488 const val1_type & get_val1() const { return expr.val1; }
2489 const val2_type & get_val2() const { return expr.val2; }
2490 mp_bitcnt_t get_prec() const { return expr.val2.get_prec(); }
2494 // both arguments are subexpressions
2496 template <class T, class U, class V, class W, class Op>
2497 class __gmp_expr
2498 <T, __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<V, W>, Op> >
2500 private:
2501 typedef __gmp_expr<T, U> val1_type;
2502 typedef __gmp_expr<V, W> val2_type;
2504 __gmp_binary_expr<val1_type, val2_type, Op> expr;
2505 public:
2506 __gmp_expr(const val1_type &val1, const val2_type &val2)
2507 : expr(val1, val2) { }
2508 void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
2510 __gmp_temp<T> temp2(expr.val2, p);
2511 expr.val1.eval(p);
2512 Op::eval(p, p, temp2.__get_mp());
2514 const val1_type & get_val1() const { return expr.val1; }
2515 const val2_type & get_val2() const { return expr.val2; }
2516 mp_bitcnt_t get_prec() const
2518 mp_bitcnt_t prec1 = expr.val1.get_prec(),
2519 prec2 = expr.val2.get_prec();
2520 return (prec1 > prec2) ? prec1 : prec2;
2524 template <class T, class U, class V, class W, class Op>
2525 class __gmp_expr
2526 <T, __gmp_binary_expr<__gmp_expr<U, V>, __gmp_expr<T, W>, Op> >
2528 private:
2529 typedef __gmp_expr<U, V> val1_type;
2530 typedef __gmp_expr<T, W> val2_type;
2532 __gmp_binary_expr<val1_type, val2_type, Op> expr;
2533 public:
2534 __gmp_expr(const val1_type &val1, const val2_type &val2)
2535 : expr(val1, val2) { }
2536 void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
2538 __gmp_temp<T> temp1(expr.val1, p);
2539 expr.val2.eval(p);
2540 Op::eval(p, temp1.__get_mp(), p);
2542 const val1_type & get_val1() const { return expr.val1; }
2543 const val2_type & get_val2() const { return expr.val2; }
2544 mp_bitcnt_t get_prec() const
2546 mp_bitcnt_t prec1 = expr.val1.get_prec(),
2547 prec2 = expr.val2.get_prec();
2548 return (prec1 > prec2) ? prec1 : prec2;
2552 template <class T, class U, class V, class Op>
2553 class __gmp_expr
2554 <T, __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<T, V>, Op> >
2556 private:
2557 typedef __gmp_expr<T, U> val1_type;
2558 typedef __gmp_expr<T, V> val2_type;
2560 __gmp_binary_expr<val1_type, val2_type, Op> expr;
2561 public:
2562 __gmp_expr(const val1_type &val1, const val2_type &val2)
2563 : expr(val1, val2) { }
2564 void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
2566 __gmp_temp<T> temp2(expr.val2, p);
2567 expr.val1.eval(p);
2568 Op::eval(p, p, temp2.__get_mp());
2570 const val1_type & get_val1() const { return expr.val1; }
2571 const val2_type & get_val2() const { return expr.val2; }
2572 mp_bitcnt_t get_prec() const
2574 mp_bitcnt_t prec1 = expr.val1.get_prec(),
2575 prec2 = expr.val2.get_prec();
2576 return (prec1 > prec2) ? prec1 : prec2;
2581 /**************** Special cases ****************/
2583 /* Some operations (i.e., add and subtract) with mixed mpz/mpq arguments
2584 can be done directly without first converting the mpz to mpq.
2585 Appropriate specializations of __gmp_expr are required. */
2588 #define __GMPZQ_DEFINE_EXPR(eval_fun) \
2590 template <> \
2591 class __gmp_expr<mpq_t, __gmp_binary_expr<mpz_class, mpq_class, eval_fun> > \
2593 private: \
2594 typedef mpz_class val1_type; \
2595 typedef mpq_class val2_type; \
2597 __gmp_binary_expr<val1_type, val2_type, eval_fun> expr; \
2598 public: \
2599 __gmp_expr(const val1_type &val1, const val2_type &val2) \
2600 : expr(val1, val2) { } \
2601 void eval(mpq_ptr q) const \
2602 { eval_fun::eval(q, expr.val1.get_mpz_t(), expr.val2.get_mpq_t()); } \
2603 const val1_type & get_val1() const { return expr.val1; } \
2604 const val2_type & get_val2() const { return expr.val2; } \
2605 mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); } \
2606 }; \
2608 template <> \
2609 class __gmp_expr<mpq_t, __gmp_binary_expr<mpq_class, mpz_class, eval_fun> > \
2611 private: \
2612 typedef mpq_class val1_type; \
2613 typedef mpz_class val2_type; \
2615 __gmp_binary_expr<val1_type, val2_type, eval_fun> expr; \
2616 public: \
2617 __gmp_expr(const val1_type &val1, const val2_type &val2) \
2618 : expr(val1, val2) { } \
2619 void eval(mpq_ptr q) const \
2620 { eval_fun::eval(q, expr.val1.get_mpq_t(), expr.val2.get_mpz_t()); } \
2621 const val1_type & get_val1() const { return expr.val1; } \
2622 const val2_type & get_val2() const { return expr.val2; } \
2623 mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); } \
2624 }; \
2626 template <class T> \
2627 class __gmp_expr \
2628 <mpq_t, __gmp_binary_expr<mpz_class, __gmp_expr<mpq_t, T>, eval_fun> > \
2630 private: \
2631 typedef mpz_class val1_type; \
2632 typedef __gmp_expr<mpq_t, T> val2_type; \
2634 __gmp_binary_expr<val1_type, val2_type, eval_fun> expr; \
2635 public: \
2636 __gmp_expr(const val1_type &val1, const val2_type &val2) \
2637 : expr(val1, val2) { } \
2638 void eval(mpq_ptr q) const \
2640 mpq_class temp(expr.val2); \
2641 eval_fun::eval(q, expr.val1.get_mpz_t(), temp.get_mpq_t()); \
2643 const val1_type & get_val1() const { return expr.val1; } \
2644 const val2_type & get_val2() const { return expr.val2; } \
2645 mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); } \
2646 }; \
2648 template <class T> \
2649 class __gmp_expr \
2650 <mpq_t, __gmp_binary_expr<mpq_class, __gmp_expr<mpz_t, T>, eval_fun> > \
2652 private: \
2653 typedef mpq_class val1_type; \
2654 typedef __gmp_expr<mpz_t, T> val2_type; \
2656 __gmp_binary_expr<val1_type, val2_type, eval_fun> expr; \
2657 public: \
2658 __gmp_expr(const val1_type &val1, const val2_type &val2) \
2659 : expr(val1, val2) { } \
2660 void eval(mpq_ptr q) const \
2662 mpz_class temp(expr.val2); \
2663 eval_fun::eval(q, expr.val1.get_mpq_t(), temp.get_mpz_t()); \
2665 const val1_type & get_val1() const { return expr.val1; } \
2666 const val2_type & get_val2() const { return expr.val2; } \
2667 mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); } \
2668 }; \
2670 template <class T> \
2671 class __gmp_expr \
2672 <mpq_t, __gmp_binary_expr<__gmp_expr<mpz_t, T>, mpq_class, eval_fun> > \
2674 private: \
2675 typedef __gmp_expr<mpz_t, T> val1_type; \
2676 typedef mpq_class val2_type; \
2678 __gmp_binary_expr<val1_type, val2_type, eval_fun> expr; \
2679 public: \
2680 __gmp_expr(const val1_type &val1, const val2_type &val2) \
2681 : expr(val1, val2) { } \
2682 void eval(mpq_ptr q) const \
2684 mpz_class temp(expr.val1); \
2685 eval_fun::eval(q, temp.get_mpz_t(), expr.val2.get_mpq_t()); \
2687 const val1_type & get_val1() const { return expr.val1; } \
2688 const val2_type & get_val2() const { return expr.val2; } \
2689 mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); } \
2690 }; \
2692 template <class T> \
2693 class __gmp_expr \
2694 <mpq_t, __gmp_binary_expr<__gmp_expr<mpq_t, T>, mpz_class, eval_fun> > \
2696 private: \
2697 typedef __gmp_expr<mpq_t, T> val1_type; \
2698 typedef mpz_class val2_type; \
2700 __gmp_binary_expr<val1_type, val2_type, eval_fun> expr; \
2701 public: \
2702 __gmp_expr(const val1_type &val1, const val2_type &val2) \
2703 : expr(val1, val2) { } \
2704 void eval(mpq_ptr q) const \
2706 mpq_class temp(expr.val1); \
2707 eval_fun::eval(q, temp.get_mpq_t(), expr.val2.get_mpz_t()); \
2709 const val1_type & get_val1() const { return expr.val1; } \
2710 const val2_type & get_val2() const { return expr.val2; } \
2711 mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); } \
2712 }; \
2714 template <class T, class U> \
2715 class __gmp_expr<mpq_t, __gmp_binary_expr \
2716 <__gmp_expr<mpz_t, T>, __gmp_expr<mpq_t, U>, eval_fun> > \
2718 private: \
2719 typedef __gmp_expr<mpz_t, T> val1_type; \
2720 typedef __gmp_expr<mpq_t, U> val2_type; \
2722 __gmp_binary_expr<val1_type, val2_type, eval_fun> expr; \
2723 public: \
2724 __gmp_expr(const val1_type &val1, const val2_type &val2) \
2725 : expr(val1, val2) { } \
2726 void eval(mpq_ptr q) const \
2728 mpz_class temp1(expr.val1); \
2729 expr.val2.eval(q); \
2730 eval_fun::eval(q, temp1.get_mpz_t(), q); \
2732 const val1_type & get_val1() const { return expr.val1; } \
2733 const val2_type & get_val2() const { return expr.val2; } \
2734 mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); } \
2735 }; \
2737 template <class T, class U> \
2738 class __gmp_expr<mpq_t, __gmp_binary_expr \
2739 <__gmp_expr<mpq_t, T>, __gmp_expr<mpz_t, U>, eval_fun> > \
2741 private: \
2742 typedef __gmp_expr<mpq_t, T> val1_type; \
2743 typedef __gmp_expr<mpz_t, U> val2_type; \
2745 __gmp_binary_expr<val1_type, val2_type, eval_fun> expr; \
2746 public: \
2747 __gmp_expr(const val1_type &val1, const val2_type &val2) \
2748 : expr(val1, val2) { } \
2749 void eval(mpq_ptr q) const \
2751 mpz_class temp2(expr.val2); \
2752 expr.val1.eval(q); \
2753 eval_fun::eval(q, q, temp2.get_mpz_t()); \
2755 const val1_type & get_val1() const { return expr.val1; } \
2756 const val2_type & get_val2() const { return expr.val2; } \
2757 mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); } \
2761 __GMPZQ_DEFINE_EXPR(__gmp_binary_plus)
2762 __GMPZQ_DEFINE_EXPR(__gmp_binary_minus)
2766 /**************** Macros for defining functions ****************/
2767 /* Results of operators and functions are instances of __gmp_expr<T, U>.
2768 T determines the numerical type of the expression: it can be either
2769 mpz_t, mpq_t, or mpf_t. When the arguments of a binary
2770 expression have different numerical types, __gmp_resolve_expr is used
2771 to determine the "larger" type.
2772 U is either __gmp_unary_expr<V, Op> or __gmp_binary_expr<V, W, Op>,
2773 where V and W are the arguments' types -- they can in turn be
2774 expressions, thus allowing to build compound expressions to any
2775 degree of complexity.
2776 Op is a function object that must have an eval() method accepting
2777 appropriate arguments.
2778 Actual evaluation of a __gmp_expr<T, U> object is done when it gets
2779 assigned to an mp*_class ("lazy" evaluation): this is done by calling
2780 its eval() method. */
2783 // non-member unary operators and functions
2785 #define __GMP_DEFINE_UNARY_FUNCTION(fun, eval_fun) \
2787 template <class T, class U> \
2788 inline __gmp_expr<T, __gmp_unary_expr<__gmp_expr<T, U>, eval_fun> > \
2789 fun(const __gmp_expr<T, U> &expr) \
2791 return __gmp_expr<T, __gmp_unary_expr<__gmp_expr<T, U>, eval_fun> >(expr); \
2794 #define __GMP_DEFINE_UNARY_TYPE_FUNCTION(type, fun, eval_fun) \
2796 template <class T, class U> \
2797 inline type fun(const __gmp_expr<T, U> &expr) \
2799 __gmp_expr<T, T> const& temp(expr); \
2800 return eval_fun::eval(temp.__get_mp()); \
2804 // non-member binary operators and functions
2806 #define __GMPP_DEFINE_BINARY_FUNCTION(fun, eval_fun) \
2808 template <class T, class U, class V, class W> \
2809 inline __gmp_expr<typename __gmp_resolve_expr<T, V>::value_type, \
2810 __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<V, W>, eval_fun> > \
2811 fun(const __gmp_expr<T, U> &expr1, const __gmp_expr<V, W> &expr2) \
2813 return __gmp_expr<typename __gmp_resolve_expr<T, V>::value_type, \
2814 __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<V, W>, eval_fun> > \
2815 (expr1, expr2); \
2818 #define __GMPNN_DEFINE_BINARY_FUNCTION(fun, eval_fun, type, bigtype) \
2820 template <class T, class U> \
2821 inline __gmp_expr \
2822 <T, __gmp_binary_expr<__gmp_expr<T, U>, bigtype, eval_fun> > \
2823 fun(const __gmp_expr<T, U> &expr, type t) \
2825 return __gmp_expr \
2826 <T, __gmp_binary_expr<__gmp_expr<T, U>, bigtype, eval_fun> >(expr, t); \
2829 template <class T, class U> \
2830 inline __gmp_expr \
2831 <T, __gmp_binary_expr<bigtype, __gmp_expr<T, U>, eval_fun> > \
2832 fun(type t, const __gmp_expr<T, U> &expr) \
2834 return __gmp_expr \
2835 <T, __gmp_binary_expr<bigtype, __gmp_expr<T, U>, eval_fun> >(t, expr); \
2838 #define __GMPNS_DEFINE_BINARY_FUNCTION(fun, eval_fun, type) \
2839 __GMPNN_DEFINE_BINARY_FUNCTION(fun, eval_fun, type, signed long int)
2841 #define __GMPNU_DEFINE_BINARY_FUNCTION(fun, eval_fun, type) \
2842 __GMPNN_DEFINE_BINARY_FUNCTION(fun, eval_fun, type, unsigned long int)
2844 #define __GMPND_DEFINE_BINARY_FUNCTION(fun, eval_fun, type) \
2845 __GMPNN_DEFINE_BINARY_FUNCTION(fun, eval_fun, type, double)
2847 #define __GMPNLD_DEFINE_BINARY_FUNCTION(fun, eval_fun, type) \
2848 __GMPNN_DEFINE_BINARY_FUNCTION(fun, eval_fun, type, long double)
2850 #define __GMPN_DEFINE_BINARY_FUNCTION(fun, eval_fun) \
2851 __GMPNS_DEFINE_BINARY_FUNCTION(fun, eval_fun, signed char) \
2852 __GMPNU_DEFINE_BINARY_FUNCTION(fun, eval_fun, unsigned char) \
2853 __GMPNS_DEFINE_BINARY_FUNCTION(fun, eval_fun, signed int) \
2854 __GMPNU_DEFINE_BINARY_FUNCTION(fun, eval_fun, unsigned int) \
2855 __GMPNS_DEFINE_BINARY_FUNCTION(fun, eval_fun, signed short int) \
2856 __GMPNU_DEFINE_BINARY_FUNCTION(fun, eval_fun, unsigned short int) \
2857 __GMPNS_DEFINE_BINARY_FUNCTION(fun, eval_fun, signed long int) \
2858 __GMPNU_DEFINE_BINARY_FUNCTION(fun, eval_fun, unsigned long int) \
2859 __GMPND_DEFINE_BINARY_FUNCTION(fun, eval_fun, float) \
2860 __GMPND_DEFINE_BINARY_FUNCTION(fun, eval_fun, double) \
2861 /* __GMPNLD_DEFINE_BINARY_FUNCTION(fun, eval_fun, long double) */
2863 #define __GMP_DEFINE_BINARY_FUNCTION(fun, eval_fun) \
2864 __GMPP_DEFINE_BINARY_FUNCTION(fun, eval_fun) \
2865 __GMPN_DEFINE_BINARY_FUNCTION(fun, eval_fun)
2868 #define __GMP_DEFINE_BINARY_FUNCTION_UI(fun, eval_fun) \
2870 template <class T, class U> \
2871 inline __gmp_expr \
2872 <T, __gmp_binary_expr<__gmp_expr<T, U>, mp_bitcnt_t, eval_fun> > \
2873 fun(const __gmp_expr<T, U> &expr, mp_bitcnt_t l) \
2875 return __gmp_expr<T, __gmp_binary_expr \
2876 <__gmp_expr<T, U>, mp_bitcnt_t, eval_fun> >(expr, l); \
2880 #define __GMPP_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun) \
2882 template <class T, class U, class V, class W> \
2883 inline type fun(const __gmp_expr<T, U> &expr1, \
2884 const __gmp_expr<V, W> &expr2) \
2886 __gmp_expr<T, T> const& temp1(expr1); \
2887 __gmp_expr<V, V> const& temp2(expr2); \
2888 return eval_fun::eval(temp1.__get_mp(), temp2.__get_mp()); \
2891 #define __GMPNN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, \
2892 type2, bigtype) \
2894 template <class T, class U> \
2895 inline type fun(const __gmp_expr<T, U> &expr, type2 t) \
2897 __gmp_expr<T, T> const& temp(expr); \
2898 return eval_fun::eval(temp.__get_mp(), static_cast<bigtype>(t)); \
2901 template <class T, class U> \
2902 inline type fun(type2 t, const __gmp_expr<T, U> &expr) \
2904 __gmp_expr<T, T> const& temp(expr); \
2905 return eval_fun::eval(static_cast<bigtype>(t), temp.__get_mp()); \
2908 #define __GMPNS_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, type2) \
2909 __GMPNN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, \
2910 type2, signed long int)
2912 #define __GMPNU_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, type2) \
2913 __GMPNN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, \
2914 type2, unsigned long int)
2916 #define __GMPND_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, type2) \
2917 __GMPNN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, type2, double)
2919 #define __GMPNLD_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, type2) \
2920 __GMPNN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, type2, long double)
2922 #define __GMPN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun) \
2923 __GMPNS_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, signed char) \
2924 __GMPNU_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, unsigned char) \
2925 __GMPNS_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, signed int) \
2926 __GMPNU_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, unsigned int) \
2927 __GMPNS_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, signed short int) \
2928 __GMPNU_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, unsigned short int) \
2929 __GMPNS_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, signed long int) \
2930 __GMPNU_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, unsigned long int) \
2931 __GMPND_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, float) \
2932 __GMPND_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, double) \
2933 /* __GMPNLD_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, long double) */
2935 #define __GMP_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun) \
2936 __GMPP_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun) \
2937 __GMPN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun)
2940 // member operators
2942 #define __GMPP_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun) \
2944 template <class T, class U> \
2945 inline type##_class & type##_class::fun(const __gmp_expr<T, U> &expr) \
2947 __gmp_set_expr(mp, __gmp_expr<type##_t, __gmp_binary_expr \
2948 <type##_class, __gmp_expr<T, U>, eval_fun> >(*this, expr)); \
2949 return *this; \
2952 #define __GMPNN_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, \
2953 type2, bigtype) \
2955 inline type##_class & type##_class::fun(type2 t) \
2957 __gmp_set_expr(mp, __gmp_expr<type##_t, __gmp_binary_expr \
2958 <type##_class, bigtype, eval_fun> >(*this, t)); \
2959 return *this; \
2962 #define __GMPNS_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, type2) \
2963 __GMPNN_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, \
2964 type2, signed long int)
2966 #define __GMPNU_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, type2) \
2967 __GMPNN_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, \
2968 type2, unsigned long int)
2970 #define __GMPND_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, type2) \
2971 __GMPNN_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, type2, double)
2973 #define __GMPNLD_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, type2) \
2974 __GMPNN_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, type2, long double)
2976 #define __GMPN_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun) \
2977 __GMPNS_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, signed char) \
2978 __GMPNU_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, unsigned char) \
2979 __GMPNS_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, signed int) \
2980 __GMPNU_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, unsigned int) \
2981 __GMPNS_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, signed short int) \
2982 __GMPNU_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, unsigned short int) \
2983 __GMPNS_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, signed long int) \
2984 __GMPNU_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, unsigned long int) \
2985 __GMPND_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, float) \
2986 __GMPND_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, double) \
2987 /* __GMPNLD_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, long double) */
2989 #define __GMP_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun) \
2990 __GMPP_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun) \
2991 __GMPN_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun)
2993 #define __GMPZ_DEFINE_COMPOUND_OPERATOR(fun, eval_fun) \
2994 __GMP_DEFINE_COMPOUND_OPERATOR(mpz, fun, eval_fun)
2996 #define __GMPQ_DEFINE_COMPOUND_OPERATOR(fun, eval_fun) \
2997 __GMP_DEFINE_COMPOUND_OPERATOR(mpq, fun, eval_fun)
2999 #define __GMPF_DEFINE_COMPOUND_OPERATOR(fun, eval_fun) \
3000 __GMP_DEFINE_COMPOUND_OPERATOR(mpf, fun, eval_fun)
3004 #define __GMP_DEFINE_COMPOUND_OPERATOR_UI(type, fun, eval_fun) \
3006 inline type##_class & type##_class::fun(mp_bitcnt_t l) \
3008 __gmp_set_expr(mp, __gmp_expr<type##_t, __gmp_binary_expr \
3009 <type##_class, mp_bitcnt_t, eval_fun> >(*this, l)); \
3010 return *this; \
3013 #define __GMPZ_DEFINE_COMPOUND_OPERATOR_UI(fun, eval_fun) \
3014 __GMP_DEFINE_COMPOUND_OPERATOR_UI(mpz, fun, eval_fun)
3016 #define __GMPQ_DEFINE_COMPOUND_OPERATOR_UI(fun, eval_fun) \
3017 __GMP_DEFINE_COMPOUND_OPERATOR_UI(mpq, fun, eval_fun)
3019 #define __GMPF_DEFINE_COMPOUND_OPERATOR_UI(fun, eval_fun) \
3020 __GMP_DEFINE_COMPOUND_OPERATOR_UI(mpf, fun, eval_fun)
3024 #define __GMP_DEFINE_INCREMENT_OPERATOR(type, fun, eval_fun) \
3026 inline type##_class & type##_class::fun() \
3028 eval_fun::eval(mp); \
3029 return *this; \
3032 inline type##_class type##_class::fun(int) \
3034 type##_class temp(*this); \
3035 eval_fun::eval(mp); \
3036 return temp; \
3039 #define __GMPZ_DEFINE_INCREMENT_OPERATOR(fun, eval_fun) \
3040 __GMP_DEFINE_INCREMENT_OPERATOR(mpz, fun, eval_fun)
3042 #define __GMPQ_DEFINE_INCREMENT_OPERATOR(fun, eval_fun) \
3043 __GMP_DEFINE_INCREMENT_OPERATOR(mpq, fun, eval_fun)
3045 #define __GMPF_DEFINE_INCREMENT_OPERATOR(fun, eval_fun) \
3046 __GMP_DEFINE_INCREMENT_OPERATOR(mpf, fun, eval_fun)
3050 /**************** Arithmetic operators and functions ****************/
3052 // non-member operators and functions
3054 __GMP_DEFINE_UNARY_FUNCTION(operator+, __gmp_unary_plus)
3055 __GMP_DEFINE_UNARY_FUNCTION(operator-, __gmp_unary_minus)
3056 __GMP_DEFINE_UNARY_FUNCTION(operator~, __gmp_unary_com)
3058 __GMP_DEFINE_BINARY_FUNCTION(operator+, __gmp_binary_plus)
3059 __GMP_DEFINE_BINARY_FUNCTION(operator-, __gmp_binary_minus)
3060 __GMP_DEFINE_BINARY_FUNCTION(operator*, __gmp_binary_multiplies)
3061 __GMP_DEFINE_BINARY_FUNCTION(operator/, __gmp_binary_divides)
3062 __GMP_DEFINE_BINARY_FUNCTION(operator%, __gmp_binary_modulus)
3063 __GMP_DEFINE_BINARY_FUNCTION(operator&, __gmp_binary_and)
3064 __GMP_DEFINE_BINARY_FUNCTION(operator|, __gmp_binary_ior)
3065 __GMP_DEFINE_BINARY_FUNCTION(operator^, __gmp_binary_xor)
3067 __GMP_DEFINE_BINARY_FUNCTION_UI(operator<<, __gmp_binary_lshift)
3068 __GMP_DEFINE_BINARY_FUNCTION_UI(operator>>, __gmp_binary_rshift)
3070 __GMP_DEFINE_BINARY_TYPE_FUNCTION(bool, operator==, __gmp_binary_equal)
3071 __GMP_DEFINE_BINARY_TYPE_FUNCTION(bool, operator!=, ! __gmp_binary_equal)
3072 __GMP_DEFINE_BINARY_TYPE_FUNCTION(bool, operator<, __gmp_binary_less)
3073 __GMP_DEFINE_BINARY_TYPE_FUNCTION(bool, operator<=, ! __gmp_binary_greater)
3074 __GMP_DEFINE_BINARY_TYPE_FUNCTION(bool, operator>, __gmp_binary_greater)
3075 __GMP_DEFINE_BINARY_TYPE_FUNCTION(bool, operator>=, ! __gmp_binary_less)
3077 __GMP_DEFINE_UNARY_FUNCTION(abs, __gmp_abs_function)
3078 __GMP_DEFINE_UNARY_FUNCTION(trunc, __gmp_trunc_function)
3079 __GMP_DEFINE_UNARY_FUNCTION(floor, __gmp_floor_function)
3080 __GMP_DEFINE_UNARY_FUNCTION(ceil, __gmp_ceil_function)
3081 __GMP_DEFINE_UNARY_FUNCTION(sqrt, __gmp_sqrt_function)
3082 __GMP_DEFINE_BINARY_FUNCTION(hypot, __gmp_hypot_function)
3083 __GMP_DEFINE_BINARY_FUNCTION(gcd, __gmp_gcd_function)
3084 __GMP_DEFINE_BINARY_FUNCTION(lcm, __gmp_lcm_function)
3086 __GMP_DEFINE_UNARY_TYPE_FUNCTION(int, sgn, __gmp_sgn_function)
3087 __GMP_DEFINE_BINARY_TYPE_FUNCTION(int, cmp, __gmp_cmp_function)
3089 template <class T>
3090 void swap(__gmp_expr<T, T>& x, __gmp_expr<T, T>& y) __GMPXX_NOEXCEPT
3091 { x.swap(y); }
3093 // member operators for mpz_class
3095 __GMPZ_DEFINE_COMPOUND_OPERATOR(operator+=, __gmp_binary_plus)
3096 __GMPZ_DEFINE_COMPOUND_OPERATOR(operator-=, __gmp_binary_minus)
3097 __GMPZ_DEFINE_COMPOUND_OPERATOR(operator*=, __gmp_binary_multiplies)
3098 __GMPZ_DEFINE_COMPOUND_OPERATOR(operator/=, __gmp_binary_divides)
3099 __GMPZ_DEFINE_COMPOUND_OPERATOR(operator%=, __gmp_binary_modulus)
3101 __GMPZ_DEFINE_COMPOUND_OPERATOR(operator&=, __gmp_binary_and)
3102 __GMPZ_DEFINE_COMPOUND_OPERATOR(operator|=, __gmp_binary_ior)
3103 __GMPZ_DEFINE_COMPOUND_OPERATOR(operator^=, __gmp_binary_xor)
3105 __GMPZ_DEFINE_COMPOUND_OPERATOR_UI(operator<<=, __gmp_binary_lshift)
3106 __GMPZ_DEFINE_COMPOUND_OPERATOR_UI(operator>>=, __gmp_binary_rshift)
3108 __GMPZ_DEFINE_INCREMENT_OPERATOR(operator++, __gmp_unary_increment)
3109 __GMPZ_DEFINE_INCREMENT_OPERATOR(operator--, __gmp_unary_decrement)
3111 // member operators for mpq_class
3113 __GMPQ_DEFINE_COMPOUND_OPERATOR(operator+=, __gmp_binary_plus)
3114 __GMPQ_DEFINE_COMPOUND_OPERATOR(operator-=, __gmp_binary_minus)
3115 __GMPQ_DEFINE_COMPOUND_OPERATOR(operator*=, __gmp_binary_multiplies)
3116 __GMPQ_DEFINE_COMPOUND_OPERATOR(operator/=, __gmp_binary_divides)
3118 __GMPQ_DEFINE_COMPOUND_OPERATOR_UI(operator<<=, __gmp_binary_lshift)
3119 __GMPQ_DEFINE_COMPOUND_OPERATOR_UI(operator>>=, __gmp_binary_rshift)
3121 __GMPQ_DEFINE_INCREMENT_OPERATOR(operator++, __gmp_unary_increment)
3122 __GMPQ_DEFINE_INCREMENT_OPERATOR(operator--, __gmp_unary_decrement)
3124 // member operators for mpf_class
3126 __GMPF_DEFINE_COMPOUND_OPERATOR(operator+=, __gmp_binary_plus)
3127 __GMPF_DEFINE_COMPOUND_OPERATOR(operator-=, __gmp_binary_minus)
3128 __GMPF_DEFINE_COMPOUND_OPERATOR(operator*=, __gmp_binary_multiplies)
3129 __GMPF_DEFINE_COMPOUND_OPERATOR(operator/=, __gmp_binary_divides)
3131 __GMPF_DEFINE_COMPOUND_OPERATOR_UI(operator<<=, __gmp_binary_lshift)
3132 __GMPF_DEFINE_COMPOUND_OPERATOR_UI(operator>>=, __gmp_binary_rshift)
3134 __GMPF_DEFINE_INCREMENT_OPERATOR(operator++, __gmp_unary_increment)
3135 __GMPF_DEFINE_INCREMENT_OPERATOR(operator--, __gmp_unary_decrement)
3139 /**************** Class wrapper for gmp_randstate_t ****************/
3141 class __gmp_urandomb_value { };
3142 class __gmp_urandomm_value { };
3144 template <>
3145 class __gmp_expr<mpz_t, __gmp_urandomb_value>
3147 private:
3148 __gmp_randstate_struct *state;
3149 mp_bitcnt_t bits;
3150 public:
3151 __gmp_expr(gmp_randstate_t s, mp_bitcnt_t l) : state(s), bits(l) { }
3152 void eval(mpz_ptr z) const { __gmp_rand_function::eval(z, state, bits); }
3153 mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); }
3156 template <>
3157 class __gmp_expr<mpz_t, __gmp_urandomm_value>
3159 private:
3160 __gmp_randstate_struct *state;
3161 mpz_class range;
3162 public:
3163 __gmp_expr(gmp_randstate_t s, const mpz_class &z) : state(s), range(z) { }
3164 void eval(mpz_ptr z) const
3165 { __gmp_rand_function::eval(z, state, range.get_mpz_t()); }
3166 mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); }
3169 template <>
3170 class __gmp_expr<mpf_t, __gmp_urandomb_value>
3172 private:
3173 __gmp_randstate_struct *state;
3174 mp_bitcnt_t bits;
3175 public:
3176 __gmp_expr(gmp_randstate_t s, mp_bitcnt_t l) : state(s), bits(l) { }
3177 void eval(mpf_ptr f) const
3179 __gmp_rand_function::eval(f, state,
3180 (bits>0) ? bits : mpf_get_prec(f));
3182 mp_bitcnt_t get_prec() const
3184 if (bits == 0)
3185 return mpf_get_default_prec();
3186 else
3187 return bits;
3191 extern "C" {
3192 typedef void __gmp_randinit_default_t (gmp_randstate_t);
3193 typedef void __gmp_randinit_lc_2exp_t (gmp_randstate_t, mpz_srcptr, unsigned long int, mp_bitcnt_t);
3194 typedef int __gmp_randinit_lc_2exp_size_t (gmp_randstate_t, mp_bitcnt_t);
3197 class gmp_randclass
3199 private:
3200 gmp_randstate_t state;
3202 // copy construction and assignment not allowed
3203 gmp_randclass(const gmp_randclass &);
3204 void operator=(const gmp_randclass &);
3205 public:
3206 // constructors and destructor
3207 gmp_randclass(gmp_randalg_t alg, unsigned long int size)
3209 switch (alg)
3211 case GMP_RAND_ALG_LC: // no other cases for now
3212 default:
3213 gmp_randinit(state, alg, size);
3214 break;
3218 // gmp_randinit_default
3219 gmp_randclass(__gmp_randinit_default_t* f) { f(state); }
3221 // gmp_randinit_lc_2exp
3222 gmp_randclass(__gmp_randinit_lc_2exp_t* f,
3223 mpz_class z, unsigned long int l1, mp_bitcnt_t l2)
3224 { f(state, z.get_mpz_t(), l1, l2); }
3226 // gmp_randinit_lc_2exp_size
3227 gmp_randclass(__gmp_randinit_lc_2exp_size_t* f,
3228 mp_bitcnt_t size)
3230 if (f (state, size) == 0)
3231 throw std::length_error ("gmp_randinit_lc_2exp_size");
3234 ~gmp_randclass() { gmp_randclear(state); }
3236 // initialize
3237 void seed(); // choose a random seed some way (?)
3238 void seed(unsigned long int s) { gmp_randseed_ui(state, s); }
3239 void seed(const mpz_class &z) { gmp_randseed(state, z.get_mpz_t()); }
3241 // get random number
3242 __gmp_expr<mpz_t, __gmp_urandomb_value> get_z_bits(mp_bitcnt_t l)
3243 { return __gmp_expr<mpz_t, __gmp_urandomb_value>(state, l); }
3244 __gmp_expr<mpz_t, __gmp_urandomb_value> get_z_bits(const mpz_class &z)
3245 { return get_z_bits(z.get_ui()); }
3246 // FIXME: z.get_bitcnt_t() ?
3248 __gmp_expr<mpz_t, __gmp_urandomm_value> get_z_range(const mpz_class &z)
3249 { return __gmp_expr<mpz_t, __gmp_urandomm_value>(state, z); }
3251 __gmp_expr<mpf_t, __gmp_urandomb_value> get_f(mp_bitcnt_t prec = 0)
3252 { return __gmp_expr<mpf_t, __gmp_urandomb_value>(state, prec); }
3256 /**************** Specialize std::numeric_limits ****************/
3258 namespace std {
3259 template <> class numeric_limits<mpz_class>
3261 public:
3262 static const bool is_specialized = true;
3263 static mpz_class min() { return mpz_class(); }
3264 static mpz_class max() { return mpz_class(); }
3265 static mpz_class lowest() { return mpz_class(); }
3266 static const int digits = 0;
3267 static const int digits10 = 0;
3268 static const int max_digits10 = 0;
3269 static const bool is_signed = true;
3270 static const bool is_integer = true;
3271 static const bool is_exact = true;
3272 static const int radix = 2;
3273 static mpz_class epsilon() { return mpz_class(); }
3274 static mpz_class round_error() { return mpz_class(); }
3275 static const int min_exponent = 0;
3276 static const int min_exponent10 = 0;
3277 static const int max_exponent = 0;
3278 static const int max_exponent10 = 0;
3279 static const bool has_infinity = false;
3280 static const bool has_quiet_NaN = false;
3281 static const bool has_signaling_NaN = false;
3282 static const float_denorm_style has_denorm = denorm_absent;
3283 static const bool has_denorm_loss = false;
3284 static mpz_class infinity() { return mpz_class(); }
3285 static mpz_class quiet_NaN() { return mpz_class(); }
3286 static mpz_class signaling_NaN() { return mpz_class(); }
3287 static mpz_class denorm_min() { return mpz_class(); }
3288 static const bool is_iec559 = false;
3289 static const bool is_bounded = false;
3290 static const bool is_modulo = false;
3291 static const bool traps = false;
3292 static const bool tinyness_before = false;
3293 static const float_round_style round_style = round_toward_zero;
3296 template <> class numeric_limits<mpq_class>
3298 public:
3299 static const bool is_specialized = true;
3300 static mpq_class min() { return mpq_class(); }
3301 static mpq_class max() { return mpq_class(); }
3302 static mpq_class lowest() { return mpq_class(); }
3303 static const int digits = 0;
3304 static const int digits10 = 0;
3305 static const int max_digits10 = 0;
3306 static const bool is_signed = true;
3307 static const bool is_integer = false;
3308 static const bool is_exact = true;
3309 static const int radix = 2;
3310 static mpq_class epsilon() { return mpq_class(); }
3311 static mpq_class round_error() { return mpq_class(); }
3312 static const int min_exponent = 0;
3313 static const int min_exponent10 = 0;
3314 static const int max_exponent = 0;
3315 static const int max_exponent10 = 0;
3316 static const bool has_infinity = false;
3317 static const bool has_quiet_NaN = false;
3318 static const bool has_signaling_NaN = false;
3319 static const float_denorm_style has_denorm = denorm_absent;
3320 static const bool has_denorm_loss = false;
3321 static mpq_class infinity() { return mpq_class(); }
3322 static mpq_class quiet_NaN() { return mpq_class(); }
3323 static mpq_class signaling_NaN() { return mpq_class(); }
3324 static mpq_class denorm_min() { return mpq_class(); }
3325 static const bool is_iec559 = false;
3326 static const bool is_bounded = false;
3327 static const bool is_modulo = false;
3328 static const bool traps = false;
3329 static const bool tinyness_before = false;
3330 static const float_round_style round_style = round_toward_zero;
3333 template <> class numeric_limits<mpf_class>
3335 public:
3336 static const bool is_specialized = true;
3337 static mpf_class min() { return mpf_class(); }
3338 static mpf_class max() { return mpf_class(); }
3339 static mpf_class lowest() { return mpf_class(); }
3340 static const int digits = 0;
3341 static const int digits10 = 0;
3342 static const int max_digits10 = 0;
3343 static const bool is_signed = true;
3344 static const bool is_integer = false;
3345 static const bool is_exact = false;
3346 static const int radix = 2;
3347 static mpf_class epsilon() { return mpf_class(); }
3348 static mpf_class round_error() { return mpf_class(); }
3349 static const int min_exponent = 0;
3350 static const int min_exponent10 = 0;
3351 static const int max_exponent = 0;
3352 static const int max_exponent10 = 0;
3353 static const bool has_infinity = false;
3354 static const bool has_quiet_NaN = false;
3355 static const bool has_signaling_NaN = false;
3356 static const float_denorm_style has_denorm = denorm_absent;
3357 static const bool has_denorm_loss = false;
3358 static mpf_class infinity() { return mpf_class(); }
3359 static mpf_class quiet_NaN() { return mpf_class(); }
3360 static mpf_class signaling_NaN() { return mpf_class(); }
3361 static mpf_class denorm_min() { return mpf_class(); }
3362 static const bool is_iec559 = false;
3363 static const bool is_bounded = false;
3364 static const bool is_modulo = false;
3365 static const bool traps = false;
3366 static const bool tinyness_before = false;
3367 static const float_round_style round_style = round_indeterminate;
3372 /**************** #undef all private macros ****************/
3374 #undef __GMPP_DECLARE_COMPOUND_OPERATOR
3375 #undef __GMPN_DECLARE_COMPOUND_OPERATOR
3376 #undef __GMP_DECLARE_COMPOUND_OPERATOR
3377 #undef __GMP_DECLARE_COMPOUND_OPERATOR_UI
3378 #undef __GMP_DECLARE_INCREMENT_OPERATOR
3379 #undef __GMPXX_DEFINE_ARITHMETIC_CONSTRUCTORS
3380 #undef __GMPXX_DEFINE_ARITHMETIC_ASSIGNMENTS
3382 #undef __GMPZQ_DEFINE_EXPR
3384 #undef __GMP_DEFINE_UNARY_FUNCTION
3385 #undef __GMP_DEFINE_UNARY_TYPE_FUNCTION
3387 #undef __GMPP_DEFINE_BINARY_FUNCTION
3388 #undef __GMPNN_DEFINE_BINARY_FUNCTION
3389 #undef __GMPNS_DEFINE_BINARY_FUNCTION
3390 #undef __GMPNU_DEFINE_BINARY_FUNCTION
3391 #undef __GMPND_DEFINE_BINARY_FUNCTION
3392 #undef __GMPNLD_DEFINE_BINARY_FUNCTION
3393 #undef __GMPN_DEFINE_BINARY_FUNCTION
3394 #undef __GMP_DEFINE_BINARY_FUNCTION
3396 #undef __GMP_DEFINE_BINARY_FUNCTION_UI
3398 #undef __GMPP_DEFINE_BINARY_TYPE_FUNCTION
3399 #undef __GMPNN_DEFINE_BINARY_TYPE_FUNCTION
3400 #undef __GMPNS_DEFINE_BINARY_TYPE_FUNCTION
3401 #undef __GMPNU_DEFINE_BINARY_TYPE_FUNCTION
3402 #undef __GMPND_DEFINE_BINARY_TYPE_FUNCTION
3403 #undef __GMPNLD_DEFINE_BINARY_TYPE_FUNCTION
3404 #undef __GMPN_DEFINE_BINARY_TYPE_FUNCTION
3405 #undef __GMP_DEFINE_BINARY_TYPE_FUNCTION
3407 #undef __GMPZ_DEFINE_COMPOUND_OPERATOR
3409 #undef __GMPP_DEFINE_COMPOUND_OPERATOR
3410 #undef __GMPNN_DEFINE_COMPOUND_OPERATOR
3411 #undef __GMPNS_DEFINE_COMPOUND_OPERATOR
3412 #undef __GMPNU_DEFINE_COMPOUND_OPERATOR
3413 #undef __GMPND_DEFINE_COMPOUND_OPERATOR
3414 #undef __GMPNLD_DEFINE_COMPOUND_OPERATOR
3415 #undef __GMPN_DEFINE_COMPOUND_OPERATOR
3416 #undef __GMP_DEFINE_COMPOUND_OPERATOR
3418 #undef __GMPQ_DEFINE_COMPOUND_OPERATOR
3419 #undef __GMPF_DEFINE_COMPOUND_OPERATOR
3421 #undef __GMP_DEFINE_COMPOUND_OPERATOR_UI
3422 #undef __GMPZ_DEFINE_COMPOUND_OPERATOR_UI
3423 #undef __GMPQ_DEFINE_COMPOUND_OPERATOR_UI
3424 #undef __GMPF_DEFINE_COMPOUND_OPERATOR_UI
3426 #undef __GMP_DEFINE_INCREMENT_OPERATOR
3427 #undef __GMPZ_DEFINE_INCREMENT_OPERATOR
3428 #undef __GMPQ_DEFINE_INCREMENT_OPERATOR
3429 #undef __GMPF_DEFINE_INCREMENT_OPERATOR
3431 #undef __GMPXX_CONSTANT_TRUE
3432 #undef __GMPXX_CONSTANT
3434 #endif /* __GMP_PLUSPLUS__ */