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
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
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__
36 #include <cstring> /* for strlen */
37 #include <limits> /* numeric_limits */
39 #include <algorithm> /* swap */
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)
51 #define __GMPXX_CONSTANT(X) false
53 #define __GMPXX_CONSTANT_TRUE(X) (__GMPXX_CONSTANT(X) && (X))
56 #ifndef __GMPXX_USE_CXX11
57 #if __cplusplus >= 201103L
58 #define __GMPXX_USE_CXX11 1
60 #define __GMPXX_USE_CXX11 0
65 #define __GMPXX_NOEXCEPT noexcept
66 #include <type_traits> // for common_type
68 #define __GMPXX_NOEXCEPT
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
75 #define __GMPZ_ULI_LIMBS 1
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
92 p
->_mp_size
+= (l
!= 0);
96 inline void __mpz_set_si_safe(mpz_ptr p
, long l
)
100 __mpz_set_ui_safe(p
, -static_cast<unsigned long>(l
));
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 \
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 \
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 \
121 mp_limb_t limbs[__GMPZ_DBL_LIMBS]; \
122 temp->_mp_d = limbs; \
123 temp->_mp_alloc = __GMPZ_DBL_LIMBS; \
126 #define __GMPXX_TMPQ_UI \
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 \
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 \
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; \
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
);
198 static void eval(mpz_ptr z
, unsigned long int l
, mpz_srcptr w
)
200 static void eval(mpz_ptr z
, mpz_srcptr w
, signed long int l
)
203 eval(z
, w
, static_cast<unsigned long>(l
));
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
)
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
)
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
);
226 mpz_addmul_ui(mpq_numref(q
), mpq_denref(q
), l
);
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
)
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
)
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
)
246 static void eval(mpq_ptr q
, mpq_srcptr r
, mpz_srcptr z
)
249 mpz_addmul(mpq_numref(q
), mpq_denref(q
), z
);
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
)
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
)
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
)
276 static void eval(mpf_ptr f
, mpf_srcptr g
, double d
)
279 mpf_init2(temp
, 8*sizeof(double));
284 static void eval(mpf_ptr f
, double d
, mpf_srcptr g
)
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
);
302 static void eval(mpz_ptr z
, unsigned long int l
, mpz_srcptr w
)
304 if (__GMPXX_CONSTANT(l
) && l
== 0)
311 static void eval(mpz_ptr z
, mpz_srcptr w
, signed long int l
)
314 eval(z
, w
, static_cast<unsigned long>(l
));
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
)
321 eval(z
, static_cast<unsigned long>(l
), w
);
324 mpz_add_ui(z
, w
, -static_cast<unsigned long>(l
));
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
);
345 mpz_submul_ui(mpq_numref(q
), mpq_denref(q
), l
);
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
)
359 eval(q
, r
, static_cast<unsigned long>(l
));
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
)
373 mpz_submul(mpq_numref(q
), mpq_denref(q
), z
);
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
)
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
)
403 mpf_add_ui(f
, g
, -static_cast<unsigned long>(l
));
406 static void eval(mpf_ptr f
, mpf_srcptr g
, double d
)
409 mpf_init2(temp
, 8*sizeof(double));
414 static void eval(mpf_ptr f
, double d
, mpf_srcptr g
)
417 mpf_init2(temp
, 8*sizeof(double));
424 // defined here so it can reference __gmp_binary_minus
426 __gmp_binary_plus::eval(mpq_ptr q
, mpq_srcptr r
, signed long int l
)
429 eval(q
, r
, static_cast<unsigned long>(l
));
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
);
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
);
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
);
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
);
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)
499 __gmp_binary_lshift::eval(z
, w
, __builtin_ctzl(l
));
506 static void eval(mpz_ptr z
, unsigned long int l
, mpz_srcptr w
)
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
));
518 mpz_mul_si (z
, w
, l
);
520 static void eval(mpz_ptr z
, signed long int l
, mpz_srcptr w
)
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
)
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)
541 __gmp_binary_lshift::eval(q
, r
, __builtin_ctzl(l
));
548 mpq_mul (q
, r
, temp
);
551 static void eval(mpq_ptr q
, unsigned long int l
, mpq_srcptr r
)
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
));
565 mpq_mul (q
, r
, temp
);
568 static void eval(mpq_ptr q
, signed long int l
, mpq_srcptr r
)
570 static void eval(mpq_ptr q
, mpq_srcptr r
, double d
)
571 { __GMPXX_TMPQ_D
; mpq_mul (q
, r
, temp
); }
572 static void eval(mpq_ptr q
, double d
, mpq_srcptr r
)
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
)
588 mpf_mul_ui(f
, g
, -static_cast<unsigned long>(l
));
592 static void eval(mpf_ptr f
, signed long int l
, mpf_srcptr g
)
594 static void eval(mpf_ptr f
, mpf_srcptr g
, double d
)
597 mpf_init2(temp
, 8*sizeof(double));
602 static void eval(mpf_ptr f
, double d
, mpf_srcptr g
)
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)
619 if (z
!= w
) mpz_set(z
, w
);
622 mpz_tdiv_q_2exp(z
, w
, __builtin_ctzl(l
));
623 // warning: do not use rshift (fdiv)
627 mpz_tdiv_q_ui(z
, w
, l
);
629 static void eval(mpz_ptr z
, unsigned long int l
, mpz_srcptr w
)
633 if (mpz_fits_ulong_p(w
))
634 mpz_set_ui(z
, l
/ mpz_get_ui(w
));
641 if (mpz_fits_ulong_p(z
))
643 mpz_set_ui(z
, l
/ mpz_get_ui(z
));
650 static void eval(mpz_ptr z
, mpz_srcptr w
, signed long int l
)
653 eval(z
, w
, static_cast<unsigned long>(l
));
656 eval(z
, w
, -static_cast<unsigned long>(l
));
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
));
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
));
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
));
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
)
728 mpf_div_ui(f
, g
, -static_cast<unsigned long>(l
));
732 static void eval(mpf_ptr f
, signed long int l
, mpf_srcptr g
)
738 mpf_ui_div(f
, -static_cast<unsigned long>(l
), g
);
742 static void eval(mpf_ptr f
, mpf_srcptr g
, double d
)
745 mpf_init2(temp
, 8*sizeof(double));
750 static void eval(mpf_ptr f
, double d
, mpf_srcptr g
)
753 mpf_init2(temp
, 8*sizeof(double));
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
)
771 if (mpz_fits_ulong_p(w
))
772 mpz_set_ui(z
, l
% mpz_get_ui(w
));
779 if (mpz_fits_ulong_p(z
))
780 mpz_set_ui(z
, l
% mpz_get_ui(z
));
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
));
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
)
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
)
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
)
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
)
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
)
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
)
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
)
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
)
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
)
861 struct __gmp_binary_equal
863 static bool eval(mpz_srcptr z
, mpz_srcptr w
) { return mpz_cmp(z
, w
) == 0; }
865 static bool eval(mpz_srcptr z
, unsigned long int l
)
866 { return mpz_cmp_ui(z
, l
) == 0; }
867 static bool eval(unsigned long int l
, mpz_srcptr z
)
868 { return eval(z
, l
); }
869 static bool eval(mpz_srcptr z
, signed long int l
)
870 { return mpz_cmp_si(z
, l
) == 0; }
871 static bool eval(signed long int l
, mpz_srcptr z
)
872 { return eval(z
, l
); }
873 static bool eval(mpz_srcptr z
, double d
)
874 { return mpz_cmp_d(z
, d
) == 0; }
875 static bool eval(double d
, mpz_srcptr z
)
876 { return eval(z
, d
); }
878 static bool eval(mpq_srcptr q
, mpq_srcptr r
)
879 { return mpq_equal(q
, r
) != 0; }
881 static bool eval(mpq_srcptr q
, unsigned long int l
)
882 { return mpq_cmp_ui(q
, l
, 1) == 0; }
883 static bool eval(unsigned long int l
, mpq_srcptr q
)
884 { return eval(q
, l
); }
885 static bool eval(mpq_srcptr q
, signed long int l
)
886 { return mpq_cmp_si(q
, l
, 1) == 0; }
887 static bool eval(signed long int l
, mpq_srcptr q
)
888 { return eval(q
, l
); }
889 static bool eval(mpq_srcptr q
, double d
)
890 { __GMPXX_TMPQ_D
; return mpq_equal (q
, temp
) != 0; }
891 static bool eval(double d
, mpq_srcptr q
)
892 { return eval(q
, d
); }
894 static bool eval(mpf_srcptr f
, mpf_srcptr g
) { return mpf_cmp(f
, g
) == 0; }
896 static bool eval(mpf_srcptr f
, unsigned long int l
)
897 { return mpf_cmp_ui(f
, l
) == 0; }
898 static bool eval(unsigned long int l
, mpf_srcptr f
)
899 { return eval(f
, l
); }
900 static bool eval(mpf_srcptr f
, signed long int l
)
901 { return mpf_cmp_si(f
, l
) == 0; }
902 static bool eval(signed long int l
, mpf_srcptr f
)
903 { return eval(f
, l
); }
904 static bool eval(mpf_srcptr f
, double d
)
905 { return mpf_cmp_d(f
, d
) == 0; }
906 static bool eval(double d
, mpf_srcptr f
)
907 { return eval(f
, d
); }
910 struct __gmp_binary_less
912 static bool eval(mpz_srcptr z
, mpz_srcptr w
) { return mpz_cmp(z
, w
) < 0; }
914 static bool eval(mpz_srcptr z
, unsigned long int l
)
915 { return mpz_cmp_ui(z
, l
) < 0; }
916 static bool eval(unsigned long int l
, mpz_srcptr z
)
917 { return mpz_cmp_ui(z
, l
) > 0; }
918 static bool eval(mpz_srcptr z
, signed long int l
)
919 { return mpz_cmp_si(z
, l
) < 0; }
920 static bool eval(signed long int l
, mpz_srcptr z
)
921 { return mpz_cmp_si(z
, l
) > 0; }
922 static bool eval(mpz_srcptr z
, double d
)
923 { return mpz_cmp_d(z
, d
) < 0; }
924 static bool eval(double d
, mpz_srcptr z
)
925 { return mpz_cmp_d(z
, d
) > 0; }
927 static bool eval(mpq_srcptr q
, mpq_srcptr r
) { return mpq_cmp(q
, r
) < 0; }
929 static bool eval(mpq_srcptr q
, unsigned long int l
)
930 { return mpq_cmp_ui(q
, l
, 1) < 0; }
931 static bool eval(unsigned long int l
, mpq_srcptr q
)
932 { return mpq_cmp_ui(q
, l
, 1) > 0; }
933 static bool eval(mpq_srcptr q
, signed long int l
)
934 { return mpq_cmp_si(q
, l
, 1) < 0; }
935 static bool eval(signed long int l
, mpq_srcptr q
)
936 { return mpq_cmp_si(q
, l
, 1) > 0; }
937 static bool eval(mpq_srcptr q
, double d
)
938 { __GMPXX_TMPQ_D
; return mpq_cmp (q
, temp
) < 0; }
939 static bool eval(double d
, mpq_srcptr q
)
940 { __GMPXX_TMPQ_D
; return mpq_cmp (temp
, q
) < 0; }
942 static bool eval(mpf_srcptr f
, mpf_srcptr g
) { return mpf_cmp(f
, g
) < 0; }
944 static bool eval(mpf_srcptr f
, unsigned long int l
)
945 { return mpf_cmp_ui(f
, l
) < 0; }
946 static bool eval(unsigned long int l
, mpf_srcptr f
)
947 { return mpf_cmp_ui(f
, l
) > 0; }
948 static bool eval(mpf_srcptr f
, signed long int l
)
949 { return mpf_cmp_si(f
, l
) < 0; }
950 static bool eval(signed long int l
, mpf_srcptr f
)
951 { return mpf_cmp_si(f
, l
) > 0; }
952 static bool eval(mpf_srcptr f
, double d
)
953 { return mpf_cmp_d(f
, d
) < 0; }
954 static bool eval(double d
, mpf_srcptr f
)
955 { return mpf_cmp_d(f
, d
) > 0; }
958 struct __gmp_binary_greater
960 template <class T
, class U
>
961 static inline bool eval(T t
, U u
) { return __gmp_binary_less::eval(u
, t
); }
964 struct __gmp_unary_increment
966 static void eval(mpz_ptr z
) { mpz_add_ui(z
, z
, 1); }
967 static void eval(mpq_ptr q
)
968 { mpz_add(mpq_numref(q
), mpq_numref(q
), mpq_denref(q
)); }
969 static void eval(mpf_ptr f
) { mpf_add_ui(f
, f
, 1); }
972 struct __gmp_unary_decrement
974 static void eval(mpz_ptr z
) { mpz_sub_ui(z
, z
, 1); }
975 static void eval(mpq_ptr q
)
976 { mpz_sub(mpq_numref(q
), mpq_numref(q
), mpq_denref(q
)); }
977 static void eval(mpf_ptr f
) { mpf_sub_ui(f
, f
, 1); }
980 struct __gmp_abs_function
982 static void eval(mpz_ptr z
, mpz_srcptr w
) { mpz_abs(z
, w
); }
983 static void eval(mpq_ptr q
, mpq_srcptr r
) { mpq_abs(q
, r
); }
984 static void eval(mpf_ptr f
, mpf_srcptr g
) { mpf_abs(f
, g
); }
987 struct __gmp_trunc_function
989 static void eval(mpf_ptr f
, mpf_srcptr g
) { mpf_trunc(f
, g
); }
992 struct __gmp_floor_function
994 static void eval(mpf_ptr f
, mpf_srcptr g
) { mpf_floor(f
, g
); }
997 struct __gmp_ceil_function
999 static void eval(mpf_ptr f
, mpf_srcptr g
) { mpf_ceil(f
, g
); }
1002 struct __gmp_sqrt_function
1004 static void eval(mpz_ptr z
, mpz_srcptr w
) { mpz_sqrt(z
, w
); }
1005 static void eval(mpf_ptr f
, mpf_srcptr g
) { mpf_sqrt(f
, g
); }
1008 struct __gmp_hypot_function
1010 static void eval(mpf_ptr f
, mpf_srcptr g
, mpf_srcptr h
)
1013 mpf_init2(temp
, mpf_get_prec(f
));
1014 mpf_mul(temp
, g
, g
);
1016 mpf_add(f
, f
, temp
);
1021 static void eval(mpf_ptr f
, mpf_srcptr g
, unsigned long int l
)
1024 mpf_init2(temp
, mpf_get_prec(f
));
1025 mpf_mul(temp
, g
, g
);
1027 mpf_mul_ui(f
, f
, l
);
1028 mpf_add(f
, f
, temp
);
1032 static void eval(mpf_ptr f
, unsigned long int l
, mpf_srcptr g
)
1034 static void eval(mpf_ptr f
, mpf_srcptr g
, signed long int l
)
1035 { eval(f
, g
, __gmpxx_abs_ui(l
)); }
1036 static void eval(mpf_ptr f
, signed long int l
, mpf_srcptr g
)
1038 static void eval(mpf_ptr f
, mpf_srcptr g
, double d
)
1041 mpf_init2(temp
, mpf_get_prec(f
));
1042 mpf_mul(temp
, g
, g
);
1045 mpf_add(f
, f
, temp
);
1049 static void eval(mpf_ptr f
, double d
, mpf_srcptr g
)
1053 struct __gmp_sgn_function
1055 static int eval(mpz_srcptr z
) { return mpz_sgn(z
); }
1056 static int eval(mpq_srcptr q
) { return mpq_sgn(q
); }
1057 static int eval(mpf_srcptr f
) { return mpf_sgn(f
); }
1060 struct __gmp_cmp_function
1062 static int eval(mpz_srcptr z
, mpz_srcptr w
) { return mpz_cmp(z
, w
); }
1064 static int eval(mpz_srcptr z
, unsigned long int l
)
1065 { return mpz_cmp_ui(z
, l
); }
1066 static int eval(unsigned long int l
, mpz_srcptr z
)
1067 { return -mpz_cmp_ui(z
, l
); }
1068 static int eval(mpz_srcptr z
, signed long int l
)
1069 { return mpz_cmp_si(z
, l
); }
1070 static int eval(signed long int l
, mpz_srcptr z
)
1071 { return -mpz_cmp_si(z
, l
); }
1072 static int eval(mpz_srcptr z
, double d
)
1073 { return mpz_cmp_d(z
, d
); }
1074 static int eval(double d
, mpz_srcptr z
)
1075 { return -mpz_cmp_d(z
, d
); }
1077 static int eval(mpq_srcptr q
, mpq_srcptr r
) { return mpq_cmp(q
, r
); }
1079 static int eval(mpq_srcptr q
, unsigned long int l
)
1080 { return mpq_cmp_ui(q
, l
, 1); }
1081 static int eval(unsigned long int l
, mpq_srcptr q
)
1082 { return -mpq_cmp_ui(q
, l
, 1); }
1083 static int eval(mpq_srcptr q
, signed long int l
)
1084 { return mpq_cmp_si(q
, l
, 1); }
1085 static int eval(signed long int l
, mpq_srcptr q
)
1086 { return -mpq_cmp_si(q
, l
, 1); }
1087 static int eval(mpq_srcptr q
, double d
)
1088 { __GMPXX_TMPQ_D
; return mpq_cmp (q
, temp
); }
1089 static int eval(double d
, mpq_srcptr q
)
1090 { __GMPXX_TMPQ_D
; return mpq_cmp (temp
, q
); }
1092 static int eval(mpf_srcptr f
, mpf_srcptr g
) { return mpf_cmp(f
, g
); }
1094 static int eval(mpf_srcptr f
, unsigned long int l
)
1095 { return mpf_cmp_ui(f
, l
); }
1096 static int eval(unsigned long int l
, mpf_srcptr f
)
1097 { return -mpf_cmp_ui(f
, l
); }
1098 static int eval(mpf_srcptr f
, signed long int l
)
1099 { return mpf_cmp_si(f
, l
); }
1100 static int eval(signed long int l
, mpf_srcptr f
)
1101 { return -mpf_cmp_si(f
, l
); }
1102 static int eval(mpf_srcptr f
, double d
)
1103 { return mpf_cmp_d(f
, d
); }
1104 static int eval(double d
, mpf_srcptr f
)
1105 { return -mpf_cmp_d(f
, d
); }
1108 struct __gmp_rand_function
1110 static void eval(mpz_ptr z
, gmp_randstate_t s
, mp_bitcnt_t l
)
1111 { mpz_urandomb(z
, s
, l
); }
1112 static void eval(mpz_ptr z
, gmp_randstate_t s
, mpz_srcptr w
)
1113 { mpz_urandomm(z
, s
, w
); }
1114 static void eval(mpf_ptr f
, gmp_randstate_t s
, mp_bitcnt_t prec
)
1115 { mpf_urandomb(f
, s
, prec
); }
1119 /**************** Auxiliary classes ****************/
1121 /* this is much the same as gmp_allocated_string in gmp-impl.h
1122 since gmp-impl.h is not publicly available, I redefine it here
1123 I use a different name to avoid possible clashes */
1126 typedef void (*__gmp_freefunc_t
) (void *, size_t);
1128 struct __gmp_alloc_cstring
1131 __gmp_alloc_cstring(char *s
) { str
= s
; }
1132 ~__gmp_alloc_cstring()
1134 __gmp_freefunc_t freefunc
;
1135 mp_get_memory_functions (NULL
, NULL
, &freefunc
);
1136 (*freefunc
) (str
, std::strlen(str
)+1);
1141 // general expression template class
1142 template <class T
, class U
>
1146 // templates for resolving expression types
1148 struct __gmp_resolve_ref
1153 template <class T
, class U
>
1154 struct __gmp_resolve_ref
<__gmp_expr
<T
, U
> >
1156 typedef const __gmp_expr
<T
, U
> & ref_type
;
1160 template <class T
, class U
= T
>
1161 struct __gmp_resolve_expr
;
1164 struct __gmp_resolve_expr
<mpz_t
>
1166 typedef mpz_t value_type
;
1167 typedef mpz_ptr ptr_type
;
1168 typedef mpz_srcptr srcptr_type
;
1172 struct __gmp_resolve_expr
<mpq_t
>
1174 typedef mpq_t value_type
;
1175 typedef mpq_ptr ptr_type
;
1176 typedef mpq_srcptr srcptr_type
;
1180 struct __gmp_resolve_expr
<mpf_t
>
1182 typedef mpf_t value_type
;
1183 typedef mpf_ptr ptr_type
;
1184 typedef mpf_srcptr srcptr_type
;
1188 struct __gmp_resolve_expr
<mpz_t
, mpq_t
>
1190 typedef mpq_t value_type
;
1194 struct __gmp_resolve_expr
<mpq_t
, mpz_t
>
1196 typedef mpq_t value_type
;
1200 struct __gmp_resolve_expr
<mpz_t
, mpf_t
>
1202 typedef mpf_t value_type
;
1206 struct __gmp_resolve_expr
<mpf_t
, mpz_t
>
1208 typedef mpf_t value_type
;
1212 struct __gmp_resolve_expr
<mpq_t
, mpf_t
>
1214 typedef mpf_t value_type
;
1218 struct __gmp_resolve_expr
<mpf_t
, mpq_t
>
1220 typedef mpf_t value_type
;
1223 #if __GMPXX_USE_CXX11
1225 template <class T
, class U
, class V
, class W
>
1226 struct common_type
<__gmp_expr
<T
, U
>, __gmp_expr
<V
, W
> >
1229 typedef typename __gmp_resolve_expr
<T
, V
>::value_type X
;
1231 typedef __gmp_expr
<X
, X
> type
;
1234 template <class T
, class U
>
1235 struct common_type
<__gmp_expr
<T
, U
>, __gmp_expr
<T
, U
> >
1237 typedef __gmp_expr
<T
, U
> type
;
1240 #define __GMPXX_DECLARE_COMMON_TYPE(typ) \
1241 template <class T, class U> \
1242 struct common_type <__gmp_expr<T, U>, typ > \
1244 typedef __gmp_expr<T, T> type; \
1247 template <class T, class U> \
1248 struct common_type <typ, __gmp_expr<T, U> > \
1250 typedef __gmp_expr<T, T> type; \
1253 __GMPXX_DECLARE_COMMON_TYPE(signed char);
1254 __GMPXX_DECLARE_COMMON_TYPE(unsigned char);
1255 __GMPXX_DECLARE_COMMON_TYPE(signed int);
1256 __GMPXX_DECLARE_COMMON_TYPE(unsigned int);
1257 __GMPXX_DECLARE_COMMON_TYPE(signed short int);
1258 __GMPXX_DECLARE_COMMON_TYPE(unsigned short int);
1259 __GMPXX_DECLARE_COMMON_TYPE(signed long int);
1260 __GMPXX_DECLARE_COMMON_TYPE(unsigned long int);
1261 __GMPXX_DECLARE_COMMON_TYPE(float);
1262 __GMPXX_DECLARE_COMMON_TYPE(double);
1263 #undef __GMPXX_DECLARE_COMMON_TYPE
1267 // classes for evaluating unary and binary expressions
1268 template <class T
, class Op
>
1269 struct __gmp_unary_expr
1273 __gmp_unary_expr(const T
&v
) : val(v
) { }
1278 template <class T
, class U
, class Op
>
1279 struct __gmp_binary_expr
1281 typename __gmp_resolve_ref
<T
>::ref_type val1
;
1282 typename __gmp_resolve_ref
<U
>::ref_type val2
;
1284 __gmp_binary_expr(const T
&v1
, const U
&v2
) : val1(v1
), val2(v2
) { }
1286 __gmp_binary_expr();
1291 /**************** Macros for in-class declarations ****************/
1292 /* This is just repetitive code that is easier to maintain if it's written
1295 #define __GMPP_DECLARE_COMPOUND_OPERATOR(fun) \
1296 template <class T, class U> \
1297 __gmp_expr<value_type, value_type> & fun(const __gmp_expr<T, U> &);
1299 #define __GMPN_DECLARE_COMPOUND_OPERATOR(fun) \
1300 __gmp_expr & fun(signed char); \
1301 __gmp_expr & fun(unsigned char); \
1302 __gmp_expr & fun(signed int); \
1303 __gmp_expr & fun(unsigned int); \
1304 __gmp_expr & fun(signed short int); \
1305 __gmp_expr & fun(unsigned short int); \
1306 __gmp_expr & fun(signed long int); \
1307 __gmp_expr & fun(unsigned long int); \
1308 __gmp_expr & fun(float); \
1309 __gmp_expr & fun(double); \
1310 /* __gmp_expr & fun(long double); */
1312 #define __GMP_DECLARE_COMPOUND_OPERATOR(fun) \
1313 __GMPP_DECLARE_COMPOUND_OPERATOR(fun) \
1314 __GMPN_DECLARE_COMPOUND_OPERATOR(fun)
1316 #define __GMP_DECLARE_COMPOUND_OPERATOR_UI(fun) \
1317 __gmp_expr & fun(mp_bitcnt_t);
1319 #define __GMP_DECLARE_INCREMENT_OPERATOR(fun) \
1320 inline __gmp_expr & fun(); \
1321 inline __gmp_expr fun(int);
1323 #define __GMPXX_DEFINE_ARITHMETIC_CONSTRUCTORS \
1324 __gmp_expr(signed char c) { init_si(c); } \
1325 __gmp_expr(unsigned char c) { init_ui(c); } \
1326 __gmp_expr(signed int i) { init_si(i); } \
1327 __gmp_expr(unsigned int i) { init_ui(i); } \
1328 __gmp_expr(signed short int s) { init_si(s); } \
1329 __gmp_expr(unsigned short int s) { init_ui(s); } \
1330 __gmp_expr(signed long int l) { init_si(l); } \
1331 __gmp_expr(unsigned long int l) { init_ui(l); } \
1332 __gmp_expr(float f) { init_d(f); } \
1333 __gmp_expr(double d) { init_d(d); }
1335 #define __GMPXX_DEFINE_ARITHMETIC_ASSIGNMENTS \
1336 __gmp_expr & operator=(signed char c) { assign_si(c); return *this; } \
1337 __gmp_expr & operator=(unsigned char c) { assign_ui(c); return *this; } \
1338 __gmp_expr & operator=(signed int i) { assign_si(i); return *this; } \
1339 __gmp_expr & operator=(unsigned int i) { assign_ui(i); return *this; } \
1340 __gmp_expr & operator=(signed short int s) { assign_si(s); return *this; } \
1341 __gmp_expr & operator=(unsigned short int s) { assign_ui(s); return *this; } \
1342 __gmp_expr & operator=(signed long int l) { assign_si(l); return *this; } \
1343 __gmp_expr & operator=(unsigned long int l) { assign_ui(l); return *this; } \
1344 __gmp_expr & operator=(float f) { assign_d(f); return *this; } \
1345 __gmp_expr & operator=(double d) { assign_d(d); return *this; }
1347 /**************** mpz_class -- wrapper for mpz_t ****************/
1350 class __gmp_expr
<mpz_t
, mpz_t
>
1353 typedef mpz_t value_type
;
1356 // Helper functions used for all arithmetic types
1357 void assign_ui(unsigned long l
)
1359 if (__GMPXX_CONSTANT_TRUE(l
== 0))
1364 void assign_si(signed long l
)
1366 if (__GMPXX_CONSTANT_TRUE(l
>= 0))
1368 else if (__GMPXX_CONSTANT_TRUE(l
<= 0))
1370 assign_ui(-static_cast<unsigned long>(l
));
1376 void assign_d (double d
)
1381 void init_ui(unsigned long l
)
1383 if (__GMPXX_CONSTANT_TRUE(l
== 0))
1386 mpz_init_set_ui(mp
, l
);
1388 void init_si(signed long l
)
1390 if (__GMPXX_CONSTANT_TRUE(l
>= 0))
1392 else if (__GMPXX_CONSTANT_TRUE(l
<= 0))
1394 init_ui(-static_cast<unsigned long>(l
));
1398 mpz_init_set_si(mp
, l
);
1400 void init_d (double d
)
1402 mpz_init_set_d (mp
, d
);
1406 mp_bitcnt_t
get_prec() const { return mpf_get_default_prec(); }
1408 // constructors and destructor
1409 __gmp_expr() { mpz_init(mp
); }
1411 __gmp_expr(const __gmp_expr
&z
) { mpz_init_set(mp
, z
.mp
); }
1412 #if __GMPXX_USE_CXX11
1413 __gmp_expr(__gmp_expr
&&z
)
1414 { *mp
= *z
.mp
; mpz_init(z
.mp
); }
1417 __gmp_expr(const __gmp_expr
<mpz_t
, T
> &expr
)
1418 { mpz_init(mp
); __gmp_set_expr(mp
, expr
); }
1419 template <class T
, class U
>
1420 explicit __gmp_expr(const __gmp_expr
<T
, U
> &expr
)
1421 { mpz_init(mp
); __gmp_set_expr(mp
, expr
); }
1423 __GMPXX_DEFINE_ARITHMETIC_CONSTRUCTORS
1425 explicit __gmp_expr(const char *s
, int base
= 0)
1427 if (mpz_init_set_str (mp
, s
, base
) != 0)
1430 throw std::invalid_argument ("mpz_set_str");
1433 explicit __gmp_expr(const std::string
&s
, int base
= 0)
1435 if (mpz_init_set_str(mp
, s
.c_str(), base
) != 0)
1438 throw std::invalid_argument ("mpz_set_str");
1442 explicit __gmp_expr(mpz_srcptr z
) { mpz_init_set(mp
, z
); }
1444 ~__gmp_expr() { mpz_clear(mp
); }
1446 void swap(__gmp_expr
& z
) __GMPXX_NOEXCEPT
{ std::swap(*mp
, *z
.mp
); }
1448 // assignment operators
1449 __gmp_expr
& operator=(const __gmp_expr
&z
)
1450 { mpz_set(mp
, z
.mp
); return *this; }
1451 #if __GMPXX_USE_CXX11
1452 __gmp_expr
& operator=(__gmp_expr
&&z
) noexcept
1453 { swap(z
); return *this; }
1455 template <class T
, class U
>
1456 __gmp_expr
<value_type
, value_type
> & operator=(const __gmp_expr
<T
, U
> &expr
)
1457 { __gmp_set_expr(mp
, expr
); return *this; }
1459 __GMPXX_DEFINE_ARITHMETIC_ASSIGNMENTS
1461 __gmp_expr
& operator=(const char *s
)
1463 if (mpz_set_str (mp
, s
, 0) != 0)
1464 throw std::invalid_argument ("mpz_set_str");
1467 __gmp_expr
& operator=(const std::string
&s
)
1469 if (mpz_set_str(mp
, s
.c_str(), 0) != 0)
1470 throw std::invalid_argument ("mpz_set_str");
1474 // string input/output functions
1475 int set_str(const char *s
, int base
)
1476 { return mpz_set_str(mp
, s
, base
); }
1477 int set_str(const std::string
&s
, int base
)
1478 { return mpz_set_str(mp
, s
.c_str(), base
); }
1479 std::string
get_str(int base
= 10) const
1481 __gmp_alloc_cstring
temp(mpz_get_str(0, base
, mp
));
1482 return std::string(temp
.str
);
1485 // conversion functions
1486 mpz_srcptr
__get_mp() const { return mp
; }
1487 mpz_ptr
__get_mp() { return mp
; }
1488 mpz_srcptr
get_mpz_t() const { return mp
; }
1489 mpz_ptr
get_mpz_t() { return mp
; }
1491 signed long int get_si() const { return mpz_get_si(mp
); }
1492 unsigned long int get_ui() const { return mpz_get_ui(mp
); }
1493 double get_d() const { return mpz_get_d(mp
); }
1495 // bool fits_schar_p() const { return mpz_fits_schar_p(mp); }
1496 // bool fits_uchar_p() const { return mpz_fits_uchar_p(mp); }
1497 bool fits_sint_p() const { return mpz_fits_sint_p(mp
); }
1498 bool fits_uint_p() const { return mpz_fits_uint_p(mp
); }
1499 bool fits_sshort_p() const { return mpz_fits_sshort_p(mp
); }
1500 bool fits_ushort_p() const { return mpz_fits_ushort_p(mp
); }
1501 bool fits_slong_p() const { return mpz_fits_slong_p(mp
); }
1502 bool fits_ulong_p() const { return mpz_fits_ulong_p(mp
); }
1503 // bool fits_float_p() const { return mpz_fits_float_p(mp); }
1504 // bool fits_double_p() const { return mpz_fits_double_p(mp); }
1505 // bool fits_ldouble_p() const { return mpz_fits_ldouble_p(mp); }
1507 #if __GMPXX_USE_CXX11
1508 explicit operator bool() const { return mp
->_mp_size
!= 0; }
1512 __GMP_DECLARE_COMPOUND_OPERATOR(operator+=)
1513 __GMP_DECLARE_COMPOUND_OPERATOR(operator-=)
1514 __GMP_DECLARE_COMPOUND_OPERATOR(operator*=)
1515 __GMP_DECLARE_COMPOUND_OPERATOR(operator/=)
1516 __GMP_DECLARE_COMPOUND_OPERATOR(operator%=)
1518 __GMP_DECLARE_COMPOUND_OPERATOR(operator&=)
1519 __GMP_DECLARE_COMPOUND_OPERATOR(operator|=)
1520 __GMP_DECLARE_COMPOUND_OPERATOR(operator^=)
1522 __GMP_DECLARE_COMPOUND_OPERATOR_UI(operator<<=)
1523 __GMP_DECLARE_COMPOUND_OPERATOR_UI(operator>>=)
1525 __GMP_DECLARE_INCREMENT_OPERATOR(operator++)
1526 __GMP_DECLARE_INCREMENT_OPERATOR(operator--)
1529 typedef __gmp_expr
<mpz_t
, mpz_t
> mpz_class
;
1532 /**************** mpq_class -- wrapper for mpq_t ****************/
1535 class __gmp_expr
<mpq_t
, mpq_t
>
1538 typedef mpq_t value_type
;
1541 // Helper functions used for all arithmetic types
1542 void assign_ui(unsigned long l
) { mpq_set_ui(mp
, l
, 1); }
1543 void assign_si(signed long l
)
1545 if (__GMPXX_CONSTANT_TRUE(l
>= 0))
1548 mpq_set_si(mp
, l
, 1);
1550 void assign_d (double d
) { mpq_set_d (mp
, d
); }
1552 void init_ui(unsigned long l
) { mpq_init(mp
); get_num() = l
; }
1553 void init_si(signed long l
) { mpq_init(mp
); get_num() = l
; }
1554 void init_d (double d
) { mpq_init(mp
); assign_d (d
); }
1557 mp_bitcnt_t
get_prec() const { return mpf_get_default_prec(); }
1558 void canonicalize() { mpq_canonicalize(mp
); }
1560 // constructors and destructor
1561 __gmp_expr() { mpq_init(mp
); }
1563 __gmp_expr(const __gmp_expr
&q
)
1565 mpz_init_set(mpq_numref(mp
), mpq_numref(q
.mp
));
1566 mpz_init_set(mpq_denref(mp
), mpq_denref(q
.mp
));
1568 #if __GMPXX_USE_CXX11
1569 __gmp_expr(__gmp_expr
&&q
)
1570 { *mp
= *q
.mp
; mpq_init(q
.mp
); }
1573 __gmp_expr(const __gmp_expr
<mpz_t
, T
> &expr
)
1574 { mpq_init(mp
); __gmp_set_expr(mp
, expr
); }
1576 __gmp_expr(const __gmp_expr
<mpq_t
, T
> &expr
)
1577 { mpq_init(mp
); __gmp_set_expr(mp
, expr
); }
1578 template <class T
, class U
>
1579 explicit __gmp_expr(const __gmp_expr
<T
, U
> &expr
)
1580 { mpq_init(mp
); __gmp_set_expr(mp
, expr
); }
1582 __GMPXX_DEFINE_ARITHMETIC_CONSTRUCTORS
1584 explicit __gmp_expr(const char *s
, int base
= 0)
1587 // If s is the literal 0, we meant to call another constructor.
1588 // If s just happens to evaluate to 0, we would crash, so whatever.
1591 // Don't turn mpq_class(0,0) into 0
1592 mpz_set_si(mpq_denref(mp
), base
);
1594 else if (mpq_set_str(mp
, s
, base
) != 0)
1597 throw std::invalid_argument ("mpq_set_str");
1600 explicit __gmp_expr(const std::string
&s
, int base
= 0)
1603 if (mpq_set_str (mp
, s
.c_str(), base
) != 0)
1606 throw std::invalid_argument ("mpq_set_str");
1609 explicit __gmp_expr(mpq_srcptr q
)
1611 mpz_init_set(mpq_numref(mp
), mpq_numref(q
));
1612 mpz_init_set(mpq_denref(mp
), mpq_denref(q
));
1615 __gmp_expr(const mpz_class
&num
, const mpz_class
&den
)
1617 mpz_init_set(mpq_numref(mp
), num
.get_mpz_t());
1618 mpz_init_set(mpq_denref(mp
), den
.get_mpz_t());
1621 ~__gmp_expr() { mpq_clear(mp
); }
1623 void swap(__gmp_expr
& q
) __GMPXX_NOEXCEPT
{ std::swap(*mp
, *q
.mp
); }
1625 // assignment operators
1626 __gmp_expr
& operator=(const __gmp_expr
&q
)
1627 { mpq_set(mp
, q
.mp
); return *this; }
1628 #if __GMPXX_USE_CXX11
1629 __gmp_expr
& operator=(__gmp_expr
&&q
) noexcept
1630 { swap(q
); return *this; }
1631 __gmp_expr
& operator=(mpz_class
&&z
) noexcept
1632 { get_num() = std::move(z
); get_den() = 1u; return *this; }
1634 template <class T
, class U
>
1635 __gmp_expr
<value_type
, value_type
> & operator=(const __gmp_expr
<T
, U
> &expr
)
1636 { __gmp_set_expr(mp
, expr
); return *this; }
1638 __GMPXX_DEFINE_ARITHMETIC_ASSIGNMENTS
1640 __gmp_expr
& operator=(const char *s
)
1642 if (mpq_set_str (mp
, s
, 0) != 0)
1643 throw std::invalid_argument ("mpq_set_str");
1646 __gmp_expr
& operator=(const std::string
&s
)
1648 if (mpq_set_str(mp
, s
.c_str(), 0) != 0)
1649 throw std::invalid_argument ("mpq_set_str");
1653 // string input/output functions
1654 int set_str(const char *s
, int base
)
1655 { return mpq_set_str(mp
, s
, base
); }
1656 int set_str(const std::string
&s
, int base
)
1657 { return mpq_set_str(mp
, s
.c_str(), base
); }
1658 std::string
get_str(int base
= 10) const
1660 __gmp_alloc_cstring
temp(mpq_get_str(0, base
, mp
));
1661 return std::string(temp
.str
);
1664 // conversion functions
1666 // casting a reference to an mpz_t to mpz_class & is a dirty hack,
1667 // but works because the internal representation of mpz_class is
1669 const mpz_class
& get_num() const
1670 { return reinterpret_cast<const mpz_class
&>(*mpq_numref(mp
)); }
1671 mpz_class
& get_num()
1672 { return reinterpret_cast<mpz_class
&>(*mpq_numref(mp
)); }
1673 const mpz_class
& get_den() const
1674 { return reinterpret_cast<const mpz_class
&>(*mpq_denref(mp
)); }
1675 mpz_class
& get_den()
1676 { return reinterpret_cast<mpz_class
&>(*mpq_denref(mp
)); }
1678 mpq_srcptr
__get_mp() const { return mp
; }
1679 mpq_ptr
__get_mp() { return mp
; }
1680 mpq_srcptr
get_mpq_t() const { return mp
; }
1681 mpq_ptr
get_mpq_t() { return mp
; }
1683 mpz_srcptr
get_num_mpz_t() const { return mpq_numref(mp
); }
1684 mpz_ptr
get_num_mpz_t() { return mpq_numref(mp
); }
1685 mpz_srcptr
get_den_mpz_t() const { return mpq_denref(mp
); }
1686 mpz_ptr
get_den_mpz_t() { return mpq_denref(mp
); }
1688 double get_d() const { return mpq_get_d(mp
); }
1690 #if __GMPXX_USE_CXX11
1691 explicit operator bool() const { return mpq_numref(mp
)->_mp_size
!= 0; }
1694 // compound assignments
1695 __GMP_DECLARE_COMPOUND_OPERATOR(operator+=)
1696 __GMP_DECLARE_COMPOUND_OPERATOR(operator-=)
1697 __GMP_DECLARE_COMPOUND_OPERATOR(operator*=)
1698 __GMP_DECLARE_COMPOUND_OPERATOR(operator/=)
1700 __GMP_DECLARE_COMPOUND_OPERATOR_UI(operator<<=)
1701 __GMP_DECLARE_COMPOUND_OPERATOR_UI(operator>>=)
1703 __GMP_DECLARE_INCREMENT_OPERATOR(operator++)
1704 __GMP_DECLARE_INCREMENT_OPERATOR(operator--)
1707 typedef __gmp_expr
<mpq_t
, mpq_t
> mpq_class
;
1710 /**************** mpf_class -- wrapper for mpf_t ****************/
1713 class __gmp_expr
<mpf_t
, mpf_t
>
1716 typedef mpf_t value_type
;
1719 // Helper functions used for all arithmetic types
1720 void assign_ui(unsigned long l
) { mpf_set_ui(mp
, l
); }
1721 void assign_si(signed long l
)
1723 if (__GMPXX_CONSTANT_TRUE(l
>= 0))
1728 void assign_d (double d
) { mpf_set_d (mp
, d
); }
1730 void init_ui(unsigned long l
)
1732 if (__GMPXX_CONSTANT_TRUE(l
== 0))
1735 mpf_init_set_ui(mp
, l
);
1737 void init_si(signed long l
)
1739 if (__GMPXX_CONSTANT_TRUE(l
>= 0))
1742 mpf_init_set_si(mp
, l
);
1744 void init_d (double d
) { mpf_init_set_d (mp
, d
); }
1747 mp_bitcnt_t
get_prec() const { return mpf_get_prec(mp
); }
1749 void set_prec(mp_bitcnt_t prec
) { mpf_set_prec(mp
, prec
); }
1750 void set_prec_raw(mp_bitcnt_t prec
) { mpf_set_prec_raw(mp
, prec
); }
1752 // constructors and destructor
1753 __gmp_expr() { mpf_init(mp
); }
1755 __gmp_expr(const __gmp_expr
&f
)
1756 { mpf_init2(mp
, f
.get_prec()); mpf_set(mp
, f
.mp
); }
1757 #if __GMPXX_USE_CXX11
1758 __gmp_expr(__gmp_expr
&&f
)
1759 { *mp
= *f
.mp
; mpf_init2(f
.mp
, get_prec()); }
1761 __gmp_expr(const __gmp_expr
&f
, mp_bitcnt_t prec
)
1762 { mpf_init2(mp
, prec
); mpf_set(mp
, f
.mp
); }
1763 template <class T
, class U
>
1764 __gmp_expr(const __gmp_expr
<T
, U
> &expr
)
1765 { mpf_init2(mp
, expr
.get_prec()); __gmp_set_expr(mp
, expr
); }
1766 template <class T
, class U
>
1767 __gmp_expr(const __gmp_expr
<T
, U
> &expr
, mp_bitcnt_t prec
)
1768 { mpf_init2(mp
, prec
); __gmp_set_expr(mp
, expr
); }
1770 __GMPXX_DEFINE_ARITHMETIC_CONSTRUCTORS
1772 __gmp_expr(signed char c
, mp_bitcnt_t prec
)
1773 { mpf_init2(mp
, prec
); mpf_set_si(mp
, c
); }
1774 __gmp_expr(unsigned char c
, mp_bitcnt_t prec
)
1775 { mpf_init2(mp
, prec
); mpf_set_ui(mp
, c
); }
1777 __gmp_expr(signed int i
, mp_bitcnt_t prec
)
1778 { mpf_init2(mp
, prec
); mpf_set_si(mp
, i
); }
1779 __gmp_expr(unsigned int i
, mp_bitcnt_t prec
)
1780 { mpf_init2(mp
, prec
); mpf_set_ui(mp
, i
); }
1782 __gmp_expr(signed short int s
, mp_bitcnt_t prec
)
1783 { mpf_init2(mp
, prec
); mpf_set_si(mp
, s
); }
1784 __gmp_expr(unsigned short int s
, mp_bitcnt_t prec
)
1785 { mpf_init2(mp
, prec
); mpf_set_ui(mp
, s
); }
1787 __gmp_expr(signed long int l
, mp_bitcnt_t prec
)
1788 { mpf_init2(mp
, prec
); mpf_set_si(mp
, l
); }
1789 __gmp_expr(unsigned long int l
, mp_bitcnt_t prec
)
1790 { mpf_init2(mp
, prec
); mpf_set_ui(mp
, l
); }
1792 __gmp_expr(float f
, mp_bitcnt_t prec
)
1793 { mpf_init2(mp
, prec
); mpf_set_d(mp
, f
); }
1794 __gmp_expr(double d
, mp_bitcnt_t prec
)
1795 { mpf_init2(mp
, prec
); mpf_set_d(mp
, d
); }
1796 // __gmp_expr(long double ld) { mpf_init_set_d(mp, ld); }
1797 // __gmp_expr(long double ld, mp_bitcnt_t prec)
1798 // { mpf_init2(mp, prec); mpf_set_d(mp, ld); }
1800 explicit __gmp_expr(const char *s
)
1802 if (mpf_init_set_str (mp
, s
, 0) != 0)
1805 throw std::invalid_argument ("mpf_set_str");
1808 __gmp_expr(const char *s
, mp_bitcnt_t prec
, int base
= 0)
1810 mpf_init2(mp
, prec
);
1811 if (mpf_set_str(mp
, s
, base
) != 0)
1814 throw std::invalid_argument ("mpf_set_str");
1817 explicit __gmp_expr(const std::string
&s
)
1819 if (mpf_init_set_str(mp
, s
.c_str(), 0) != 0)
1822 throw std::invalid_argument ("mpf_set_str");
1825 __gmp_expr(const std::string
&s
, mp_bitcnt_t prec
, int base
= 0)
1827 mpf_init2(mp
, prec
);
1828 if (mpf_set_str(mp
, s
.c_str(), base
) != 0)
1831 throw std::invalid_argument ("mpf_set_str");
1835 explicit __gmp_expr(mpf_srcptr f
)
1836 { mpf_init2(mp
, mpf_get_prec(f
)); mpf_set(mp
, f
); }
1837 __gmp_expr(mpf_srcptr f
, mp_bitcnt_t prec
)
1838 { mpf_init2(mp
, prec
); mpf_set(mp
, f
); }
1840 ~__gmp_expr() { mpf_clear(mp
); }
1842 void swap(__gmp_expr
& f
) __GMPXX_NOEXCEPT
{ std::swap(*mp
, *f
.mp
); }
1844 // assignment operators
1845 __gmp_expr
& operator=(const __gmp_expr
&f
)
1846 { mpf_set(mp
, f
.mp
); return *this; }
1847 #if __GMPXX_USE_CXX11
1848 __gmp_expr
& operator=(__gmp_expr
&&f
) noexcept
1849 { swap(f
); return *this; }
1851 template <class T
, class U
>
1852 __gmp_expr
<value_type
, value_type
> & operator=(const __gmp_expr
<T
, U
> &expr
)
1853 { __gmp_set_expr(mp
, expr
); return *this; }
1855 __GMPXX_DEFINE_ARITHMETIC_ASSIGNMENTS
1857 __gmp_expr
& operator=(const char *s
)
1859 if (mpf_set_str (mp
, s
, 0) != 0)
1860 throw std::invalid_argument ("mpf_set_str");
1863 __gmp_expr
& operator=(const std::string
&s
)
1865 if (mpf_set_str(mp
, s
.c_str(), 0) != 0)
1866 throw std::invalid_argument ("mpf_set_str");
1870 // string input/output functions
1871 int set_str(const char *s
, int base
)
1872 { return mpf_set_str(mp
, s
, base
); }
1873 int set_str(const std::string
&s
, int base
)
1874 { return mpf_set_str(mp
, s
.c_str(), base
); }
1875 std::string
get_str(mp_exp_t
&expo
, int base
= 10, size_t size
= 0) const
1877 __gmp_alloc_cstring
temp(mpf_get_str(0, &expo
, base
, size
, mp
));
1878 return std::string(temp
.str
);
1881 // conversion functions
1882 mpf_srcptr
__get_mp() const { return mp
; }
1883 mpf_ptr
__get_mp() { return mp
; }
1884 mpf_srcptr
get_mpf_t() const { return mp
; }
1885 mpf_ptr
get_mpf_t() { return mp
; }
1887 signed long int get_si() const { return mpf_get_si(mp
); }
1888 unsigned long int get_ui() const { return mpf_get_ui(mp
); }
1889 double get_d() const { return mpf_get_d(mp
); }
1891 // bool fits_schar_p() const { return mpf_fits_schar_p(mp); }
1892 // bool fits_uchar_p() const { return mpf_fits_uchar_p(mp); }
1893 bool fits_sint_p() const { return mpf_fits_sint_p(mp
); }
1894 bool fits_uint_p() const { return mpf_fits_uint_p(mp
); }
1895 bool fits_sshort_p() const { return mpf_fits_sshort_p(mp
); }
1896 bool fits_ushort_p() const { return mpf_fits_ushort_p(mp
); }
1897 bool fits_slong_p() const { return mpf_fits_slong_p(mp
); }
1898 bool fits_ulong_p() const { return mpf_fits_ulong_p(mp
); }
1899 // bool fits_float_p() const { return mpf_fits_float_p(mp); }
1900 // bool fits_double_p() const { return mpf_fits_double_p(mp); }
1901 // bool fits_ldouble_p() const { return mpf_fits_ldouble_p(mp); }
1903 #if __GMPXX_USE_CXX11
1904 explicit operator bool() const { return mp
->_mp_size
!= 0; }
1907 // compound assignments
1908 __GMP_DECLARE_COMPOUND_OPERATOR(operator+=)
1909 __GMP_DECLARE_COMPOUND_OPERATOR(operator-=)
1910 __GMP_DECLARE_COMPOUND_OPERATOR(operator*=)
1911 __GMP_DECLARE_COMPOUND_OPERATOR(operator/=)
1913 __GMP_DECLARE_COMPOUND_OPERATOR_UI(operator<<=)
1914 __GMP_DECLARE_COMPOUND_OPERATOR_UI(operator>>=)
1916 __GMP_DECLARE_INCREMENT_OPERATOR(operator++)
1917 __GMP_DECLARE_INCREMENT_OPERATOR(operator--)
1920 typedef __gmp_expr
<mpf_t
, mpf_t
> mpf_class
;
1924 /**************** User-defined literals ****************/
1926 #if __GMPXX_USE_CXX11
1927 inline mpz_class
operator"" _mpz(const char* s
)
1929 return mpz_class(s
);
1932 inline mpq_class
operator"" _mpq(const char* s
)
1939 inline mpf_class
operator"" _mpf(const char* s
)
1941 return mpf_class(s
);
1945 /**************** I/O operators ****************/
1947 // these should (and will) be provided separately
1949 template <class T
, class U
>
1950 inline std::ostream
& operator<<
1951 (std::ostream
&o
, const __gmp_expr
<T
, U
> &expr
)
1953 __gmp_expr
<T
, T
> const& temp(expr
);
1954 return o
<< temp
.__get_mp();
1958 inline std::istream
& operator>>(std::istream
&i
, __gmp_expr
<T
, T
> &expr
)
1960 return i
>> expr
.__get_mp();
1964 // you might want to uncomment this
1965 inline std::istream & operator>>(std::istream &i, mpq_class &q)
1974 /**************** Functions for type conversion ****************/
1976 inline void __gmp_set_expr(mpz_ptr z
, const mpz_class
&w
)
1978 mpz_set(z
, w
.get_mpz_t());
1982 inline void __gmp_set_expr(mpz_ptr z
, const __gmp_expr
<mpz_t
, T
> &expr
)
1988 inline void __gmp_set_expr(mpz_ptr z
, const __gmp_expr
<mpq_t
, T
> &expr
)
1990 mpq_class
const& temp(expr
);
1991 mpz_set_q(z
, temp
.get_mpq_t());
1995 inline void __gmp_set_expr(mpz_ptr z
, const __gmp_expr
<mpf_t
, T
> &expr
)
1997 mpf_class
const& temp(expr
);
1998 mpz_set_f(z
, temp
.get_mpf_t());
2001 inline void __gmp_set_expr(mpq_ptr q
, const mpz_class
&z
)
2003 mpq_set_z(q
, z
.get_mpz_t());
2007 inline void __gmp_set_expr(mpq_ptr q
, const __gmp_expr
<mpz_t
, T
> &expr
)
2009 __gmp_set_expr(mpq_numref(q
), expr
);
2010 mpz_set_ui(mpq_denref(q
), 1);
2013 inline void __gmp_set_expr(mpq_ptr q
, const mpq_class
&r
)
2015 mpq_set(q
, r
.get_mpq_t());
2019 inline void __gmp_set_expr(mpq_ptr q
, const __gmp_expr
<mpq_t
, T
> &expr
)
2025 inline void __gmp_set_expr(mpq_ptr q
, const __gmp_expr
<mpf_t
, T
> &expr
)
2027 mpf_class
const& temp(expr
);
2028 mpq_set_f(q
, temp
.get_mpf_t());
2032 inline void __gmp_set_expr(mpf_ptr f
, const __gmp_expr
<mpz_t
, T
> &expr
)
2034 mpz_class
const& temp(expr
);
2035 mpf_set_z(f
, temp
.get_mpz_t());
2039 inline void __gmp_set_expr(mpf_ptr f
, const __gmp_expr
<mpq_t
, T
> &expr
)
2041 mpq_class
const& temp(expr
);
2042 mpf_set_q(f
, temp
.get_mpq_t());
2045 inline void __gmp_set_expr(mpf_ptr f
, const mpf_class
&g
)
2047 mpf_set(f
, g
.get_mpf_t());
2051 inline void __gmp_set_expr(mpf_ptr f
, const __gmp_expr
<mpf_t
, T
> &expr
)
2057 /* Temporary objects */
2062 __gmp_expr
<T
, T
> val
;
2064 template<class U
, class V
>
2065 __gmp_temp(U
const& u
, V
) : val (u
) {}
2066 typename __gmp_resolve_expr
<T
>::srcptr_type
2067 __get_mp() const { return val
.__get_mp(); }
2071 class __gmp_temp
<mpf_t
>
2076 __gmp_temp(U
const& u
, mpf_ptr res
) : val (u
, mpf_get_prec(res
)) {}
2077 mpf_srcptr
__get_mp() const { return val
.__get_mp(); }
2080 /**************** Specializations of __gmp_expr ****************/
2081 /* The eval() method of __gmp_expr<T, U> evaluates the corresponding
2082 expression and assigns the result to its argument, which is either an
2083 mpz_t, mpq_t, or mpf_t as specified by the T argument.
2084 Compound expressions are evaluated recursively (temporaries are created
2085 to hold intermediate values), while for simple expressions the eval()
2086 method of the appropriate function object (available as the Op argument
2087 of either __gmp_unary_expr<T, Op> or __gmp_binary_expr<T, U, Op>) is
2091 /**************** Unary expressions ****************/
2093 - simple: argument is mp*_class, that is, __gmp_expr<T, T>
2094 - compound: argument is __gmp_expr<T, U> (with U not equal to T) */
2097 // simple expressions
2099 template <class T
, class Op
>
2100 class __gmp_expr
<T
, __gmp_unary_expr
<__gmp_expr
<T
, T
>, Op
> >
2103 typedef __gmp_expr
<T
, T
> val_type
;
2105 __gmp_unary_expr
<val_type
, Op
> expr
;
2107 explicit __gmp_expr(const val_type
&val
) : expr(val
) { }
2108 void eval(typename __gmp_resolve_expr
<T
>::ptr_type p
) const
2109 { Op::eval(p
, expr
.val
.__get_mp()); }
2110 const val_type
& get_val() const { return expr
.val
; }
2111 mp_bitcnt_t
get_prec() const { return expr
.val
.get_prec(); }
2115 // compound expressions
2117 template <class T
, class U
, class Op
>
2118 class __gmp_expr
<T
, __gmp_unary_expr
<__gmp_expr
<T
, U
>, Op
> >
2121 typedef __gmp_expr
<T
, U
> val_type
;
2123 __gmp_unary_expr
<val_type
, Op
> expr
;
2125 explicit __gmp_expr(const val_type
&val
) : expr(val
) { }
2126 void eval(typename __gmp_resolve_expr
<T
>::ptr_type p
) const
2127 { expr
.val
.eval(p
); Op::eval(p
, p
); }
2128 const val_type
& get_val() const { return expr
.val
; }
2129 mp_bitcnt_t
get_prec() const { return expr
.val
.get_prec(); }
2133 /**************** Binary expressions ****************/
2135 - arguments are both mp*_class
2136 - one argument is mp*_class, one is a built-in type
2138 - one is mp*_class, one is __gmp_expr<T, U>
2139 - one is __gmp_expr<T, U>, one is built-in
2140 - both arguments are __gmp_expr<...> */
2143 // simple expressions
2145 template <class T
, class Op
>
2147 <T
, __gmp_binary_expr
<__gmp_expr
<T
, T
>, __gmp_expr
<T
, T
>, Op
> >
2150 typedef __gmp_expr
<T
, T
> val1_type
;
2151 typedef __gmp_expr
<T
, T
> val2_type
;
2153 __gmp_binary_expr
<val1_type
, val2_type
, Op
> expr
;
2155 __gmp_expr(const val1_type
&val1
, const val2_type
&val2
)
2156 : expr(val1
, val2
) { }
2157 void eval(typename __gmp_resolve_expr
<T
>::ptr_type p
) const
2158 { Op::eval(p
, expr
.val1
.__get_mp(), expr
.val2
.__get_mp()); }
2159 const val1_type
& get_val1() const { return expr
.val1
; }
2160 const val2_type
& get_val2() const { return expr
.val2
; }
2161 mp_bitcnt_t
get_prec() const
2163 mp_bitcnt_t prec1
= expr
.val1
.get_prec(),
2164 prec2
= expr
.val2
.get_prec();
2165 return (prec1
> prec2
) ? prec1
: prec2
;
2170 // simple expressions, T is a built-in numerical type
2172 template <class T
, class U
, class Op
>
2173 class __gmp_expr
<T
, __gmp_binary_expr
<__gmp_expr
<T
, T
>, U
, Op
> >
2176 typedef __gmp_expr
<T
, T
> val1_type
;
2177 typedef U val2_type
;
2179 __gmp_binary_expr
<val1_type
, val2_type
, Op
> expr
;
2181 __gmp_expr(const val1_type
&val1
, const val2_type
&val2
)
2182 : expr(val1
, val2
) { }
2183 void eval(typename __gmp_resolve_expr
<T
>::ptr_type p
) const
2184 { Op::eval(p
, expr
.val1
.__get_mp(), expr
.val2
); }
2185 const val1_type
& get_val1() const { return expr
.val1
; }
2186 const val2_type
& get_val2() const { return expr
.val2
; }
2187 mp_bitcnt_t
get_prec() const { return expr
.val1
.get_prec(); }
2190 template <class T
, class U
, class Op
>
2191 class __gmp_expr
<T
, __gmp_binary_expr
<U
, __gmp_expr
<T
, T
>, Op
> >
2194 typedef U val1_type
;
2195 typedef __gmp_expr
<T
, T
> val2_type
;
2197 __gmp_binary_expr
<val1_type
, val2_type
, Op
> expr
;
2199 __gmp_expr(const val1_type
&val1
, const val2_type
&val2
)
2200 : expr(val1
, val2
) { }
2201 void eval(typename __gmp_resolve_expr
<T
>::ptr_type p
) const
2202 { Op::eval(p
, expr
.val1
, expr
.val2
.__get_mp()); }
2203 const val1_type
& get_val1() const { return expr
.val1
; }
2204 const val2_type
& get_val2() const { return expr
.val2
; }
2205 mp_bitcnt_t
get_prec() const { return expr
.val2
.get_prec(); }
2209 // compound expressions, one argument is a subexpression
2211 template <class T
, class U
, class V
, class Op
>
2213 <T
, __gmp_binary_expr
<__gmp_expr
<T
, T
>, __gmp_expr
<U
, V
>, Op
> >
2216 typedef __gmp_expr
<T
, T
> val1_type
;
2217 typedef __gmp_expr
<U
, V
> val2_type
;
2219 __gmp_binary_expr
<val1_type
, val2_type
, Op
> expr
;
2221 __gmp_expr(const val1_type
&val1
, const val2_type
&val2
)
2222 : expr(val1
, val2
) { }
2223 void eval(typename __gmp_resolve_expr
<T
>::ptr_type p
) const
2225 if(p
!= expr
.val1
.__get_mp())
2227 __gmp_set_expr(p
, expr
.val2
);
2228 Op::eval(p
, expr
.val1
.__get_mp(), p
);
2232 __gmp_temp
<T
> temp(expr
.val2
, p
);
2233 Op::eval(p
, expr
.val1
.__get_mp(), temp
.__get_mp());
2236 const val1_type
& get_val1() const { return expr
.val1
; }
2237 const val2_type
& get_val2() const { return expr
.val2
; }
2238 mp_bitcnt_t
get_prec() const
2240 mp_bitcnt_t prec1
= expr
.val1
.get_prec(),
2241 prec2
= expr
.val2
.get_prec();
2242 return (prec1
> prec2
) ? prec1
: prec2
;
2246 template <class T
, class U
, class V
, class Op
>
2248 <T
, __gmp_binary_expr
<__gmp_expr
<U
, V
>, __gmp_expr
<T
, T
>, Op
> >
2251 typedef __gmp_expr
<U
, V
> val1_type
;
2252 typedef __gmp_expr
<T
, T
> val2_type
;
2254 __gmp_binary_expr
<val1_type
, val2_type
, Op
> expr
;
2256 __gmp_expr(const val1_type
&val1
, const val2_type
&val2
)
2257 : expr(val1
, val2
) { }
2258 void eval(typename __gmp_resolve_expr
<T
>::ptr_type p
) const
2260 if(p
!= expr
.val2
.__get_mp())
2262 __gmp_set_expr(p
, expr
.val1
);
2263 Op::eval(p
, p
, expr
.val2
.__get_mp());
2267 __gmp_temp
<T
> temp(expr
.val1
, p
);
2268 Op::eval(p
, temp
.__get_mp(), expr
.val2
.__get_mp());
2271 const val1_type
& get_val1() const { return expr
.val1
; }
2272 const val2_type
& get_val2() const { return expr
.val2
; }
2273 mp_bitcnt_t
get_prec() const
2275 mp_bitcnt_t prec1
= expr
.val1
.get_prec(),
2276 prec2
= expr
.val2
.get_prec();
2277 return (prec1
> prec2
) ? prec1
: prec2
;
2281 template <class T
, class U
, class Op
>
2283 <T
, __gmp_binary_expr
<__gmp_expr
<T
, T
>, __gmp_expr
<T
, U
>, Op
> >
2286 typedef __gmp_expr
<T
, T
> val1_type
;
2287 typedef __gmp_expr
<T
, U
> val2_type
;
2289 __gmp_binary_expr
<val1_type
, val2_type
, Op
> expr
;
2291 __gmp_expr(const val1_type
&val1
, const val2_type
&val2
)
2292 : expr(val1
, val2
) { }
2293 void eval(typename __gmp_resolve_expr
<T
>::ptr_type p
) const
2295 if(p
!= expr
.val1
.__get_mp())
2297 __gmp_set_expr(p
, expr
.val2
);
2298 Op::eval(p
, expr
.val1
.__get_mp(), p
);
2302 __gmp_temp
<T
> temp(expr
.val2
, p
);
2303 Op::eval(p
, expr
.val1
.__get_mp(), temp
.__get_mp());
2306 const val1_type
& get_val1() const { return expr
.val1
; }
2307 const val2_type
& get_val2() const { return expr
.val2
; }
2308 mp_bitcnt_t
get_prec() const
2310 mp_bitcnt_t prec1
= expr
.val1
.get_prec(),
2311 prec2
= expr
.val2
.get_prec();
2312 return (prec1
> prec2
) ? prec1
: prec2
;
2316 template <class T
, class U
, class Op
>
2318 <T
, __gmp_binary_expr
<__gmp_expr
<T
, U
>, __gmp_expr
<T
, T
>, Op
> >
2321 typedef __gmp_expr
<T
, U
> val1_type
;
2322 typedef __gmp_expr
<T
, T
> val2_type
;
2324 __gmp_binary_expr
<val1_type
, val2_type
, Op
> expr
;
2326 __gmp_expr(const val1_type
&val1
, const val2_type
&val2
)
2327 : expr(val1
, val2
) { }
2328 void eval(typename __gmp_resolve_expr
<T
>::ptr_type p
) const
2330 if(p
!= expr
.val2
.__get_mp())
2332 __gmp_set_expr(p
, expr
.val1
);
2333 Op::eval(p
, p
, expr
.val2
.__get_mp());
2337 __gmp_temp
<T
> temp(expr
.val1
, p
);
2338 Op::eval(p
, temp
.__get_mp(), expr
.val2
.__get_mp());
2341 const val1_type
& get_val1() const { return expr
.val1
; }
2342 const val2_type
& get_val2() const { return expr
.val2
; }
2343 mp_bitcnt_t
get_prec() const
2345 mp_bitcnt_t prec1
= expr
.val1
.get_prec(),
2346 prec2
= expr
.val2
.get_prec();
2347 return (prec1
> prec2
) ? prec1
: prec2
;
2352 // one argument is a subexpression, one is a built-in
2354 template <class T
, class U
, class V
, class Op
>
2355 class __gmp_expr
<T
, __gmp_binary_expr
<__gmp_expr
<T
, U
>, V
, Op
> >
2358 typedef __gmp_expr
<T
, U
> val1_type
;
2359 typedef V val2_type
;
2361 __gmp_binary_expr
<val1_type
, val2_type
, Op
> expr
;
2363 __gmp_expr(const val1_type
&val1
, const val2_type
&val2
)
2364 : expr(val1
, val2
) { }
2365 void eval(typename __gmp_resolve_expr
<T
>::ptr_type p
) const
2368 Op::eval(p
, p
, expr
.val2
);
2370 const val1_type
& get_val1() const { return expr
.val1
; }
2371 const val2_type
& get_val2() const { return expr
.val2
; }
2372 mp_bitcnt_t
get_prec() const { return expr
.val1
.get_prec(); }
2375 template <class T
, class U
, class V
, class Op
>
2376 class __gmp_expr
<T
, __gmp_binary_expr
<U
, __gmp_expr
<T
, V
>, Op
> >
2379 typedef U val1_type
;
2380 typedef __gmp_expr
<T
, V
> val2_type
;
2382 __gmp_binary_expr
<val1_type
, val2_type
, Op
> expr
;
2384 __gmp_expr(const val1_type
&val1
, const val2_type
&val2
)
2385 : expr(val1
, val2
) { }
2386 void eval(typename __gmp_resolve_expr
<T
>::ptr_type p
) const
2389 Op::eval(p
, expr
.val1
, p
);
2391 const val1_type
& get_val1() const { return expr
.val1
; }
2392 const val2_type
& get_val2() const { return expr
.val2
; }
2393 mp_bitcnt_t
get_prec() const { return expr
.val2
.get_prec(); }
2397 // both arguments are subexpressions
2399 template <class T
, class U
, class V
, class W
, class Op
>
2401 <T
, __gmp_binary_expr
<__gmp_expr
<T
, U
>, __gmp_expr
<V
, W
>, Op
> >
2404 typedef __gmp_expr
<T
, U
> val1_type
;
2405 typedef __gmp_expr
<V
, W
> val2_type
;
2407 __gmp_binary_expr
<val1_type
, val2_type
, Op
> expr
;
2409 __gmp_expr(const val1_type
&val1
, const val2_type
&val2
)
2410 : expr(val1
, val2
) { }
2411 void eval(typename __gmp_resolve_expr
<T
>::ptr_type p
) const
2413 __gmp_temp
<T
> temp2(expr
.val2
, p
);
2415 Op::eval(p
, p
, temp2
.__get_mp());
2417 const val1_type
& get_val1() const { return expr
.val1
; }
2418 const val2_type
& get_val2() const { return expr
.val2
; }
2419 mp_bitcnt_t
get_prec() const
2421 mp_bitcnt_t prec1
= expr
.val1
.get_prec(),
2422 prec2
= expr
.val2
.get_prec();
2423 return (prec1
> prec2
) ? prec1
: prec2
;
2427 template <class T
, class U
, class V
, class W
, class Op
>
2429 <T
, __gmp_binary_expr
<__gmp_expr
<U
, V
>, __gmp_expr
<T
, W
>, Op
> >
2432 typedef __gmp_expr
<U
, V
> val1_type
;
2433 typedef __gmp_expr
<T
, W
> val2_type
;
2435 __gmp_binary_expr
<val1_type
, val2_type
, Op
> expr
;
2437 __gmp_expr(const val1_type
&val1
, const val2_type
&val2
)
2438 : expr(val1
, val2
) { }
2439 void eval(typename __gmp_resolve_expr
<T
>::ptr_type p
) const
2441 __gmp_temp
<T
> temp1(expr
.val1
, p
);
2443 Op::eval(p
, temp1
.__get_mp(), p
);
2445 const val1_type
& get_val1() const { return expr
.val1
; }
2446 const val2_type
& get_val2() const { return expr
.val2
; }
2447 mp_bitcnt_t
get_prec() const
2449 mp_bitcnt_t prec1
= expr
.val1
.get_prec(),
2450 prec2
= expr
.val2
.get_prec();
2451 return (prec1
> prec2
) ? prec1
: prec2
;
2455 template <class T
, class U
, class V
, class Op
>
2457 <T
, __gmp_binary_expr
<__gmp_expr
<T
, U
>, __gmp_expr
<T
, V
>, Op
> >
2460 typedef __gmp_expr
<T
, U
> val1_type
;
2461 typedef __gmp_expr
<T
, V
> val2_type
;
2463 __gmp_binary_expr
<val1_type
, val2_type
, Op
> expr
;
2465 __gmp_expr(const val1_type
&val1
, const val2_type
&val2
)
2466 : expr(val1
, val2
) { }
2467 void eval(typename __gmp_resolve_expr
<T
>::ptr_type p
) const
2469 __gmp_temp
<T
> temp2(expr
.val2
, p
);
2471 Op::eval(p
, p
, temp2
.__get_mp());
2473 const val1_type
& get_val1() const { return expr
.val1
; }
2474 const val2_type
& get_val2() const { return expr
.val2
; }
2475 mp_bitcnt_t
get_prec() const
2477 mp_bitcnt_t prec1
= expr
.val1
.get_prec(),
2478 prec2
= expr
.val2
.get_prec();
2479 return (prec1
> prec2
) ? prec1
: prec2
;
2484 /**************** Special cases ****************/
2486 /* Some operations (i.e., add and subtract) with mixed mpz/mpq arguments
2487 can be done directly without first converting the mpz to mpq.
2488 Appropriate specializations of __gmp_expr are required. */
2491 #define __GMPZQ_DEFINE_EXPR(eval_fun) \
2494 class __gmp_expr<mpq_t, __gmp_binary_expr<mpz_class, mpq_class, eval_fun> > \
2497 typedef mpz_class val1_type; \
2498 typedef mpq_class val2_type; \
2500 __gmp_binary_expr<val1_type, val2_type, eval_fun> expr; \
2502 __gmp_expr(const val1_type &val1, const val2_type &val2) \
2503 : expr(val1, val2) { } \
2504 void eval(mpq_ptr q) const \
2505 { eval_fun::eval(q, expr.val1.get_mpz_t(), expr.val2.get_mpq_t()); } \
2506 const val1_type & get_val1() const { return expr.val1; } \
2507 const val2_type & get_val2() const { return expr.val2; } \
2508 mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); } \
2512 class __gmp_expr<mpq_t, __gmp_binary_expr<mpq_class, mpz_class, eval_fun> > \
2515 typedef mpq_class val1_type; \
2516 typedef mpz_class val2_type; \
2518 __gmp_binary_expr<val1_type, val2_type, eval_fun> expr; \
2520 __gmp_expr(const val1_type &val1, const val2_type &val2) \
2521 : expr(val1, val2) { } \
2522 void eval(mpq_ptr q) const \
2523 { eval_fun::eval(q, expr.val1.get_mpq_t(), expr.val2.get_mpz_t()); } \
2524 const val1_type & get_val1() const { return expr.val1; } \
2525 const val2_type & get_val2() const { return expr.val2; } \
2526 mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); } \
2529 template <class T> \
2531 <mpq_t, __gmp_binary_expr<mpz_class, __gmp_expr<mpq_t, T>, eval_fun> > \
2534 typedef mpz_class val1_type; \
2535 typedef __gmp_expr<mpq_t, T> val2_type; \
2537 __gmp_binary_expr<val1_type, val2_type, eval_fun> expr; \
2539 __gmp_expr(const val1_type &val1, const val2_type &val2) \
2540 : expr(val1, val2) { } \
2541 void eval(mpq_ptr q) const \
2543 mpq_class temp(expr.val2); \
2544 eval_fun::eval(q, expr.val1.get_mpz_t(), temp.get_mpq_t()); \
2546 const val1_type & get_val1() const { return expr.val1; } \
2547 const val2_type & get_val2() const { return expr.val2; } \
2548 mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); } \
2551 template <class T> \
2553 <mpq_t, __gmp_binary_expr<mpq_class, __gmp_expr<mpz_t, T>, eval_fun> > \
2556 typedef mpq_class val1_type; \
2557 typedef __gmp_expr<mpz_t, T> val2_type; \
2559 __gmp_binary_expr<val1_type, val2_type, eval_fun> expr; \
2561 __gmp_expr(const val1_type &val1, const val2_type &val2) \
2562 : expr(val1, val2) { } \
2563 void eval(mpq_ptr q) const \
2565 mpz_class temp(expr.val2); \
2566 eval_fun::eval(q, expr.val1.get_mpq_t(), temp.get_mpz_t()); \
2568 const val1_type & get_val1() const { return expr.val1; } \
2569 const val2_type & get_val2() const { return expr.val2; } \
2570 mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); } \
2573 template <class T> \
2575 <mpq_t, __gmp_binary_expr<__gmp_expr<mpz_t, T>, mpq_class, eval_fun> > \
2578 typedef __gmp_expr<mpz_t, T> val1_type; \
2579 typedef mpq_class val2_type; \
2581 __gmp_binary_expr<val1_type, val2_type, eval_fun> expr; \
2583 __gmp_expr(const val1_type &val1, const val2_type &val2) \
2584 : expr(val1, val2) { } \
2585 void eval(mpq_ptr q) const \
2587 mpz_class temp(expr.val1); \
2588 eval_fun::eval(q, temp.get_mpz_t(), expr.val2.get_mpq_t()); \
2590 const val1_type & get_val1() const { return expr.val1; } \
2591 const val2_type & get_val2() const { return expr.val2; } \
2592 mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); } \
2595 template <class T> \
2597 <mpq_t, __gmp_binary_expr<__gmp_expr<mpq_t, T>, mpz_class, eval_fun> > \
2600 typedef __gmp_expr<mpq_t, T> val1_type; \
2601 typedef mpz_class val2_type; \
2603 __gmp_binary_expr<val1_type, val2_type, eval_fun> expr; \
2605 __gmp_expr(const val1_type &val1, const val2_type &val2) \
2606 : expr(val1, val2) { } \
2607 void eval(mpq_ptr q) const \
2609 mpq_class temp(expr.val1); \
2610 eval_fun::eval(q, temp.get_mpq_t(), expr.val2.get_mpz_t()); \
2612 const val1_type & get_val1() const { return expr.val1; } \
2613 const val2_type & get_val2() const { return expr.val2; } \
2614 mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); } \
2617 template <class T, class U> \
2618 class __gmp_expr<mpq_t, __gmp_binary_expr \
2619 <__gmp_expr<mpz_t, T>, __gmp_expr<mpq_t, U>, eval_fun> > \
2622 typedef __gmp_expr<mpz_t, T> val1_type; \
2623 typedef __gmp_expr<mpq_t, U> val2_type; \
2625 __gmp_binary_expr<val1_type, val2_type, eval_fun> expr; \
2627 __gmp_expr(const val1_type &val1, const val2_type &val2) \
2628 : expr(val1, val2) { } \
2629 void eval(mpq_ptr q) const \
2631 mpz_class temp1(expr.val1); \
2632 expr.val2.eval(q); \
2633 eval_fun::eval(q, temp1.get_mpz_t(), q); \
2635 const val1_type & get_val1() const { return expr.val1; } \
2636 const val2_type & get_val2() const { return expr.val2; } \
2637 mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); } \
2640 template <class T, class U> \
2641 class __gmp_expr<mpq_t, __gmp_binary_expr \
2642 <__gmp_expr<mpq_t, T>, __gmp_expr<mpz_t, U>, eval_fun> > \
2645 typedef __gmp_expr<mpq_t, T> val1_type; \
2646 typedef __gmp_expr<mpz_t, U> val2_type; \
2648 __gmp_binary_expr<val1_type, val2_type, eval_fun> expr; \
2650 __gmp_expr(const val1_type &val1, const val2_type &val2) \
2651 : expr(val1, val2) { } \
2652 void eval(mpq_ptr q) const \
2654 mpz_class temp2(expr.val2); \
2655 expr.val1.eval(q); \
2656 eval_fun::eval(q, q, temp2.get_mpz_t()); \
2658 const val1_type & get_val1() const { return expr.val1; } \
2659 const val2_type & get_val2() const { return expr.val2; } \
2660 mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); } \
2664 __GMPZQ_DEFINE_EXPR(__gmp_binary_plus
)
2665 __GMPZQ_DEFINE_EXPR(__gmp_binary_minus
)
2669 /**************** Macros for defining functions ****************/
2670 /* Results of operators and functions are instances of __gmp_expr<T, U>.
2671 T determines the numerical type of the expression: it can be either
2672 mpz_t, mpq_t, or mpf_t. When the arguments of a binary
2673 expression have different numerical types, __gmp_resolve_expr is used
2674 to determine the "larger" type.
2675 U is either __gmp_unary_expr<V, Op> or __gmp_binary_expr<V, W, Op>,
2676 where V and W are the arguments' types -- they can in turn be
2677 expressions, thus allowing to build compound expressions to any
2678 degree of complexity.
2679 Op is a function object that must have an eval() method accepting
2680 appropriate arguments.
2681 Actual evaluation of a __gmp_expr<T, U> object is done when it gets
2682 assigned to an mp*_class ("lazy" evaluation): this is done by calling
2683 its eval() method. */
2686 // non-member unary operators and functions
2688 #define __GMP_DEFINE_UNARY_FUNCTION(fun, eval_fun) \
2690 template <class T, class U> \
2691 inline __gmp_expr<T, __gmp_unary_expr<__gmp_expr<T, U>, eval_fun> > \
2692 fun(const __gmp_expr<T, U> &expr) \
2694 return __gmp_expr<T, __gmp_unary_expr<__gmp_expr<T, U>, eval_fun> >(expr); \
2697 #define __GMP_DEFINE_UNARY_TYPE_FUNCTION(type, fun, eval_fun) \
2699 template <class T, class U> \
2700 inline type fun(const __gmp_expr<T, U> &expr) \
2702 __gmp_expr<T, T> const& temp(expr); \
2703 return eval_fun::eval(temp.__get_mp()); \
2707 // non-member binary operators and functions
2709 #define __GMPP_DEFINE_BINARY_FUNCTION(fun, eval_fun) \
2711 template <class T, class U, class V, class W> \
2712 inline __gmp_expr<typename __gmp_resolve_expr<T, V>::value_type, \
2713 __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<V, W>, eval_fun> > \
2714 fun(const __gmp_expr<T, U> &expr1, const __gmp_expr<V, W> &expr2) \
2716 return __gmp_expr<typename __gmp_resolve_expr<T, V>::value_type, \
2717 __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<V, W>, eval_fun> > \
2721 #define __GMPNN_DEFINE_BINARY_FUNCTION(fun, eval_fun, type, bigtype) \
2723 template <class T, class U> \
2725 <T, __gmp_binary_expr<__gmp_expr<T, U>, bigtype, eval_fun> > \
2726 fun(const __gmp_expr<T, U> &expr, type t) \
2729 <T, __gmp_binary_expr<__gmp_expr<T, U>, bigtype, eval_fun> >(expr, t); \
2732 template <class T, class U> \
2734 <T, __gmp_binary_expr<bigtype, __gmp_expr<T, U>, eval_fun> > \
2735 fun(type t, const __gmp_expr<T, U> &expr) \
2738 <T, __gmp_binary_expr<bigtype, __gmp_expr<T, U>, eval_fun> >(t, expr); \
2741 #define __GMPNS_DEFINE_BINARY_FUNCTION(fun, eval_fun, type) \
2742 __GMPNN_DEFINE_BINARY_FUNCTION(fun, eval_fun, type, signed long int)
2744 #define __GMPNU_DEFINE_BINARY_FUNCTION(fun, eval_fun, type) \
2745 __GMPNN_DEFINE_BINARY_FUNCTION(fun, eval_fun, type, unsigned long int)
2747 #define __GMPND_DEFINE_BINARY_FUNCTION(fun, eval_fun, type) \
2748 __GMPNN_DEFINE_BINARY_FUNCTION(fun, eval_fun, type, double)
2750 #define __GMPNLD_DEFINE_BINARY_FUNCTION(fun, eval_fun, type) \
2751 __GMPNN_DEFINE_BINARY_FUNCTION(fun, eval_fun, type, long double)
2753 #define __GMPN_DEFINE_BINARY_FUNCTION(fun, eval_fun) \
2754 __GMPNS_DEFINE_BINARY_FUNCTION(fun, eval_fun, signed char) \
2755 __GMPNU_DEFINE_BINARY_FUNCTION(fun, eval_fun, unsigned char) \
2756 __GMPNS_DEFINE_BINARY_FUNCTION(fun, eval_fun, signed int) \
2757 __GMPNU_DEFINE_BINARY_FUNCTION(fun, eval_fun, unsigned int) \
2758 __GMPNS_DEFINE_BINARY_FUNCTION(fun, eval_fun, signed short int) \
2759 __GMPNU_DEFINE_BINARY_FUNCTION(fun, eval_fun, unsigned short int) \
2760 __GMPNS_DEFINE_BINARY_FUNCTION(fun, eval_fun, signed long int) \
2761 __GMPNU_DEFINE_BINARY_FUNCTION(fun, eval_fun, unsigned long int) \
2762 __GMPND_DEFINE_BINARY_FUNCTION(fun, eval_fun, float) \
2763 __GMPND_DEFINE_BINARY_FUNCTION(fun, eval_fun, double) \
2764 /* __GMPNLD_DEFINE_BINARY_FUNCTION(fun, eval_fun, long double) */
2766 #define __GMP_DEFINE_BINARY_FUNCTION(fun, eval_fun) \
2767 __GMPP_DEFINE_BINARY_FUNCTION(fun, eval_fun) \
2768 __GMPN_DEFINE_BINARY_FUNCTION(fun, eval_fun)
2771 #define __GMP_DEFINE_BINARY_FUNCTION_UI(fun, eval_fun) \
2773 template <class T, class U> \
2775 <T, __gmp_binary_expr<__gmp_expr<T, U>, mp_bitcnt_t, eval_fun> > \
2776 fun(const __gmp_expr<T, U> &expr, mp_bitcnt_t l) \
2778 return __gmp_expr<T, __gmp_binary_expr \
2779 <__gmp_expr<T, U>, mp_bitcnt_t, eval_fun> >(expr, l); \
2783 #define __GMPP_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun) \
2785 template <class T, class U, class V, class W> \
2786 inline type fun(const __gmp_expr<T, U> &expr1, \
2787 const __gmp_expr<V, W> &expr2) \
2789 typedef typename __gmp_resolve_expr<T, V>::value_type eval_type; \
2790 __gmp_expr<eval_type, eval_type> const& temp1(expr1); \
2791 __gmp_expr<eval_type, eval_type> const& temp2(expr2); \
2792 return eval_fun::eval(temp1.__get_mp(), temp2.__get_mp()); \
2795 #define __GMPNN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, \
2798 template <class T, class U> \
2799 inline type fun(const __gmp_expr<T, U> &expr, type2 t) \
2801 __gmp_expr<T, T> const& temp(expr); \
2802 return eval_fun::eval(temp.__get_mp(), static_cast<bigtype>(t)); \
2805 template <class T, class U> \
2806 inline type fun(type2 t, const __gmp_expr<T, U> &expr) \
2808 __gmp_expr<T, T> const& temp(expr); \
2809 return eval_fun::eval(static_cast<bigtype>(t), temp.__get_mp()); \
2812 #define __GMPNS_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, type2) \
2813 __GMPNN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, \
2814 type2, signed long int)
2816 #define __GMPNU_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, type2) \
2817 __GMPNN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, \
2818 type2, unsigned long int)
2820 #define __GMPND_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, type2) \
2821 __GMPNN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, type2, double)
2823 #define __GMPNLD_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, type2) \
2824 __GMPNN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, type2, long double)
2826 #define __GMPN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun) \
2827 __GMPNS_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, signed char) \
2828 __GMPNU_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, unsigned char) \
2829 __GMPNS_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, signed int) \
2830 __GMPNU_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, unsigned int) \
2831 __GMPNS_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, signed short int) \
2832 __GMPNU_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, unsigned short int) \
2833 __GMPNS_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, signed long int) \
2834 __GMPNU_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, unsigned long int) \
2835 __GMPND_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, float) \
2836 __GMPND_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, double) \
2837 /* __GMPNLD_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, long double) */
2839 #define __GMP_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun) \
2840 __GMPP_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun) \
2841 __GMPN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun)
2846 #define __GMPP_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun) \
2848 template <class T, class U> \
2849 inline type##_class & type##_class::fun(const __gmp_expr<T, U> &expr) \
2851 __gmp_set_expr(mp, __gmp_expr<type##_t, __gmp_binary_expr \
2852 <type##_class, __gmp_expr<T, U>, eval_fun> >(*this, expr)); \
2856 #define __GMPNN_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, \
2859 inline type##_class & type##_class::fun(type2 t) \
2861 __gmp_set_expr(mp, __gmp_expr<type##_t, __gmp_binary_expr \
2862 <type##_class, bigtype, eval_fun> >(*this, t)); \
2866 #define __GMPNS_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, type2) \
2867 __GMPNN_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, \
2868 type2, signed long int)
2870 #define __GMPNU_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, type2) \
2871 __GMPNN_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, \
2872 type2, unsigned long int)
2874 #define __GMPND_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, type2) \
2875 __GMPNN_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, type2, double)
2877 #define __GMPNLD_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, type2) \
2878 __GMPNN_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, type2, long double)
2880 #define __GMPN_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun) \
2881 __GMPNS_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, signed char) \
2882 __GMPNU_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, unsigned char) \
2883 __GMPNS_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, signed int) \
2884 __GMPNU_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, unsigned int) \
2885 __GMPNS_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, signed short int) \
2886 __GMPNU_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, unsigned short int) \
2887 __GMPNS_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, signed long int) \
2888 __GMPNU_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, unsigned long int) \
2889 __GMPND_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, float) \
2890 __GMPND_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, double) \
2891 /* __GMPNLD_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, long double) */
2893 #define __GMP_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun) \
2894 __GMPP_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun) \
2895 __GMPN_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun)
2897 #define __GMPZ_DEFINE_COMPOUND_OPERATOR(fun, eval_fun) \
2898 __GMP_DEFINE_COMPOUND_OPERATOR(mpz, fun, eval_fun)
2900 #define __GMPQ_DEFINE_COMPOUND_OPERATOR(fun, eval_fun) \
2901 __GMP_DEFINE_COMPOUND_OPERATOR(mpq, fun, eval_fun)
2903 #define __GMPF_DEFINE_COMPOUND_OPERATOR(fun, eval_fun) \
2904 __GMP_DEFINE_COMPOUND_OPERATOR(mpf, fun, eval_fun)
2908 #define __GMP_DEFINE_COMPOUND_OPERATOR_UI(type, fun, eval_fun) \
2910 inline type##_class & type##_class::fun(mp_bitcnt_t l) \
2912 __gmp_set_expr(mp, __gmp_expr<type##_t, __gmp_binary_expr \
2913 <type##_class, mp_bitcnt_t, eval_fun> >(*this, l)); \
2917 #define __GMPZ_DEFINE_COMPOUND_OPERATOR_UI(fun, eval_fun) \
2918 __GMP_DEFINE_COMPOUND_OPERATOR_UI(mpz, fun, eval_fun)
2920 #define __GMPQ_DEFINE_COMPOUND_OPERATOR_UI(fun, eval_fun) \
2921 __GMP_DEFINE_COMPOUND_OPERATOR_UI(mpq, fun, eval_fun)
2923 #define __GMPF_DEFINE_COMPOUND_OPERATOR_UI(fun, eval_fun) \
2924 __GMP_DEFINE_COMPOUND_OPERATOR_UI(mpf, fun, eval_fun)
2928 #define __GMP_DEFINE_INCREMENT_OPERATOR(type, fun, eval_fun) \
2930 inline type##_class & type##_class::fun() \
2932 eval_fun::eval(mp); \
2936 inline type##_class type##_class::fun(int) \
2938 type##_class temp(*this); \
2939 eval_fun::eval(mp); \
2943 #define __GMPZ_DEFINE_INCREMENT_OPERATOR(fun, eval_fun) \
2944 __GMP_DEFINE_INCREMENT_OPERATOR(mpz, fun, eval_fun)
2946 #define __GMPQ_DEFINE_INCREMENT_OPERATOR(fun, eval_fun) \
2947 __GMP_DEFINE_INCREMENT_OPERATOR(mpq, fun, eval_fun)
2949 #define __GMPF_DEFINE_INCREMENT_OPERATOR(fun, eval_fun) \
2950 __GMP_DEFINE_INCREMENT_OPERATOR(mpf, fun, eval_fun)
2954 /**************** Arithmetic operators and functions ****************/
2956 // non-member operators and functions
2958 __GMP_DEFINE_UNARY_FUNCTION(operator+, __gmp_unary_plus
)
2959 __GMP_DEFINE_UNARY_FUNCTION(operator-, __gmp_unary_minus
)
2960 __GMP_DEFINE_UNARY_FUNCTION(operator~, __gmp_unary_com
)
2962 __GMP_DEFINE_BINARY_FUNCTION(operator+, __gmp_binary_plus
)
2963 __GMP_DEFINE_BINARY_FUNCTION(operator-, __gmp_binary_minus
)
2964 __GMP_DEFINE_BINARY_FUNCTION(operator*, __gmp_binary_multiplies
)
2965 __GMP_DEFINE_BINARY_FUNCTION(operator/, __gmp_binary_divides
)
2966 __GMP_DEFINE_BINARY_FUNCTION(operator%, __gmp_binary_modulus
)
2967 __GMP_DEFINE_BINARY_FUNCTION(operator&, __gmp_binary_and
)
2968 __GMP_DEFINE_BINARY_FUNCTION(operator|, __gmp_binary_ior
)
2969 __GMP_DEFINE_BINARY_FUNCTION(operator^, __gmp_binary_xor
)
2971 __GMP_DEFINE_BINARY_FUNCTION_UI(operator<<, __gmp_binary_lshift
)
2972 __GMP_DEFINE_BINARY_FUNCTION_UI(operator>>, __gmp_binary_rshift
)
2974 __GMP_DEFINE_BINARY_TYPE_FUNCTION(bool, operator==, __gmp_binary_equal
)
2975 __GMP_DEFINE_BINARY_TYPE_FUNCTION(bool, operator!=, ! __gmp_binary_equal
)
2976 __GMP_DEFINE_BINARY_TYPE_FUNCTION(bool, operator<, __gmp_binary_less
)
2977 __GMP_DEFINE_BINARY_TYPE_FUNCTION(bool, operator<=, ! __gmp_binary_greater
)
2978 __GMP_DEFINE_BINARY_TYPE_FUNCTION(bool, operator>, __gmp_binary_greater
)
2979 __GMP_DEFINE_BINARY_TYPE_FUNCTION(bool, operator>=, ! __gmp_binary_less
)
2981 __GMP_DEFINE_UNARY_FUNCTION(abs
, __gmp_abs_function
)
2982 __GMP_DEFINE_UNARY_FUNCTION(trunc
, __gmp_trunc_function
)
2983 __GMP_DEFINE_UNARY_FUNCTION(floor
, __gmp_floor_function
)
2984 __GMP_DEFINE_UNARY_FUNCTION(ceil
, __gmp_ceil_function
)
2985 __GMP_DEFINE_UNARY_FUNCTION(sqrt
, __gmp_sqrt_function
)
2986 __GMP_DEFINE_BINARY_FUNCTION(hypot
, __gmp_hypot_function
)
2988 __GMP_DEFINE_UNARY_TYPE_FUNCTION(int, sgn
, __gmp_sgn_function
)
2989 __GMP_DEFINE_BINARY_TYPE_FUNCTION(int, cmp
, __gmp_cmp_function
)
2992 void swap(__gmp_expr
<T
, T
>& x
, __gmp_expr
<T
, T
>& y
) __GMPXX_NOEXCEPT
2995 // member operators for mpz_class
2997 __GMPZ_DEFINE_COMPOUND_OPERATOR(operator+=, __gmp_binary_plus
)
2998 __GMPZ_DEFINE_COMPOUND_OPERATOR(operator-=, __gmp_binary_minus
)
2999 __GMPZ_DEFINE_COMPOUND_OPERATOR(operator*=, __gmp_binary_multiplies
)
3000 __GMPZ_DEFINE_COMPOUND_OPERATOR(operator/=, __gmp_binary_divides
)
3001 __GMPZ_DEFINE_COMPOUND_OPERATOR(operator%=, __gmp_binary_modulus
)
3003 __GMPZ_DEFINE_COMPOUND_OPERATOR(operator&=, __gmp_binary_and
)
3004 __GMPZ_DEFINE_COMPOUND_OPERATOR(operator|=, __gmp_binary_ior
)
3005 __GMPZ_DEFINE_COMPOUND_OPERATOR(operator^=, __gmp_binary_xor
)
3007 __GMPZ_DEFINE_COMPOUND_OPERATOR_UI(operator<<=, __gmp_binary_lshift
)
3008 __GMPZ_DEFINE_COMPOUND_OPERATOR_UI(operator>>=, __gmp_binary_rshift
)
3010 __GMPZ_DEFINE_INCREMENT_OPERATOR(operator++, __gmp_unary_increment
)
3011 __GMPZ_DEFINE_INCREMENT_OPERATOR(operator--, __gmp_unary_decrement
)
3013 // member operators for mpq_class
3015 __GMPQ_DEFINE_COMPOUND_OPERATOR(operator+=, __gmp_binary_plus
)
3016 __GMPQ_DEFINE_COMPOUND_OPERATOR(operator-=, __gmp_binary_minus
)
3017 __GMPQ_DEFINE_COMPOUND_OPERATOR(operator*=, __gmp_binary_multiplies
)
3018 __GMPQ_DEFINE_COMPOUND_OPERATOR(operator/=, __gmp_binary_divides
)
3020 __GMPQ_DEFINE_COMPOUND_OPERATOR_UI(operator<<=, __gmp_binary_lshift
)
3021 __GMPQ_DEFINE_COMPOUND_OPERATOR_UI(operator>>=, __gmp_binary_rshift
)
3023 __GMPQ_DEFINE_INCREMENT_OPERATOR(operator++, __gmp_unary_increment
)
3024 __GMPQ_DEFINE_INCREMENT_OPERATOR(operator--, __gmp_unary_decrement
)
3026 // member operators for mpf_class
3028 __GMPF_DEFINE_COMPOUND_OPERATOR(operator+=, __gmp_binary_plus
)
3029 __GMPF_DEFINE_COMPOUND_OPERATOR(operator-=, __gmp_binary_minus
)
3030 __GMPF_DEFINE_COMPOUND_OPERATOR(operator*=, __gmp_binary_multiplies
)
3031 __GMPF_DEFINE_COMPOUND_OPERATOR(operator/=, __gmp_binary_divides
)
3033 __GMPF_DEFINE_COMPOUND_OPERATOR_UI(operator<<=, __gmp_binary_lshift
)
3034 __GMPF_DEFINE_COMPOUND_OPERATOR_UI(operator>>=, __gmp_binary_rshift
)
3036 __GMPF_DEFINE_INCREMENT_OPERATOR(operator++, __gmp_unary_increment
)
3037 __GMPF_DEFINE_INCREMENT_OPERATOR(operator--, __gmp_unary_decrement
)
3041 /**************** Class wrapper for gmp_randstate_t ****************/
3043 class __gmp_urandomb_value
{ };
3044 class __gmp_urandomm_value
{ };
3047 class __gmp_expr
<mpz_t
, __gmp_urandomb_value
>
3050 __gmp_randstate_struct
*state
;
3053 __gmp_expr(gmp_randstate_t s
, mp_bitcnt_t l
) : state(s
), bits(l
) { }
3054 void eval(mpz_ptr z
) const { __gmp_rand_function::eval(z
, state
, bits
); }
3055 mp_bitcnt_t
get_prec() const { return mpf_get_default_prec(); }
3059 class __gmp_expr
<mpz_t
, __gmp_urandomm_value
>
3062 __gmp_randstate_struct
*state
;
3065 __gmp_expr(gmp_randstate_t s
, const mpz_class
&z
) : state(s
), range(z
) { }
3066 void eval(mpz_ptr z
) const
3067 { __gmp_rand_function::eval(z
, state
, range
.get_mpz_t()); }
3068 mp_bitcnt_t
get_prec() const { return mpf_get_default_prec(); }
3072 class __gmp_expr
<mpf_t
, __gmp_urandomb_value
>
3075 __gmp_randstate_struct
*state
;
3078 __gmp_expr(gmp_randstate_t s
, mp_bitcnt_t l
) : state(s
), bits(l
) { }
3079 void eval(mpf_ptr f
) const
3081 __gmp_rand_function::eval(f
, state
,
3082 (bits
>0) ? bits
: mpf_get_prec(f
));
3084 mp_bitcnt_t
get_prec() const
3087 return mpf_get_default_prec();
3094 typedef void __gmp_randinit_default_t (gmp_randstate_t
);
3095 typedef void __gmp_randinit_lc_2exp_t (gmp_randstate_t
, mpz_srcptr
, unsigned long int, mp_bitcnt_t
);
3096 typedef int __gmp_randinit_lc_2exp_size_t (gmp_randstate_t
, mp_bitcnt_t
);
3102 gmp_randstate_t state
;
3104 // copy construction and assignment not allowed
3105 gmp_randclass(const gmp_randclass
&);
3106 void operator=(const gmp_randclass
&);
3108 // constructors and destructor
3109 gmp_randclass(gmp_randalg_t alg
, unsigned long int size
)
3113 case GMP_RAND_ALG_LC
: // no other cases for now
3115 gmp_randinit(state
, alg
, size
);
3120 // gmp_randinit_default
3121 gmp_randclass(__gmp_randinit_default_t
* f
) { f(state
); }
3123 // gmp_randinit_lc_2exp
3124 gmp_randclass(__gmp_randinit_lc_2exp_t
* f
,
3125 mpz_class z
, unsigned long int l1
, mp_bitcnt_t l2
)
3126 { f(state
, z
.get_mpz_t(), l1
, l2
); }
3128 // gmp_randinit_lc_2exp_size
3129 gmp_randclass(__gmp_randinit_lc_2exp_size_t
* f
,
3132 if (f (state
, size
) == 0)
3133 throw std::length_error ("gmp_randinit_lc_2exp_size");
3136 ~gmp_randclass() { gmp_randclear(state
); }
3139 void seed(); // choose a random seed some way (?)
3140 void seed(unsigned long int s
) { gmp_randseed_ui(state
, s
); }
3141 void seed(const mpz_class
&z
) { gmp_randseed(state
, z
.get_mpz_t()); }
3143 // get random number
3144 __gmp_expr
<mpz_t
, __gmp_urandomb_value
> get_z_bits(mp_bitcnt_t l
)
3145 { return __gmp_expr
<mpz_t
, __gmp_urandomb_value
>(state
, l
); }
3146 __gmp_expr
<mpz_t
, __gmp_urandomb_value
> get_z_bits(const mpz_class
&z
)
3147 { return get_z_bits(z
.get_ui()); }
3148 // FIXME: z.get_bitcnt_t() ?
3150 __gmp_expr
<mpz_t
, __gmp_urandomm_value
> get_z_range(const mpz_class
&z
)
3151 { return __gmp_expr
<mpz_t
, __gmp_urandomm_value
>(state
, z
); }
3153 __gmp_expr
<mpf_t
, __gmp_urandomb_value
> get_f(mp_bitcnt_t prec
= 0)
3154 { return __gmp_expr
<mpf_t
, __gmp_urandomb_value
>(state
, prec
); }
3158 /**************** Specialize std::numeric_limits ****************/
3161 template <> class numeric_limits
<mpz_class
>
3164 static const bool is_specialized
= true;
3165 static mpz_class
min() { return mpz_class(); }
3166 static mpz_class
max() { return mpz_class(); }
3167 static mpz_class
lowest() { return mpz_class(); }
3168 static const int digits
= 0;
3169 static const int digits10
= 0;
3170 static const int max_digits10
= 0;
3171 static const bool is_signed
= true;
3172 static const bool is_integer
= true;
3173 static const bool is_exact
= true;
3174 static const int radix
= 2;
3175 static mpz_class
epsilon() { return mpz_class(); }
3176 static mpz_class
round_error() { return mpz_class(); }
3177 static const int min_exponent
= 0;
3178 static const int min_exponent10
= 0;
3179 static const int max_exponent
= 0;
3180 static const int max_exponent10
= 0;
3181 static const bool has_infinity
= false;
3182 static const bool has_quiet_NaN
= false;
3183 static const bool has_signaling_NaN
= false;
3184 static const float_denorm_style has_denorm
= denorm_absent
;
3185 static const bool has_denorm_loss
= false;
3186 static mpz_class
infinity() { return mpz_class(); }
3187 static mpz_class
quiet_NaN() { return mpz_class(); }
3188 static mpz_class
signaling_NaN() { return mpz_class(); }
3189 static mpz_class
denorm_min() { return mpz_class(); }
3190 static const bool is_iec559
= false;
3191 static const bool is_bounded
= false;
3192 static const bool is_modulo
= false;
3193 static const bool traps
= false;
3194 static const bool tinyness_before
= false;
3195 static const float_round_style round_style
= round_toward_zero
;
3198 template <> class numeric_limits
<mpq_class
>
3201 static const bool is_specialized
= true;
3202 static mpq_class
min() { return mpq_class(); }
3203 static mpq_class
max() { return mpq_class(); }
3204 static mpq_class
lowest() { return mpq_class(); }
3205 static const int digits
= 0;
3206 static const int digits10
= 0;
3207 static const int max_digits10
= 0;
3208 static const bool is_signed
= true;
3209 static const bool is_integer
= false;
3210 static const bool is_exact
= true;
3211 static const int radix
= 2;
3212 static mpq_class
epsilon() { return mpq_class(); }
3213 static mpq_class
round_error() { return mpq_class(); }
3214 static const int min_exponent
= 0;
3215 static const int min_exponent10
= 0;
3216 static const int max_exponent
= 0;
3217 static const int max_exponent10
= 0;
3218 static const bool has_infinity
= false;
3219 static const bool has_quiet_NaN
= false;
3220 static const bool has_signaling_NaN
= false;
3221 static const float_denorm_style has_denorm
= denorm_absent
;
3222 static const bool has_denorm_loss
= false;
3223 static mpq_class
infinity() { return mpq_class(); }
3224 static mpq_class
quiet_NaN() { return mpq_class(); }
3225 static mpq_class
signaling_NaN() { return mpq_class(); }
3226 static mpq_class
denorm_min() { return mpq_class(); }
3227 static const bool is_iec559
= false;
3228 static const bool is_bounded
= false;
3229 static const bool is_modulo
= false;
3230 static const bool traps
= false;
3231 static const bool tinyness_before
= false;
3232 static const float_round_style round_style
= round_toward_zero
;
3235 template <> class numeric_limits
<mpf_class
>
3238 static const bool is_specialized
= true;
3239 static mpf_class
min() { return mpf_class(); }
3240 static mpf_class
max() { return mpf_class(); }
3241 static mpf_class
lowest() { return mpf_class(); }
3242 static const int digits
= 0;
3243 static const int digits10
= 0;
3244 static const int max_digits10
= 0;
3245 static const bool is_signed
= true;
3246 static const bool is_integer
= false;
3247 static const bool is_exact
= false;
3248 static const int radix
= 2;
3249 static mpf_class
epsilon() { return mpf_class(); }
3250 static mpf_class
round_error() { return mpf_class(); }
3251 static const int min_exponent
= 0;
3252 static const int min_exponent10
= 0;
3253 static const int max_exponent
= 0;
3254 static const int max_exponent10
= 0;
3255 static const bool has_infinity
= false;
3256 static const bool has_quiet_NaN
= false;
3257 static const bool has_signaling_NaN
= false;
3258 static const float_denorm_style has_denorm
= denorm_absent
;
3259 static const bool has_denorm_loss
= false;
3260 static mpf_class
infinity() { return mpf_class(); }
3261 static mpf_class
quiet_NaN() { return mpf_class(); }
3262 static mpf_class
signaling_NaN() { return mpf_class(); }
3263 static mpf_class
denorm_min() { return mpf_class(); }
3264 static const bool is_iec559
= false;
3265 static const bool is_bounded
= false;
3266 static const bool is_modulo
= false;
3267 static const bool traps
= false;
3268 static const bool tinyness_before
= false;
3269 static const float_round_style round_style
= round_indeterminate
;
3274 /**************** #undef all private macros ****************/
3276 #undef __GMPP_DECLARE_COMPOUND_OPERATOR
3277 #undef __GMPN_DECLARE_COMPOUND_OPERATOR
3278 #undef __GMP_DECLARE_COMPOUND_OPERATOR
3279 #undef __GMP_DECLARE_COMPOUND_OPERATOR_UI
3280 #undef __GMP_DECLARE_INCREMENT_OPERATOR
3281 #undef __GMPXX_DEFINE_ARITHMETIC_CONSTRUCTORS
3282 #undef __GMPXX_DEFINE_ARITHMETIC_ASSIGNMENTS
3284 #undef __GMPZQ_DEFINE_EXPR
3286 #undef __GMP_DEFINE_UNARY_FUNCTION
3287 #undef __GMP_DEFINE_UNARY_TYPE_FUNCTION
3289 #undef __GMPP_DEFINE_BINARY_FUNCTION
3290 #undef __GMPNN_DEFINE_BINARY_FUNCTION
3291 #undef __GMPNS_DEFINE_BINARY_FUNCTION
3292 #undef __GMPNU_DEFINE_BINARY_FUNCTION
3293 #undef __GMPND_DEFINE_BINARY_FUNCTION
3294 #undef __GMPNLD_DEFINE_BINARY_FUNCTION
3295 #undef __GMPN_DEFINE_BINARY_FUNCTION
3296 #undef __GMP_DEFINE_BINARY_FUNCTION
3298 #undef __GMP_DEFINE_BINARY_FUNCTION_UI
3300 #undef __GMPP_DEFINE_BINARY_TYPE_FUNCTION
3301 #undef __GMPNN_DEFINE_BINARY_TYPE_FUNCTION
3302 #undef __GMPNS_DEFINE_BINARY_TYPE_FUNCTION
3303 #undef __GMPNU_DEFINE_BINARY_TYPE_FUNCTION
3304 #undef __GMPND_DEFINE_BINARY_TYPE_FUNCTION
3305 #undef __GMPNLD_DEFINE_BINARY_TYPE_FUNCTION
3306 #undef __GMPN_DEFINE_BINARY_TYPE_FUNCTION
3307 #undef __GMP_DEFINE_BINARY_TYPE_FUNCTION
3309 #undef __GMPZ_DEFINE_COMPOUND_OPERATOR
3311 #undef __GMPP_DEFINE_COMPOUND_OPERATOR
3312 #undef __GMPNN_DEFINE_COMPOUND_OPERATOR
3313 #undef __GMPNS_DEFINE_COMPOUND_OPERATOR
3314 #undef __GMPNU_DEFINE_COMPOUND_OPERATOR
3315 #undef __GMPND_DEFINE_COMPOUND_OPERATOR
3316 #undef __GMPNLD_DEFINE_COMPOUND_OPERATOR
3317 #undef __GMPN_DEFINE_COMPOUND_OPERATOR
3318 #undef __GMP_DEFINE_COMPOUND_OPERATOR
3320 #undef __GMPQ_DEFINE_COMPOUND_OPERATOR
3321 #undef __GMPF_DEFINE_COMPOUND_OPERATOR
3323 #undef __GMP_DEFINE_COMPOUND_OPERATOR_UI
3324 #undef __GMPZ_DEFINE_COMPOUND_OPERATOR_UI
3325 #undef __GMPQ_DEFINE_COMPOUND_OPERATOR_UI
3326 #undef __GMPF_DEFINE_COMPOUND_OPERATOR_UI
3328 #undef __GMP_DEFINE_INCREMENT_OPERATOR
3329 #undef __GMPZ_DEFINE_INCREMENT_OPERATOR
3330 #undef __GMPQ_DEFINE_INCREMENT_OPERATOR
3331 #undef __GMPF_DEFINE_INCREMENT_OPERATOR
3333 #undef __GMPXX_CONSTANT_TRUE
3334 #undef __GMPXX_CONSTANT
3336 #endif /* __GMP_PLUSPLUS__ */