1 /* gmpxx.h -- C++ class wrapper for GMP types. -*- C++ -*-
3 Copyright 2001, 2002, 2003, 2006 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 the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 2.1 of the License, or (at your
10 option) any later version.
12 The GNU MP Library is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15 License for more details.
17 You should have received a copy of the GNU Lesser General Public License
18 along with the GNU MP Library; see the file COPYING.LIB. If not, write to
19 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
20 MA 02110-1301, USA. */
22 /* the C++ compiler must implement the following features:
24 - partial specialization of templates
26 for g++, this means version 2.91 or higher
27 for other compilers, I don't know */
29 #if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 91)
30 #error gmpxx.h requires g++ version 2.91 (egcs 1.1.2) or higher
34 #ifndef __GMP_PLUSPLUS__
35 #define __GMP_PLUSPLUS__
39 #include <cstring> /* for strlen */
45 /**************** Function objects ****************/
46 /* Any evaluation of a __gmp_expr ends up calling one of these functions
47 all intermediate functions being inline, the evaluation should optimize
48 to a direct call to the relevant function, thus yielding no overhead
49 over the C interface. */
51 struct __gmp_unary_plus
53 static void eval(mpz_ptr z, mpz_srcptr w) { mpz_set(z, w); }
54 static void eval(mpq_ptr q, mpq_srcptr r) { mpq_set(q, r); }
55 static void eval(mpf_ptr f, mpf_srcptr g) { mpf_set(f, g); }
58 struct __gmp_unary_minus
60 static void eval(mpz_ptr z, mpz_srcptr w) { mpz_neg(z, w); }
61 static void eval(mpq_ptr q, mpq_srcptr r) { mpq_neg(q, r); }
62 static void eval(mpf_ptr f, mpf_srcptr g) { mpf_neg(f, g); }
65 struct __gmp_unary_com
67 static void eval(mpz_ptr z, mpz_srcptr w) { mpz_com(z, w); }
70 struct __gmp_binary_plus
72 static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v)
75 static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l)
76 { mpz_add_ui(z, w, l); }
77 static void eval(mpz_ptr z, unsigned long int l, mpz_srcptr w)
78 { mpz_add_ui(z, w, l); }
79 static void eval(mpz_ptr z, mpz_srcptr w, signed long int l)
86 static void eval(mpz_ptr z, signed long int l, mpz_srcptr w)
93 static void eval(mpz_ptr z, mpz_srcptr w, double d)
96 mpz_init_set_d(temp, d);
100 static void eval(mpz_ptr z, double d, mpz_srcptr w)
103 mpz_init_set_d(temp, d);
108 static void eval(mpq_ptr q, mpq_srcptr r, mpq_srcptr s)
109 { mpq_add(q, r, s); }
111 static void eval(mpq_ptr q, mpq_srcptr r, unsigned long int l)
112 { mpq_set(q, r); mpz_addmul_ui(mpq_numref(q), mpq_denref(q), l); }
113 static void eval(mpq_ptr q, unsigned long int l, mpq_srcptr r)
114 { mpq_set(q, r); mpz_addmul_ui(mpq_numref(q), mpq_denref(q), l); }
115 static void eval(mpq_ptr q, mpq_srcptr r, signed long int l)
119 mpz_addmul_ui(mpq_numref(q), mpq_denref(q), l);
121 mpz_submul_ui(mpq_numref(q), mpq_denref(q), -l);
123 static void eval(mpq_ptr q, signed long int l, mpq_srcptr r)
127 mpz_addmul_ui(mpq_numref(q), mpq_denref(q), l);
129 mpz_submul_ui(mpq_numref(q), mpq_denref(q), -l);
131 static void eval(mpq_ptr q, mpq_srcptr r, double d)
139 static void eval(mpq_ptr q, double d, mpq_srcptr r)
148 static void eval(mpq_ptr q, mpq_srcptr r, mpz_srcptr z)
149 { mpq_set(q, r); mpz_addmul(mpq_numref(q), mpq_denref(q), z); }
150 static void eval(mpq_ptr q, mpz_srcptr z, mpq_srcptr r)
151 { mpq_set(q, r); mpz_addmul(mpq_numref(q), mpq_denref(q), z); }
153 static void eval(mpf_ptr f, mpf_srcptr g, mpf_srcptr h)
154 { mpf_add(f, g, h); }
156 static void eval(mpf_ptr f, mpf_srcptr g, unsigned long int l)
157 { mpf_add_ui(f, g, l); }
158 static void eval(mpf_ptr f, unsigned long int l, mpf_srcptr g)
159 { mpf_add_ui(f, g, l); }
160 static void eval(mpf_ptr f, mpf_srcptr g, signed long int l)
165 mpf_sub_ui(f, g, -l);
167 static void eval(mpf_ptr f, signed long int l, mpf_srcptr g)
172 mpf_sub_ui(f, g, -l);
174 static void eval(mpf_ptr f, mpf_srcptr g, double d)
177 mpf_init2(temp, 8*sizeof(double));
182 static void eval(mpf_ptr f, double d, mpf_srcptr g)
185 mpf_init2(temp, 8*sizeof(double));
192 struct __gmp_binary_minus
194 static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v)
195 { mpz_sub(z, w, v); }
197 static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l)
198 { mpz_sub_ui(z, w, l); }
199 static void eval(mpz_ptr z, unsigned long int l, mpz_srcptr w)
200 { mpz_ui_sub(z, l, w); }
201 static void eval(mpz_ptr z, mpz_srcptr w, signed long int l)
206 mpz_add_ui(z, w, -l);
208 static void eval(mpz_ptr z, signed long int l, mpz_srcptr w)
214 mpz_add_ui(z, w, -l);
218 static void eval(mpz_ptr z, mpz_srcptr w, double d)
221 mpz_init_set_d(temp, d);
225 static void eval(mpz_ptr z, double d, mpz_srcptr w)
228 mpz_init_set_d(temp, d);
233 static void eval(mpq_ptr q, mpq_srcptr r, mpq_srcptr s)
234 { mpq_sub(q, r, s); }
236 static void eval(mpq_ptr q, mpq_srcptr r, unsigned long int l)
237 { mpq_set(q, r); mpz_submul_ui(mpq_numref(q), mpq_denref(q), l); }
238 static void eval(mpq_ptr q, unsigned long int l, mpq_srcptr r)
239 { mpq_neg(q, r); mpz_addmul_ui(mpq_numref(q), mpq_denref(q), l); }
240 static void eval(mpq_ptr q, mpq_srcptr r, signed long int l)
244 mpz_submul_ui(mpq_numref(q), mpq_denref(q), l);
246 mpz_addmul_ui(mpq_numref(q), mpq_denref(q), -l);
248 static void eval(mpq_ptr q, signed long int l, mpq_srcptr r)
252 mpz_addmul_ui(mpq_numref(q), mpq_denref(q), l);
254 mpz_submul_ui(mpq_numref(q), mpq_denref(q), -l);
256 static void eval(mpq_ptr q, mpq_srcptr r, double d)
264 static void eval(mpq_ptr q, double d, mpq_srcptr r)
273 static void eval(mpq_ptr q, mpq_srcptr r, mpz_srcptr z)
274 { mpq_set(q, r); mpz_submul(mpq_numref(q), mpq_denref(q), z); }
275 static void eval(mpq_ptr q, mpz_srcptr z, mpq_srcptr r)
276 { mpq_neg(q, r); mpz_addmul(mpq_numref(q), mpq_denref(q), z); }
278 static void eval(mpf_ptr f, mpf_srcptr g, mpf_srcptr h)
279 { mpf_sub(f, g, h); }
281 static void eval(mpf_ptr f, mpf_srcptr g, unsigned long int l)
282 { mpf_sub_ui(f, g, l); }
283 static void eval(mpf_ptr f, unsigned long int l, mpf_srcptr g)
284 { mpf_ui_sub(f, l, g); }
285 static void eval(mpf_ptr f, mpf_srcptr g, signed long int l)
290 mpf_add_ui(f, g, -l);
292 static void eval(mpf_ptr f, signed long int l, mpf_srcptr g)
297 mpf_add_ui(f, g, -l);
300 static void eval(mpf_ptr f, mpf_srcptr g, double d)
303 mpf_init2(temp, 8*sizeof(double));
308 static void eval(mpf_ptr f, double d, mpf_srcptr g)
311 mpf_init2(temp, 8*sizeof(double));
318 struct __gmp_binary_multiplies
320 static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v)
321 { mpz_mul(z, w, v); }
323 static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l)
324 { mpz_mul_ui(z, w, l); }
325 static void eval(mpz_ptr z, unsigned long int l, mpz_srcptr w)
326 { mpz_mul_ui(z, w, l); }
327 static void eval(mpz_ptr z, mpz_srcptr w, signed long int l)
328 { mpz_mul_si (z, w, l); }
329 static void eval(mpz_ptr z, signed long int l, mpz_srcptr w)
330 { mpz_mul_si (z, w, l); }
331 static void eval(mpz_ptr z, mpz_srcptr w, double d)
334 mpz_init_set_d(temp, d);
338 static void eval(mpz_ptr z, double d, mpz_srcptr w)
341 mpz_init_set_d(temp, d);
346 static void eval(mpq_ptr q, mpq_srcptr r, mpq_srcptr s)
347 { mpq_mul(q, r, s); }
349 static void eval(mpq_ptr q, mpq_srcptr r, unsigned long int l)
353 mpq_set_ui(temp, l, 1);
357 static void eval(mpq_ptr q, unsigned long int l, mpq_srcptr r)
361 mpq_set_ui(temp, l, 1);
365 static void eval(mpq_ptr q, mpq_srcptr r, signed long int l)
369 mpq_set_si(temp, l, 1);
373 static void eval(mpq_ptr q, signed long int l, mpq_srcptr r)
377 mpq_set_si(temp, l, 1);
381 static void eval(mpq_ptr q, mpq_srcptr r, double d)
389 static void eval(mpq_ptr q, double d, mpq_srcptr r)
398 static void eval(mpf_ptr f, mpf_srcptr g, mpf_srcptr h)
399 { mpf_mul(f, g, h); }
401 static void eval(mpf_ptr f, mpf_srcptr g, unsigned long int l)
402 { mpf_mul_ui(f, g, l); }
403 static void eval(mpf_ptr f, unsigned long int l, mpf_srcptr g)
404 { mpf_mul_ui(f, g, l); }
405 static void eval(mpf_ptr f, mpf_srcptr g, signed long int l)
411 mpf_mul_ui(f, g, -l);
415 static void eval(mpf_ptr f, signed long int l, mpf_srcptr g)
421 mpf_mul_ui(f, g, -l);
425 static void eval(mpf_ptr f, mpf_srcptr g, double d)
428 mpf_init2(temp, 8*sizeof(double));
433 static void eval(mpf_ptr f, double d, mpf_srcptr g)
436 mpf_init2(temp, 8*sizeof(double));
443 struct __gmp_binary_divides
445 static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v)
446 { mpz_tdiv_q(z, w, v); }
448 static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l)
449 { mpz_tdiv_q_ui(z, w, l); }
450 static void eval(mpz_ptr z, unsigned long int l, mpz_srcptr w)
454 if (mpz_fits_ulong_p(w))
455 mpz_set_ui(z, l / mpz_get_ui(w));
462 if (mpz_fits_ulong_p(z))
464 mpz_set_ui(z, l / mpz_get_ui(z));
471 static void eval(mpz_ptr z, mpz_srcptr w, signed long int l)
474 mpz_tdiv_q_ui(z, w, l);
477 mpz_tdiv_q_ui(z, w, -l);
481 static void eval(mpz_ptr z, signed long int l, mpz_srcptr w)
483 if (mpz_fits_slong_p(w))
484 mpz_set_si(z, l / mpz_get_si(w));
487 /* if w is bigger than a long then the quotient must be zero, unless
488 l==LONG_MIN and w==-LONG_MIN in which case the quotient is -1 */
489 mpz_set_si (z, (mpz_cmpabs_ui (w, (l >= 0 ? l : -l)) == 0 ? -1 : 0));
492 static void eval(mpz_ptr z, mpz_srcptr w, double d)
495 mpz_init_set_d(temp, d);
496 mpz_tdiv_q(z, w, temp);
499 static void eval(mpz_ptr z, double d, mpz_srcptr w)
502 mpz_init_set_d(temp, d);
503 mpz_tdiv_q(z, temp, w);
507 static void eval(mpq_ptr q, mpq_srcptr r, mpq_srcptr s)
508 { mpq_div(q, r, s); }
510 static void eval(mpq_ptr q, mpq_srcptr r, unsigned long int l)
514 mpq_set_ui(temp, l, 1);
518 static void eval(mpq_ptr q, unsigned long int l, mpq_srcptr r)
522 mpq_set_ui(temp, l, 1);
526 static void eval(mpq_ptr q, mpq_srcptr r, signed long int l)
530 mpq_set_si(temp, l, 1);
534 static void eval(mpq_ptr q, signed long int l, mpq_srcptr r)
538 mpq_set_si(temp, l, 1);
542 static void eval(mpq_ptr q, mpq_srcptr r, double d)
550 static void eval(mpq_ptr q, double d, mpq_srcptr r)
559 static void eval(mpf_ptr f, mpf_srcptr g, mpf_srcptr h)
560 { mpf_div(f, g, h); }
562 static void eval(mpf_ptr f, mpf_srcptr g, unsigned long int l)
563 { mpf_div_ui(f, g, l); }
564 static void eval(mpf_ptr f, unsigned long int l, mpf_srcptr g)
565 { mpf_ui_div(f, l, g); }
566 static void eval(mpf_ptr f, mpf_srcptr g, signed long int l)
572 mpf_div_ui(f, g, -l);
576 static void eval(mpf_ptr f, signed long int l, mpf_srcptr g)
582 mpf_ui_div(f, -l, g);
586 static void eval(mpf_ptr f, mpf_srcptr g, double d)
589 mpf_init2(temp, 8*sizeof(double));
594 static void eval(mpf_ptr f, double d, mpf_srcptr g)
597 mpf_init2(temp, 8*sizeof(double));
604 struct __gmp_binary_modulus
606 static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v)
607 { mpz_tdiv_r(z, w, v); }
609 static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l)
610 { mpz_tdiv_r_ui(z, w, l); }
611 static void eval(mpz_ptr z, unsigned long int l, mpz_srcptr w)
615 if (mpz_fits_ulong_p(w))
616 mpz_set_ui(z, l % mpz_get_ui(w));
623 if (mpz_fits_ulong_p(z))
624 mpz_set_ui(z, l % mpz_get_ui(z));
629 static void eval(mpz_ptr z, mpz_srcptr w, signed long int l)
631 mpz_tdiv_r_ui (z, w, (l >= 0 ? l : -l));
633 static void eval(mpz_ptr z, signed long int l, mpz_srcptr w)
635 if (mpz_fits_slong_p(w))
636 mpz_set_si(z, l % mpz_get_si(w));
639 /* if w is bigger than a long then the remainder is l unchanged,
640 unless l==LONG_MIN and w==-LONG_MIN in which case it's 0 */
641 mpz_set_si (z, mpz_cmpabs_ui (w, (l >= 0 ? l : -l)) == 0 ? 0 : l);
644 static void eval(mpz_ptr z, mpz_srcptr w, double d)
647 mpz_init_set_d(temp, d);
648 mpz_tdiv_r(z, w, temp);
651 static void eval(mpz_ptr z, double d, mpz_srcptr w)
654 mpz_init_set_d(temp, d);
655 mpz_tdiv_r(z, temp, w);
660 struct __gmp_binary_and
662 static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v)
663 { mpz_and(z, w, v); }
666 struct __gmp_binary_ior
668 static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v)
669 { mpz_ior(z, w, v); }
672 struct __gmp_binary_xor
674 static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v)
675 { mpz_xor(z, w, v); }
678 struct __gmp_binary_lshift
680 static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l)
681 { mpz_mul_2exp(z, w, l); }
682 static void eval(mpq_ptr q, mpq_srcptr r, unsigned long int l)
683 { mpq_mul_2exp(q, r, l); }
684 static void eval(mpf_ptr f, mpf_srcptr g, unsigned long int l)
685 { mpf_mul_2exp(f, g, l); }
688 struct __gmp_binary_rshift
690 static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l)
691 { mpz_tdiv_q_2exp(z, w, l); }
692 static void eval(mpq_ptr q, mpq_srcptr r, unsigned long int l)
693 { mpq_div_2exp(q, r, l); }
694 static void eval(mpf_ptr f, mpf_srcptr g, unsigned long int l)
695 { mpf_div_2exp(f, g, l); }
698 struct __gmp_binary_equal
700 static bool eval(mpz_srcptr z, mpz_srcptr w) { return mpz_cmp(z, w) == 0; }
702 static bool eval(mpz_srcptr z, unsigned long int l)
703 { return mpz_cmp_ui(z, l) == 0; }
704 static bool eval(unsigned long int l, mpz_srcptr z)
705 { return mpz_cmp_ui(z, l) == 0; }
706 static bool eval(mpz_srcptr z, signed long int l)
707 { return mpz_cmp_si(z, l) == 0; }
708 static bool eval(signed long int l, mpz_srcptr z)
709 { return mpz_cmp_si(z, l) == 0; }
710 static bool eval(mpz_srcptr z, double d)
711 { return mpz_cmp_d(z, d) == 0; }
712 static bool eval(double d, mpz_srcptr z)
713 { return mpz_cmp_d(z, d) == 0; }
715 static bool eval(mpq_srcptr q, mpq_srcptr r)
716 { return mpq_equal(q, r) != 0; }
718 static bool eval(mpq_srcptr q, unsigned long int l)
719 { return mpq_cmp_ui(q, l, 1) == 0; }
720 static bool eval(unsigned long int l, mpq_srcptr q)
721 { return mpq_cmp_ui(q, l, 1) == 0; }
722 static bool eval(mpq_srcptr q, signed long int l)
723 { return mpq_cmp_si(q, l, 1) == 0; }
724 static bool eval(signed long int l, mpq_srcptr q)
725 { return mpq_cmp_si(q, l, 1) == 0; }
726 static bool eval(mpq_srcptr q, double d)
732 b = (mpq_equal(q, temp) != 0);
736 static bool eval(double d, mpq_srcptr q)
742 b = (mpq_equal(temp, q) != 0);
747 static bool eval(mpf_srcptr f, mpf_srcptr g) { return mpf_cmp(f, g) == 0; }
749 static bool eval(mpf_srcptr f, unsigned long int l)
750 { return mpf_cmp_ui(f, l) == 0; }
751 static bool eval(unsigned long int l, mpf_srcptr f)
752 { return mpf_cmp_ui(f, l) == 0; }
753 static bool eval(mpf_srcptr f, signed long int l)
754 { return mpf_cmp_si(f, l) == 0; }
755 static bool eval(signed long int l, mpf_srcptr f)
756 { return mpf_cmp_si(f, l) == 0; }
757 static bool eval(mpf_srcptr f, double d)
758 { return mpf_cmp_d(f, d) == 0; }
759 static bool eval(double d, mpf_srcptr f)
760 { return mpf_cmp_d(f, d) == 0; }
763 struct __gmp_binary_not_equal
765 static bool eval(mpz_srcptr z, mpz_srcptr w) { return mpz_cmp(z, w) != 0; }
767 static bool eval(mpz_srcptr z, unsigned long int l)
768 { return mpz_cmp_ui(z, l) != 0; }
769 static bool eval(unsigned long int l, mpz_srcptr z)
770 { return mpz_cmp_ui(z, l) != 0; }
771 static bool eval(mpz_srcptr z, signed long int l)
772 { return mpz_cmp_si(z, l) != 0; }
773 static bool eval(signed long int l, mpz_srcptr z)
774 { return mpz_cmp_si(z, l) != 0; }
775 static bool eval(mpz_srcptr z, double d)
776 { return mpz_cmp_d(z, d) != 0; }
777 static bool eval(double d, mpz_srcptr z)
778 { return mpz_cmp_d(z, d) != 0; }
780 static bool eval(mpq_srcptr q, mpq_srcptr r)
781 { return mpq_equal(q, r) == 0; }
783 static bool eval(mpq_srcptr q, unsigned long int l)
784 { return mpq_cmp_ui(q, l, 1) != 0; }
785 static bool eval(unsigned long int l, mpq_srcptr q)
786 { return mpq_cmp_ui(q, l, 1) != 0; }
787 static bool eval(mpq_srcptr q, signed long int l)
788 { return mpq_cmp_si(q, l, 1) != 0; }
789 static bool eval(signed long int l, mpq_srcptr q)
790 { return mpq_cmp_si(q, l, 1) != 0; }
791 static bool eval(mpq_srcptr q, double d)
797 b = (mpq_equal(q, temp) == 0);
801 static bool eval(double d, mpq_srcptr q)
807 b = (mpq_equal(temp, q) == 0);
812 static bool eval(mpf_srcptr f, mpf_srcptr g) { return mpf_cmp(f, g) != 0; }
814 static bool eval(mpf_srcptr f, unsigned long int l)
815 { return mpf_cmp_ui(f, l) != 0; }
816 static bool eval(unsigned long int l, mpf_srcptr f)
817 { return mpf_cmp_ui(f, l) != 0; }
818 static bool eval(mpf_srcptr f, signed long int l)
819 { return mpf_cmp_si(f, l) != 0; }
820 static bool eval(signed long int l, mpf_srcptr f)
821 { return mpf_cmp_si(f, l) != 0; }
822 static bool eval(mpf_srcptr f, double d)
823 { return mpf_cmp_d(f, d) != 0; }
824 static bool eval(double d, mpf_srcptr f)
825 { return mpf_cmp_d(f, d) != 0; }
828 struct __gmp_binary_less
830 static bool eval(mpz_srcptr z, mpz_srcptr w) { return mpz_cmp(z, w) < 0; }
832 static bool eval(mpz_srcptr z, unsigned long int l)
833 { return mpz_cmp_ui(z, l) < 0; }
834 static bool eval(unsigned long int l, mpz_srcptr z)
835 { return mpz_cmp_ui(z, l) > 0; }
836 static bool eval(mpz_srcptr z, signed long int l)
837 { return mpz_cmp_si(z, l) < 0; }
838 static bool eval(signed long int l, mpz_srcptr z)
839 { return mpz_cmp_si(z, l) > 0; }
840 static bool eval(mpz_srcptr z, double d)
841 { return mpz_cmp_d(z, d) < 0; }
842 static bool eval(double d, mpz_srcptr z)
843 { return mpz_cmp_d(z, d) > 0; }
845 static bool eval(mpq_srcptr q, mpq_srcptr r) { return mpq_cmp(q, r) < 0; }
847 static bool eval(mpq_srcptr q, unsigned long int l)
848 { return mpq_cmp_ui(q, l, 1) < 0; }
849 static bool eval(unsigned long int l, mpq_srcptr q)
850 { return mpq_cmp_ui(q, l, 1) > 0; }
851 static bool eval(mpq_srcptr q, signed long int l)
852 { return mpq_cmp_si(q, l, 1) < 0; }
853 static bool eval(signed long int l, mpq_srcptr q)
854 { return mpq_cmp_si(q, l, 1) > 0; }
855 static bool eval(mpq_srcptr q, double d)
861 b = (mpq_cmp(q, temp) < 0);
865 static bool eval(double d, mpq_srcptr q)
871 b = (mpq_cmp(temp, q) < 0);
876 static bool eval(mpf_srcptr f, mpf_srcptr g) { return mpf_cmp(f, g) < 0; }
878 static bool eval(mpf_srcptr f, unsigned long int l)
879 { return mpf_cmp_ui(f, l) < 0; }
880 static bool eval(unsigned long int l, mpf_srcptr f)
881 { return mpf_cmp_ui(f, l) > 0; }
882 static bool eval(mpf_srcptr f, signed long int l)
883 { return mpf_cmp_si(f, l) < 0; }
884 static bool eval(signed long int l, mpf_srcptr f)
885 { return mpf_cmp_si(f, l) > 0; }
886 static bool eval(mpf_srcptr f, double d)
887 { return mpf_cmp_d(f, d) < 0; }
888 static bool eval(double d, mpf_srcptr f)
889 { return mpf_cmp_d(f, d) > 0; }
892 struct __gmp_binary_less_equal
894 static bool eval(mpz_srcptr z, mpz_srcptr w) { return mpz_cmp(z, w) <= 0; }
896 static bool eval(mpz_srcptr z, unsigned long int l)
897 { return mpz_cmp_ui(z, l) <= 0; }
898 static bool eval(unsigned long int l, mpz_srcptr z)
899 { return mpz_cmp_ui(z, l) >= 0; }
900 static bool eval(mpz_srcptr z, signed long int l)
901 { return mpz_cmp_si(z, l) <= 0; }
902 static bool eval(signed long int l, mpz_srcptr z)
903 { return mpz_cmp_si(z, l) >= 0; }
904 static bool eval(mpz_srcptr z, double d)
905 { return mpz_cmp_d(z, d) <= 0; }
906 static bool eval(double d, mpz_srcptr z)
907 { return mpz_cmp_d(z, d) >= 0; }
909 static bool eval(mpq_srcptr q, mpq_srcptr r) { return mpq_cmp(q, r) <= 0; }
911 static bool eval(mpq_srcptr q, unsigned long int l)
912 { return mpq_cmp_ui(q, l, 1) <= 0; }
913 static bool eval(unsigned long int l, mpq_srcptr q)
914 { return mpq_cmp_ui(q, l, 1) >= 0; }
915 static bool eval(mpq_srcptr q, signed long int l)
916 { return mpq_cmp_si(q, l, 1) <= 0; }
917 static bool eval(signed long int l, mpq_srcptr q)
918 { return mpq_cmp_si(q, l, 1) >= 0; }
919 static bool eval(mpq_srcptr q, double d)
925 b = (mpq_cmp(q, temp) <= 0);
929 static bool eval(double d, mpq_srcptr q)
935 b = (mpq_cmp(temp, q) <= 0);
940 static bool eval(mpf_srcptr f, mpf_srcptr g) { return mpf_cmp(f, g) <= 0; }
942 static bool eval(mpf_srcptr f, unsigned long int l)
943 { return mpf_cmp_ui(f, l) <= 0; }
944 static bool eval(unsigned long int l, mpf_srcptr f)
945 { return mpf_cmp_ui(f, l) >= 0; }
946 static bool eval(mpf_srcptr f, signed long int l)
947 { return mpf_cmp_si(f, l) <= 0; }
948 static bool eval(signed long int l, mpf_srcptr f)
949 { return mpf_cmp_si(f, l) >= 0; }
950 static bool eval(mpf_srcptr f, double d)
951 { return mpf_cmp_d(f, d) <= 0; }
952 static bool eval(double d, mpf_srcptr f)
953 { return mpf_cmp_d(f, d) >= 0; }
956 struct __gmp_binary_greater
958 static bool eval(mpz_srcptr z, mpz_srcptr w) { return mpz_cmp(z, w) > 0; }
960 static bool eval(mpz_srcptr z, unsigned long int l)
961 { return mpz_cmp_ui(z, l) > 0; }
962 static bool eval(unsigned long int l, mpz_srcptr z)
963 { return mpz_cmp_ui(z, l) < 0; }
964 static bool eval(mpz_srcptr z, signed long int l)
965 { return mpz_cmp_si(z, l) > 0; }
966 static bool eval(signed long int l, mpz_srcptr z)
967 { return mpz_cmp_si(z, l) < 0; }
968 static bool eval(mpz_srcptr z, double d)
969 { return mpz_cmp_d(z, d) > 0; }
970 static bool eval(double d, mpz_srcptr z)
971 { return mpz_cmp_d(z, d) < 0; }
973 static bool eval(mpq_srcptr q, mpq_srcptr r) { return mpq_cmp(q, r) > 0; }
975 static bool eval(mpq_srcptr q, unsigned long int l)
976 { return mpq_cmp_ui(q, l, 1) > 0; }
977 static bool eval(unsigned long int l, mpq_srcptr q)
978 { return mpq_cmp_ui(q, l, 1) < 0; }
979 static bool eval(mpq_srcptr q, signed long int l)
980 { return mpq_cmp_si(q, l, 1) > 0; }
981 static bool eval(signed long int l, mpq_srcptr q)
982 { return mpq_cmp_si(q, l, 1) < 0; }
983 static bool eval(mpq_srcptr q, double d)
989 b = (mpq_cmp(q, temp) > 0);
993 static bool eval(double d, mpq_srcptr q)
999 b = (mpq_cmp(temp, q) > 0);
1004 static bool eval(mpf_srcptr f, mpf_srcptr g) { return mpf_cmp(f, g) > 0; }
1006 static bool eval(mpf_srcptr f, unsigned long int l)
1007 { return mpf_cmp_ui(f, l) > 0; }
1008 static bool eval(unsigned long int l, mpf_srcptr f)
1009 { return mpf_cmp_ui(f, l) < 0; }
1010 static bool eval(mpf_srcptr f, signed long int l)
1011 { return mpf_cmp_si(f, l) > 0; }
1012 static bool eval(signed long int l, mpf_srcptr f)
1013 { return mpf_cmp_si(f, l) < 0; }
1014 static bool eval(mpf_srcptr f, double d)
1015 { return mpf_cmp_d(f, d) > 0; }
1016 static bool eval(double d, mpf_srcptr f)
1017 { return mpf_cmp_d(f, d) < 0; }
1020 struct __gmp_binary_greater_equal
1022 static bool eval(mpz_srcptr z, mpz_srcptr w) { return mpz_cmp(z, w) >= 0; }
1024 static bool eval(mpz_srcptr z, unsigned long int l)
1025 { return mpz_cmp_ui(z, l) >= 0; }
1026 static bool eval(unsigned long int l, mpz_srcptr z)
1027 { return mpz_cmp_ui(z, l) <= 0; }
1028 static bool eval(mpz_srcptr z, signed long int l)
1029 { return mpz_cmp_si(z, l) >= 0; }
1030 static bool eval(signed long int l, mpz_srcptr z)
1031 { return mpz_cmp_si(z, l) <= 0; }
1032 static bool eval(mpz_srcptr z, double d)
1033 { return mpz_cmp_d(z, d) >= 0; }
1034 static bool eval(double d, mpz_srcptr z)
1035 { return mpz_cmp_d(z, d) <= 0; }
1037 static bool eval(mpq_srcptr q, mpq_srcptr r) { return mpq_cmp(q, r) >= 0; }
1039 static bool eval(mpq_srcptr q, unsigned long int l)
1040 { return mpq_cmp_ui(q, l, 1) >= 0; }
1041 static bool eval(unsigned long int l, mpq_srcptr q)
1042 { return mpq_cmp_ui(q, l, 1) <= 0; }
1043 static bool eval(mpq_srcptr q, signed long int l)
1044 { return mpq_cmp_si(q, l, 1) >= 0; }
1045 static bool eval(signed long int l, mpq_srcptr q)
1046 { return mpq_cmp_si(q, l, 1) <= 0; }
1047 static bool eval(mpq_srcptr q, double d)
1053 b = (mpq_cmp(q, temp) >= 0);
1057 static bool eval(double d, mpq_srcptr q)
1063 b = (mpq_cmp(temp, q) >= 0);
1068 static bool eval(mpf_srcptr f, mpf_srcptr g) { return mpf_cmp(f, g) >= 0; }
1070 static bool eval(mpf_srcptr f, unsigned long int l)
1071 { return mpf_cmp_ui(f, l) >= 0; }
1072 static bool eval(unsigned long int l, mpf_srcptr f)
1073 { return mpf_cmp_ui(f, l) <= 0; }
1074 static bool eval(mpf_srcptr f, signed long int l)
1075 { return mpf_cmp_si(f, l) >= 0; }
1076 static bool eval(signed long int l, mpf_srcptr f)
1077 { return mpf_cmp_si(f, l) <= 0; }
1078 static bool eval(mpf_srcptr f, double d)
1079 { return mpf_cmp_d(f, d) >= 0; }
1080 static bool eval(double d, mpf_srcptr f)
1081 { return mpf_cmp_d(f, d) <= 0; }
1084 struct __gmp_unary_increment
1086 static void eval(mpz_ptr z) { mpz_add_ui(z, z, 1); }
1087 static void eval(mpq_ptr q)
1088 { mpz_add(mpq_numref(q), mpq_numref(q), mpq_denref(q)); }
1089 static void eval(mpf_ptr f) { mpf_add_ui(f, f, 1); }
1092 struct __gmp_unary_decrement
1094 static void eval(mpz_ptr z) { mpz_sub_ui(z, z, 1); }
1095 static void eval(mpq_ptr q)
1096 { mpz_sub(mpq_numref(q), mpq_numref(q), mpq_denref(q)); }
1097 static void eval(mpf_ptr f) { mpf_sub_ui(f, f, 1); }
1100 struct __gmp_abs_function
1102 static void eval(mpz_ptr z, mpz_srcptr w) { mpz_abs(z, w); }
1103 static void eval(mpq_ptr q, mpq_srcptr r) { mpq_abs(q, r); }
1104 static void eval(mpf_ptr f, mpf_srcptr g) { mpf_abs(f, g); }
1107 struct __gmp_trunc_function
1109 static void eval(mpf_ptr f, mpf_srcptr g) { mpf_trunc(f, g); }
1112 struct __gmp_floor_function
1114 static void eval(mpf_ptr f, mpf_srcptr g) { mpf_floor(f, g); }
1117 struct __gmp_ceil_function
1119 static void eval(mpf_ptr f, mpf_srcptr g) { mpf_ceil(f, g); }
1122 struct __gmp_sqrt_function
1124 static void eval(mpz_ptr z, mpz_srcptr w) { mpz_sqrt(z, w); }
1125 static void eval(mpf_ptr f, mpf_srcptr g) { mpf_sqrt(f, g); }
1128 struct __gmp_hypot_function
1130 static void eval(mpf_ptr f, mpf_srcptr g, mpf_srcptr h)
1133 mpf_init2(temp, mpf_get_prec(f));
1134 mpf_mul(temp, g, g);
1136 mpf_add(f, f, temp);
1141 static void eval(mpf_ptr f, mpf_srcptr g, unsigned long int l)
1144 mpf_init2(temp, mpf_get_prec(f));
1145 mpf_mul(temp, g, g);
1148 mpf_add(f, f, temp);
1152 static void eval(mpf_ptr f, unsigned long int l, mpf_srcptr g)
1155 mpf_init2(temp, mpf_get_prec(f));
1156 mpf_mul(temp, g, g);
1159 mpf_add(f, f, temp);
1163 static void eval(mpf_ptr f, mpf_srcptr g, signed long int l)
1166 mpf_init2(temp, mpf_get_prec(f));
1167 mpf_mul(temp, g, g);
1170 mpf_add(f, f, temp);
1174 static void eval(mpf_ptr f, signed long int l, mpf_srcptr g)
1177 mpf_init2(temp, mpf_get_prec(f));
1178 mpf_mul(temp, g, g);
1181 mpf_add(f, f, temp);
1185 static void eval(mpf_ptr f, mpf_srcptr g, double d)
1188 mpf_init2(temp, mpf_get_prec(f));
1189 mpf_mul(temp, g, g);
1192 mpf_add(f, f, temp);
1196 static void eval(mpf_ptr f, double d, mpf_srcptr g)
1199 mpf_init2(temp, mpf_get_prec(f));
1200 mpf_mul(temp, g, g);
1203 mpf_add(f, f, temp);
1209 struct __gmp_sgn_function
1211 static int eval(mpz_srcptr z) { return mpz_sgn(z); }
1212 static int eval(mpq_srcptr q) { return mpq_sgn(q); }
1213 static int eval(mpf_srcptr f) { return mpf_sgn(f); }
1216 struct __gmp_cmp_function
1218 static int eval(mpz_srcptr z, mpz_srcptr w) { return mpz_cmp(z, w); }
1220 static int eval(mpz_srcptr z, unsigned long int l)
1221 { return mpz_cmp_ui(z, l); }
1222 static int eval(unsigned long int l, mpz_srcptr z)
1223 { return -mpz_cmp_ui(z, l); }
1224 static int eval(mpz_srcptr z, signed long int l)
1225 { return mpz_cmp_si(z, l); }
1226 static int eval(signed long int l, mpz_srcptr z)
1227 { return -mpz_cmp_si(z, l); }
1228 static int eval(mpz_srcptr z, double d)
1229 { return mpz_cmp_d(z, d); }
1230 static int eval(double d, mpz_srcptr z)
1231 { return -mpz_cmp_d(z, d); }
1233 static int eval(mpq_srcptr q, mpq_srcptr r) { return mpq_cmp(q, r); }
1235 static int eval(mpq_srcptr q, unsigned long int l)
1236 { return mpq_cmp_ui(q, l, 1); }
1237 static int eval(unsigned long int l, mpq_srcptr q)
1238 { return -mpq_cmp_ui(q, l, 1); }
1239 static int eval(mpq_srcptr q, signed long int l)
1240 { return mpq_cmp_si(q, l, 1); }
1241 static int eval(signed long int l, mpq_srcptr q)
1242 { return -mpq_cmp_si(q, l, 1); }
1243 static int eval(mpq_srcptr q, double d)
1249 i = mpq_cmp(q, temp);
1253 static int eval(double d, mpq_srcptr q)
1259 i = mpq_cmp(temp, q);
1264 static int eval(mpf_srcptr f, mpf_srcptr g) { return mpf_cmp(f, g); }
1266 static int eval(mpf_srcptr f, unsigned long int l)
1267 { return mpf_cmp_ui(f, l); }
1268 static int eval(unsigned long int l, mpf_srcptr f)
1269 { return -mpf_cmp_ui(f, l); }
1270 static int eval(mpf_srcptr f, signed long int l)
1271 { return mpf_cmp_si(f, l); }
1272 static int eval(signed long int l, mpf_srcptr f)
1273 { return -mpf_cmp_si(f, l); }
1274 static int eval(mpf_srcptr f, double d)
1275 { return mpf_cmp_d(f, d); }
1276 static int eval(double d, mpf_srcptr f)
1277 { return -mpf_cmp_d(f, d); }
1280 struct __gmp_ternary_addmul // z = w + v * u
1282 static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v, mpz_srcptr u)
1283 { mpz_set(z, w); mpz_addmul(z, v, u); }
1285 static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v, unsigned long int l)
1286 { mpz_set(z, w); mpz_addmul_ui(z, v, l); }
1287 static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l, mpz_srcptr v)
1288 { mpz_set(z, w); mpz_addmul_ui(z, v, l); }
1289 static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v, signed long int l)
1293 mpz_addmul_ui(z, v, l);
1295 mpz_submul_ui(z, v, -l);
1297 static void eval(mpz_ptr z, mpz_srcptr w, signed long int l, mpz_srcptr v)
1301 mpz_addmul_ui(z, v, l);
1303 mpz_submul_ui(z, v, -l);
1305 static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v, double d)
1308 mpz_init_set_d(temp, d);
1310 mpz_addmul(z, v, temp);
1313 static void eval(mpz_ptr z, mpz_srcptr w, double d, mpz_srcptr v)
1316 mpz_init_set_d(temp, d);
1318 mpz_addmul(z, temp, v);
1323 struct __gmp_ternary_submul // z = w - v * u
1325 static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v, mpz_srcptr u)
1326 { mpz_set(z, w); mpz_submul(z, v, u); }
1328 static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v, unsigned long int l)
1329 { mpz_set(z, w); mpz_submul_ui(z, v, l); }
1330 static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l, mpz_srcptr v)
1331 { mpz_set(z, w); mpz_submul_ui(z, v, l); }
1332 static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v, signed long int l)
1336 mpz_submul_ui(z, v, l);
1338 mpz_addmul_ui(z, v, -l);
1340 static void eval(mpz_ptr z, mpz_srcptr w, signed long int l, mpz_srcptr v)
1344 mpz_submul_ui(z, v, l);
1346 mpz_addmul_ui(z, v, -l);
1348 static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v, double d)
1351 mpz_init_set_d(temp, d);
1353 mpz_submul(z, v, temp);
1356 static void eval(mpz_ptr z, mpz_srcptr w, double d, mpz_srcptr v)
1359 mpz_init_set_d(temp, d);
1361 mpz_submul(z, temp, v);
1366 struct __gmp_rand_function
1368 static void eval(mpz_ptr z, gmp_randstate_t s, unsigned long int l)
1369 { mpz_urandomb(z, s, l); }
1370 static void eval(mpz_ptr z, gmp_randstate_t s, mpz_srcptr w)
1371 { mpz_urandomm(z, s, w); }
1372 static void eval(mpf_ptr f, gmp_randstate_t s, unsigned long int prec)
1373 { mpf_urandomb(f, s, prec); }
1377 /**************** Auxiliary classes ****************/
1379 /* this is much the same as gmp_allocated_string in gmp-impl.h
1380 since gmp-impl.h is not publicly available, I redefine it here
1381 I use a different name to avoid possible clashes */
1382 struct __gmp_alloc_cstring
1385 __gmp_alloc_cstring(char *s) { str = s; }
1386 ~__gmp_alloc_cstring()
1388 void (*freefunc) (void *, size_t);
1389 mp_get_memory_functions (NULL, NULL, &freefunc);
1390 (*freefunc) (str, std::strlen(str)+1);
1395 // general expression template class
1396 template <class T, class U>
1400 // templates for resolving expression types
1402 struct __gmp_resolve_ref
1407 template <class T, class U>
1408 struct __gmp_resolve_ref<__gmp_expr<T, U> >
1410 typedef const __gmp_expr<T, U> & ref_type;
1414 template <class T, class U = T>
1415 struct __gmp_resolve_expr;
1418 struct __gmp_resolve_expr<mpz_t>
1420 typedef mpz_t value_type;
1421 typedef mpz_ptr ptr_type;
1425 struct __gmp_resolve_expr<mpq_t>
1427 typedef mpq_t value_type;
1428 typedef mpq_ptr ptr_type;
1432 struct __gmp_resolve_expr<mpf_t>
1434 typedef mpf_t value_type;
1435 typedef mpf_ptr ptr_type;
1439 struct __gmp_resolve_expr<mpz_t, mpq_t>
1441 typedef mpq_t value_type;
1445 struct __gmp_resolve_expr<mpq_t, mpz_t>
1447 typedef mpq_t value_type;
1451 struct __gmp_resolve_expr<mpz_t, mpf_t>
1453 typedef mpf_t value_type;
1457 struct __gmp_resolve_expr<mpf_t, mpz_t>
1459 typedef mpf_t value_type;
1463 struct __gmp_resolve_expr<mpq_t, mpf_t>
1465 typedef mpf_t value_type;
1469 struct __gmp_resolve_expr<mpf_t, mpq_t>
1471 typedef mpf_t value_type;
1476 template <class T, class U, class V>
1477 struct __gmp_resolve_temp
1479 typedef __gmp_expr<T, T> temp_type;
1483 struct __gmp_resolve_temp<T, T, T>
1485 typedef const __gmp_expr<T, T> & temp_type;
1489 // classes for evaluating unary and binary expressions
1490 template <class T, class Op>
1491 struct __gmp_unary_expr
1495 __gmp_unary_expr(const T &v) : val(v) { }
1500 template <class T, class U, class Op>
1501 struct __gmp_binary_expr
1503 typename __gmp_resolve_ref<T>::ref_type val1;
1504 typename __gmp_resolve_ref<U>::ref_type val2;
1506 __gmp_binary_expr(const T &v1, const U &v2) : val1(v1), val2(v2) { }
1508 __gmp_binary_expr();
1512 // functions for evaluating expressions
1513 template <class T, class U>
1514 void __gmp_set_expr(mpz_ptr, const __gmp_expr<T, U> &);
1515 template <class T, class U>
1516 void __gmp_set_expr(mpq_ptr, const __gmp_expr<T, U> &);
1517 template <class T, class U>
1518 void __gmp_set_expr(mpf_ptr, const __gmp_expr<T, U> &);
1521 /**************** Macros for in-class declarations ****************/
1522 /* This is just repetitive code that is easier to maintain if it's written
1525 #define __GMPP_DECLARE_COMPOUND_OPERATOR(fun) \
1526 template <class T, class U> \
1527 __gmp_expr<value_type, value_type> & fun(const __gmp_expr<T, U> &);
1529 #define __GMPN_DECLARE_COMPOUND_OPERATOR(fun) \
1530 __gmp_expr & fun(signed char); \
1531 __gmp_expr & fun(unsigned char); \
1532 __gmp_expr & fun(signed int); \
1533 __gmp_expr & fun(unsigned int); \
1534 __gmp_expr & fun(signed short int); \
1535 __gmp_expr & fun(unsigned short int); \
1536 __gmp_expr & fun(signed long int); \
1537 __gmp_expr & fun(unsigned long int); \
1538 __gmp_expr & fun(float); \
1539 __gmp_expr & fun(double); \
1540 __gmp_expr & fun(long double);
1542 #define __GMP_DECLARE_COMPOUND_OPERATOR(fun) \
1543 __GMPP_DECLARE_COMPOUND_OPERATOR(fun) \
1544 __GMPN_DECLARE_COMPOUND_OPERATOR(fun)
1546 #define __GMP_DECLARE_COMPOUND_OPERATOR_UI(fun) \
1547 __gmp_expr & fun(unsigned long int);
1549 #define __GMP_DECLARE_INCREMENT_OPERATOR(fun) \
1550 inline __gmp_expr & fun(); \
1551 inline __gmp_expr fun(int);
1554 /**************** mpz_class -- wrapper for mpz_t ****************/
1557 class __gmp_expr<mpz_t, mpz_t>
1560 typedef mpz_t value_type;
1563 unsigned long int get_prec() const { return mpf_get_default_prec(); }
1565 // constructors and destructor
1566 __gmp_expr() { mpz_init(mp); }
1568 __gmp_expr(const __gmp_expr &z) { mpz_init_set(mp, z.mp); }
1569 template <class T, class U>
1570 __gmp_expr(const __gmp_expr<T, U> &expr)
1571 { mpz_init(mp); __gmp_set_expr(mp, expr); }
1573 __gmp_expr(signed char c) { mpz_init_set_si(mp, c); }
1574 __gmp_expr(unsigned char c) { mpz_init_set_ui(mp, c); }
1576 __gmp_expr(signed int i) { mpz_init_set_si(mp, i); }
1577 __gmp_expr(unsigned int i) { mpz_init_set_ui(mp, i); }
1579 __gmp_expr(signed short int s) { mpz_init_set_si(mp, s); }
1580 __gmp_expr(unsigned short int s) { mpz_init_set_ui(mp, s); }
1582 __gmp_expr(signed long int l) { mpz_init_set_si(mp, l); }
1583 __gmp_expr(unsigned long int l) { mpz_init_set_ui(mp, l); }
1585 __gmp_expr(float f) { mpz_init_set_d(mp, f); }
1586 __gmp_expr(double d) { mpz_init_set_d(mp, d); }
1587 // __gmp_expr(long double ld) { mpz_init_set_d(mp, ld); }
1589 explicit __gmp_expr(const char *s)
1591 if (mpz_init_set_str (mp, s, 0) != 0)
1594 throw std::invalid_argument ("mpz_set_str");
1597 __gmp_expr(const char *s, int base)
1599 if (mpz_init_set_str (mp, s, base) != 0)
1602 throw std::invalid_argument ("mpz_set_str");
1605 explicit __gmp_expr(const std::string &s)
1607 if (mpz_init_set_str (mp, s.c_str(), 0) != 0)
1610 throw std::invalid_argument ("mpz_set_str");
1613 __gmp_expr(const std::string &s, int base)
1615 if (mpz_init_set_str(mp, s.c_str(), base) != 0)
1618 throw std::invalid_argument ("mpz_set_str");
1622 explicit __gmp_expr(mpz_srcptr z) { mpz_init_set(mp, z); }
1624 ~__gmp_expr() { mpz_clear(mp); }
1626 // assignment operators
1627 __gmp_expr & operator=(const __gmp_expr &z)
1628 { mpz_set(mp, z.mp); return *this; }
1629 template <class T, class U>
1630 __gmp_expr<value_type, value_type> & operator=(const __gmp_expr<T, U> &expr)
1631 { __gmp_set_expr(mp, expr); return *this; }
1633 __gmp_expr & operator=(signed char c) { mpz_set_si(mp, c); return *this; }
1634 __gmp_expr & operator=(unsigned char c) { mpz_set_ui(mp, c); return *this; }
1636 __gmp_expr & operator=(signed int i) { mpz_set_si(mp, i); return *this; }
1637 __gmp_expr & operator=(unsigned int i) { mpz_set_ui(mp, i); return *this; }
1639 __gmp_expr & operator=(signed short int s)
1640 { mpz_set_si(mp, s); return *this; }
1641 __gmp_expr & operator=(unsigned short int s)
1642 { mpz_set_ui(mp, s); return *this; }
1644 __gmp_expr & operator=(signed long int l)
1645 { mpz_set_si(mp, l); return *this; }
1646 __gmp_expr & operator=(unsigned long int l)
1647 { mpz_set_ui(mp, l); return *this; }
1649 __gmp_expr & operator=(float f) { mpz_set_d(mp, f); return *this; }
1650 __gmp_expr & operator=(double d) { mpz_set_d(mp, d); return *this; }
1651 // __gmp_expr & operator=(long double ld)
1652 // { mpz_set_ld(mp, ld); return *this; }
1654 __gmp_expr & operator=(const char *s)
1656 if (mpz_set_str (mp, s, 0) != 0)
1657 throw std::invalid_argument ("mpz_set_str");
1660 __gmp_expr & operator=(const std::string &s)
1662 if (mpz_set_str(mp, s.c_str(), 0) != 0)
1663 throw std::invalid_argument ("mpz_set_str");
1667 // string input/output functions
1668 int set_str(const char *s, int base)
1669 { return mpz_set_str(mp, s, base); }
1670 int set_str(const std::string &s, int base)
1671 { return mpz_set_str(mp, s.c_str(), base); }
1672 std::string get_str(int base = 10) const
1674 __gmp_alloc_cstring temp(mpz_get_str(0, base, mp));
1675 return std::string(temp.str);
1678 // conversion functions
1679 mpz_srcptr __get_mp() const { return mp; }
1680 mpz_ptr __get_mp() { return mp; }
1681 mpz_srcptr get_mpz_t() const { return mp; }
1682 mpz_ptr get_mpz_t() { return mp; }
1684 signed long int get_si() const { return mpz_get_si(mp); }
1685 unsigned long int get_ui() const { return mpz_get_ui(mp); }
1686 double get_d() const { return mpz_get_d(mp); }
1688 // bool fits_schar_p() const { return mpz_fits_schar_p(mp); }
1689 // bool fits_uchar_p() const { return mpz_fits_uchar_p(mp); }
1690 bool fits_sint_p() const { return mpz_fits_sint_p(mp); }
1691 bool fits_uint_p() const { return mpz_fits_uint_p(mp); }
1692 bool fits_sshort_p() const { return mpz_fits_sshort_p(mp); }
1693 bool fits_ushort_p() const { return mpz_fits_ushort_p(mp); }
1694 bool fits_slong_p() const { return mpz_fits_slong_p(mp); }
1695 bool fits_ulong_p() const { return mpz_fits_ulong_p(mp); }
1696 // bool fits_float_p() const { return mpz_fits_float_p(mp); }
1697 // bool fits_double_p() const { return mpz_fits_double_p(mp); }
1698 // bool fits_ldouble_p() const { return mpz_fits_ldouble_p(mp); }
1701 __GMP_DECLARE_COMPOUND_OPERATOR(operator+=)
1702 __GMP_DECLARE_COMPOUND_OPERATOR(operator-=)
1703 __GMP_DECLARE_COMPOUND_OPERATOR(operator*=)
1704 __GMP_DECLARE_COMPOUND_OPERATOR(operator/=)
1705 __GMP_DECLARE_COMPOUND_OPERATOR(operator%=)
1707 __GMPP_DECLARE_COMPOUND_OPERATOR(operator&=)
1708 __GMPP_DECLARE_COMPOUND_OPERATOR(operator|=)
1709 __GMPP_DECLARE_COMPOUND_OPERATOR(operator^=)
1711 __GMP_DECLARE_COMPOUND_OPERATOR_UI(operator<<=)
1712 __GMP_DECLARE_COMPOUND_OPERATOR_UI(operator>>=)
1714 __GMP_DECLARE_INCREMENT_OPERATOR(operator++)
1715 __GMP_DECLARE_INCREMENT_OPERATOR(operator--)
1718 typedef __gmp_expr<mpz_t, mpz_t> mpz_class;
1721 /**************** mpq_class -- wrapper for mpq_t ****************/
1724 class __gmp_expr<mpq_t, mpq_t>
1727 typedef mpq_t value_type;
1730 unsigned long int get_prec() const { return mpf_get_default_prec(); }
1731 void canonicalize() { mpq_canonicalize(mp); }
1733 // constructors and destructor
1734 __gmp_expr() { mpq_init(mp); }
1736 __gmp_expr(const __gmp_expr &q) { mpq_init(mp); mpq_set(mp, q.mp); }
1737 template <class T, class U>
1738 __gmp_expr(const __gmp_expr<T, U> &expr)
1739 { mpq_init(mp); __gmp_set_expr(mp, expr); }
1741 __gmp_expr(signed char c) { mpq_init(mp); mpq_set_si(mp, c, 1); }
1742 __gmp_expr(unsigned char c) { mpq_init(mp); mpq_set_ui(mp, c, 1); }
1744 __gmp_expr(signed int i) { mpq_init(mp); mpq_set_si(mp, i, 1); }
1745 __gmp_expr(unsigned int i) { mpq_init(mp); mpq_set_ui(mp, i, 1); }
1747 __gmp_expr(signed short int s) { mpq_init(mp); mpq_set_si(mp, s, 1); }
1748 __gmp_expr(unsigned short int s) { mpq_init(mp); mpq_set_ui(mp, s, 1); }
1750 __gmp_expr(signed long int l) { mpq_init(mp); mpq_set_si(mp, l, 1); }
1751 __gmp_expr(unsigned long int l) { mpq_init(mp); mpq_set_ui(mp, l, 1); }
1753 __gmp_expr(float f) { mpq_init(mp); mpq_set_d(mp, f); }
1754 __gmp_expr(double d) { mpq_init(mp); mpq_set_d(mp, d); }
1755 // __gmp_expr(long double ld) { mpq_init(mp); mpq_set_ld(mp, ld); }
1757 explicit __gmp_expr(const char *s)
1760 if (mpq_set_str (mp, s, 0) != 0)
1763 throw std::invalid_argument ("mpq_set_str");
1766 __gmp_expr(const char *s, int base)
1769 if (mpq_set_str(mp, s, base) != 0)
1772 throw std::invalid_argument ("mpq_set_str");
1775 explicit __gmp_expr(const std::string &s)
1778 if (mpq_set_str (mp, s.c_str(), 0) != 0)
1781 throw std::invalid_argument ("mpq_set_str");
1784 __gmp_expr(const std::string &s, int base)
1787 if (mpq_set_str (mp, s.c_str(), base) != 0)
1790 throw std::invalid_argument ("mpq_set_str");
1793 explicit __gmp_expr(mpq_srcptr q) { mpq_init(mp); mpq_set(mp, q); }
1795 __gmp_expr(const mpz_class &num, const mpz_class &den)
1798 mpz_set(mpq_numref(mp), num.get_mpz_t());
1799 mpz_set(mpq_denref(mp), den.get_mpz_t());
1802 ~__gmp_expr() { mpq_clear(mp); }
1804 // assignment operators
1805 __gmp_expr & operator=(const __gmp_expr &q)
1806 { mpq_set(mp, q.mp); return *this; }
1807 template <class T, class U>
1808 __gmp_expr<value_type, value_type> & operator=(const __gmp_expr<T, U> &expr)
1809 { __gmp_set_expr(mp, expr); return *this; }
1811 __gmp_expr & operator=(signed char c)
1812 { mpq_set_si(mp, c, 1); return *this; }
1813 __gmp_expr & operator=(unsigned char c)
1814 { mpq_set_ui(mp, c, 1); return *this; }
1816 __gmp_expr & operator=(signed int i) { mpq_set_si(mp, i, 1); return *this; }
1817 __gmp_expr & operator=(unsigned int i)
1818 { mpq_set_ui(mp, i, 1); return *this; }
1820 __gmp_expr & operator=(signed short int s)
1821 { mpq_set_si(mp, s, 1); return *this; }
1822 __gmp_expr & operator=(unsigned short int s)
1823 { mpq_set_ui(mp, s, 1); return *this; }
1825 __gmp_expr & operator=(signed long int l)
1826 { mpq_set_si(mp, l, 1); return *this; }
1827 __gmp_expr & operator=(unsigned long int l)
1828 { mpq_set_ui(mp, l, 1); return *this; }
1830 __gmp_expr & operator=(float f) { mpq_set_d(mp, f); return *this; }
1831 __gmp_expr & operator=(double d) { mpq_set_d(mp, d); return *this; }
1832 // __gmp_expr & operator=(long double ld)
1833 // { mpq_set_ld(mp, ld); return *this; }
1835 __gmp_expr & operator=(const char *s)
1837 if (mpq_set_str (mp, s, 0) != 0)
1838 throw std::invalid_argument ("mpq_set_str");
1841 __gmp_expr & operator=(const std::string &s)
1843 if (mpq_set_str(mp, s.c_str(), 0) != 0)
1844 throw std::invalid_argument ("mpq_set_str");
1848 // string input/output functions
1849 int set_str(const char *s, int base)
1850 { return mpq_set_str(mp, s, base); }
1851 int set_str(const std::string &s, int base)
1852 { return mpq_set_str(mp, s.c_str(), base); }
1853 std::string get_str(int base = 10) const
1855 __gmp_alloc_cstring temp(mpq_get_str(0, base, mp));
1856 return std::string(temp.str);
1859 // conversion functions
1861 // casting a reference to an mpz_t to mpz_class & is a dirty hack,
1862 // but works because the internal representation of mpz_class is
1864 const mpz_class & get_num() const
1865 { return reinterpret_cast<const mpz_class &>(*mpq_numref(mp)); }
1866 mpz_class & get_num()
1867 { return reinterpret_cast<mpz_class &>(*mpq_numref(mp)); }
1868 const mpz_class & get_den() const
1869 { return reinterpret_cast<const mpz_class &>(*mpq_denref(mp)); }
1870 mpz_class & get_den()
1871 { return reinterpret_cast<mpz_class &>(*mpq_denref(mp)); }
1873 mpq_srcptr __get_mp() const { return mp; }
1874 mpq_ptr __get_mp() { return mp; }
1875 mpq_srcptr get_mpq_t() const { return mp; }
1876 mpq_ptr get_mpq_t() { return mp; }
1878 mpz_srcptr get_num_mpz_t() const { return mpq_numref(mp); }
1879 mpz_ptr get_num_mpz_t() { return mpq_numref(mp); }
1880 mpz_srcptr get_den_mpz_t() const { return mpq_denref(mp); }
1881 mpz_ptr get_den_mpz_t() { return mpq_denref(mp); }
1883 double get_d() const { return mpq_get_d(mp); }
1885 // compound assignments
1886 __GMP_DECLARE_COMPOUND_OPERATOR(operator+=)
1887 __GMP_DECLARE_COMPOUND_OPERATOR(operator-=)
1888 __GMP_DECLARE_COMPOUND_OPERATOR(operator*=)
1889 __GMP_DECLARE_COMPOUND_OPERATOR(operator/=)
1891 __GMP_DECLARE_COMPOUND_OPERATOR_UI(operator<<=)
1892 __GMP_DECLARE_COMPOUND_OPERATOR_UI(operator>>=)
1894 __GMP_DECLARE_INCREMENT_OPERATOR(operator++)
1895 __GMP_DECLARE_INCREMENT_OPERATOR(operator--)
1898 typedef __gmp_expr<mpq_t, mpq_t> mpq_class;
1901 /**************** mpf_class -- wrapper for mpf_t ****************/
1904 class __gmp_expr<mpf_t, mpf_t>
1907 typedef mpf_t value_type;
1910 unsigned long int get_prec() const { return mpf_get_prec(mp); }
1912 void set_prec(unsigned long int prec) { mpf_set_prec(mp, prec); }
1913 void set_prec_raw(unsigned long int prec) { mpf_set_prec_raw(mp, prec); }
1915 // constructors and destructor
1916 __gmp_expr() { mpf_init(mp); }
1918 __gmp_expr(const __gmp_expr &f)
1919 { mpf_init2(mp, f.get_prec()); mpf_set(mp, f.mp); }
1920 __gmp_expr(const __gmp_expr &f, unsigned long int prec)
1921 { mpf_init2(mp, prec); mpf_set(mp, f.mp); }
1922 template <class T, class U>
1923 __gmp_expr(const __gmp_expr<T, U> &expr)
1924 { mpf_init2(mp, expr.get_prec()); __gmp_set_expr(mp, expr); }
1925 template <class T, class U>
1926 __gmp_expr(const __gmp_expr<T, U> &expr, unsigned long int prec)
1927 { mpf_init2(mp, prec); __gmp_set_expr(mp, expr); }
1929 __gmp_expr(signed char c) { mpf_init_set_si(mp, c); }
1930 __gmp_expr(signed char c, unsigned long int prec)
1931 { mpf_init2(mp, prec); mpf_set_si(mp, c); }
1932 __gmp_expr(unsigned char c) { mpf_init_set_ui(mp, c); }
1933 __gmp_expr(unsigned char c, unsigned long int prec)
1934 { mpf_init2(mp, prec); mpf_set_ui(mp, c); }
1936 __gmp_expr(signed int i) { mpf_init_set_si(mp, i); }
1937 __gmp_expr(signed int i, unsigned long int prec)
1938 { mpf_init2(mp, prec); mpf_set_si(mp, i); }
1939 __gmp_expr(unsigned int i) { mpf_init_set_ui(mp, i); }
1940 __gmp_expr(unsigned int i, unsigned long int prec)
1941 { mpf_init2(mp, prec); mpf_set_ui(mp, i); }
1943 __gmp_expr(signed short int s) { mpf_init_set_si(mp, s); }
1944 __gmp_expr(signed short int s, unsigned long int prec)
1945 { mpf_init2(mp, prec); mpf_set_si(mp, s); }
1946 __gmp_expr(unsigned short int s) { mpf_init_set_ui(mp, s); }
1947 __gmp_expr(unsigned short int s, unsigned long int prec)
1948 { mpf_init2(mp, prec); mpf_set_ui(mp, s); }
1950 __gmp_expr(signed long int l) { mpf_init_set_si(mp, l); }
1951 __gmp_expr(signed long int l, unsigned long int prec)
1952 { mpf_init2(mp, prec); mpf_set_si(mp, l); }
1953 __gmp_expr(unsigned long int l) { mpf_init_set_ui(mp, l); }
1954 __gmp_expr(unsigned long int l, unsigned long int prec)
1955 { mpf_init2(mp, prec); mpf_set_ui(mp, l); }
1957 __gmp_expr(float f) { mpf_init_set_d(mp, f); }
1958 __gmp_expr(float f, unsigned long int prec)
1959 { mpf_init2(mp, prec); mpf_set_d(mp, f); }
1960 __gmp_expr(double d) { mpf_init_set_d(mp, d); }
1961 __gmp_expr(double d, unsigned long int prec)
1962 { mpf_init2(mp, prec); mpf_set_d(mp, d); }
1963 // __gmp_expr(long double ld) { mpf_init_set_d(mp, ld); }
1964 // __gmp_expr(long double ld, unsigned long int prec)
1965 // { mpf_init2(mp, prec); mpf_set_d(mp, ld); }
1967 explicit __gmp_expr(const char *s)
1969 if (mpf_init_set_str (mp, s, 0) != 0)
1972 throw std::invalid_argument ("mpf_set_str");
1975 __gmp_expr(const char *s, unsigned long int prec, int base = 0)
1977 mpf_init2(mp, prec);
1978 if (mpf_set_str(mp, s, base) != 0)
1981 throw std::invalid_argument ("mpf_set_str");
1984 explicit __gmp_expr(const std::string &s)
1986 if (mpf_init_set_str(mp, s.c_str(), 0) != 0)
1989 throw std::invalid_argument ("mpf_set_str");
1992 __gmp_expr(const std::string &s, unsigned long int prec, int base = 0)
1994 mpf_init2(mp, prec);
1995 if (mpf_set_str(mp, s.c_str(), base) != 0)
1998 throw std::invalid_argument ("mpf_set_str");
2002 explicit __gmp_expr(mpf_srcptr f)
2003 { mpf_init2(mp, mpf_get_prec(f)); mpf_set(mp, f); }
2004 __gmp_expr(mpf_srcptr f, unsigned long int prec)
2005 { mpf_init2(mp, prec); mpf_set(mp, f); }
2007 ~__gmp_expr() { mpf_clear(mp); }
2009 // assignment operators
2010 __gmp_expr & operator=(const __gmp_expr &f)
2011 { mpf_set(mp, f.mp); return *this; }
2012 template <class T, class U>
2013 __gmp_expr<value_type, value_type> & operator=(const __gmp_expr<T, U> &expr)
2014 { __gmp_set_expr(mp, expr); return *this; }
2016 __gmp_expr & operator=(signed char c) { mpf_set_si(mp, c); return *this; }
2017 __gmp_expr & operator=(unsigned char c) { mpf_set_ui(mp, c); return *this; }
2019 __gmp_expr & operator=(signed int i) { mpf_set_si(mp, i); return *this; }
2020 __gmp_expr & operator=(unsigned int i) { mpf_set_ui(mp, i); return *this; }
2022 __gmp_expr & operator=(signed short int s)
2023 { mpf_set_si(mp, s); return *this; }
2024 __gmp_expr & operator=(unsigned short int s)
2025 { mpf_set_ui(mp, s); return *this; }
2027 __gmp_expr & operator=(signed long int l)
2028 { mpf_set_si(mp, l); return *this; }
2029 __gmp_expr & operator=(unsigned long int l)
2030 { mpf_set_ui(mp, l); return *this; }
2032 __gmp_expr & operator=(float f) { mpf_set_d(mp, f); return *this; }
2033 __gmp_expr & operator=(double d) { mpf_set_d(mp, d); return *this; }
2034 // __gmp_expr & operator=(long double ld)
2035 // { mpf_set_ld(mp, ld); return *this; }
2037 __gmp_expr & operator=(const char *s)
2039 if (mpf_set_str (mp, s, 0) != 0)
2040 throw std::invalid_argument ("mpf_set_str");
2043 __gmp_expr & operator=(const std::string &s)
2045 if (mpf_set_str(mp, s.c_str(), 0) != 0)
2046 throw std::invalid_argument ("mpf_set_str");
2050 // string input/output functions
2051 int set_str(const char *s, int base)
2052 { return mpf_set_str(mp, s, base); }
2053 int set_str(const std::string &s, int base)
2054 { return mpf_set_str(mp, s.c_str(), base); }
2055 std::string get_str(mp_exp_t &expo, int base = 10, size_t size = 0) const
2057 __gmp_alloc_cstring temp(mpf_get_str(0, &expo, base, size, mp));
2058 return std::string(temp.str);
2061 // conversion functions
2062 mpf_srcptr __get_mp() const { return mp; }
2063 mpf_ptr __get_mp() { return mp; }
2064 mpf_srcptr get_mpf_t() const { return mp; }
2065 mpf_ptr get_mpf_t() { return mp; }
2067 signed long int get_si() const { return mpf_get_si(mp); }
2068 unsigned long int get_ui() const { return mpf_get_ui(mp); }
2069 double get_d() const { return mpf_get_d(mp); }
2071 // bool fits_schar_p() const { return mpf_fits_schar_p(mp); }
2072 // bool fits_uchar_p() const { return mpf_fits_uchar_p(mp); }
2073 bool fits_sint_p() const { return mpf_fits_sint_p(mp); }
2074 bool fits_uint_p() const { return mpf_fits_uint_p(mp); }
2075 bool fits_sshort_p() const { return mpf_fits_sshort_p(mp); }
2076 bool fits_ushort_p() const { return mpf_fits_ushort_p(mp); }
2077 bool fits_slong_p() const { return mpf_fits_slong_p(mp); }
2078 bool fits_ulong_p() const { return mpf_fits_ulong_p(mp); }
2079 // bool fits_float_p() const { return mpf_fits_float_p(mp); }
2080 // bool fits_double_p() const { return mpf_fits_double_p(mp); }
2081 // bool fits_ldouble_p() const { return mpf_fits_ldouble_p(mp); }
2083 // compound assignments
2084 __GMP_DECLARE_COMPOUND_OPERATOR(operator+=)
2085 __GMP_DECLARE_COMPOUND_OPERATOR(operator-=)
2086 __GMP_DECLARE_COMPOUND_OPERATOR(operator*=)
2087 __GMP_DECLARE_COMPOUND_OPERATOR(operator/=)
2089 __GMP_DECLARE_COMPOUND_OPERATOR_UI(operator<<=)
2090 __GMP_DECLARE_COMPOUND_OPERATOR_UI(operator>>=)
2092 __GMP_DECLARE_INCREMENT_OPERATOR(operator++)
2093 __GMP_DECLARE_INCREMENT_OPERATOR(operator--)
2096 typedef __gmp_expr<mpf_t, mpf_t> mpf_class;
2100 /**************** I/O operators ****************/
2102 // these should (and will) be provided separately
2105 inline std::ostream & operator<<
2106 (std::ostream &o, const __gmp_expr<T, T> &expr)
2108 return o << expr.__get_mp();
2111 template <class T, class U>
2112 inline std::ostream & operator<<
2113 (std::ostream &o, const __gmp_expr<T, U> &expr)
2115 __gmp_expr<T, T> temp(expr);
2116 return o << temp.__get_mp();
2121 inline std::istream & operator>>(std::istream &i, __gmp_expr<T, T> &expr)
2123 return i >> expr.__get_mp();
2126 inline std::istream & operator>>(std::istream &i, mpq_class &q)
2129 // q.canonicalize(); // you might want to uncomment this
2134 /**************** Functions for type conversion ****************/
2137 inline void __gmp_set_expr(mpz_ptr z, const mpz_class &w)
2139 mpz_set(z, w.get_mpz_t());
2143 inline void __gmp_set_expr(mpz_ptr z, const __gmp_expr<mpz_t, T> &expr)
2149 inline void __gmp_set_expr(mpz_ptr z, const mpq_class &q)
2151 mpz_set_q(z, q.get_mpq_t());
2155 inline void __gmp_set_expr(mpz_ptr z, const __gmp_expr<mpq_t, T> &expr)
2157 mpq_class temp(expr);
2158 mpz_set_q(z, temp.get_mpq_t());
2162 inline void __gmp_set_expr(mpz_ptr z, const mpf_class &f)
2164 mpz_set_f(z, f.get_mpf_t());
2168 inline void __gmp_set_expr(mpz_ptr z, const __gmp_expr<mpf_t, T> &expr)
2170 mpf_class temp(expr);
2171 mpz_set_f(z, temp.get_mpf_t());
2175 inline void __gmp_set_expr(mpq_ptr q, const mpz_class &z)
2177 mpq_set_z(q, z.get_mpz_t());
2181 inline void __gmp_set_expr(mpq_ptr q, const __gmp_expr<mpz_t, T> &expr)
2183 mpz_class temp(expr);
2184 mpq_set_z(q, temp.get_mpz_t());
2188 inline void __gmp_set_expr(mpq_ptr q, const mpq_class &r)
2190 mpq_set(q, r.get_mpq_t());
2194 inline void __gmp_set_expr(mpq_ptr q, const __gmp_expr<mpq_t, T> &expr)
2200 inline void __gmp_set_expr(mpq_ptr q, const mpf_class &f)
2202 mpq_set_f(q, f.get_mpf_t());
2206 inline void __gmp_set_expr(mpq_ptr q, const __gmp_expr<mpf_t, T> &expr)
2208 mpf_class temp(expr);
2209 mpq_set_f(q, temp.get_mpf_t());
2213 inline void __gmp_set_expr(mpf_ptr f, const mpz_class &z)
2215 mpf_set_z(f, z.get_mpz_t());
2219 inline void __gmp_set_expr(mpf_ptr f, const __gmp_expr<mpz_t, T> &expr)
2221 mpz_class temp(expr);
2222 mpf_set_z(f, temp.get_mpz_t());
2226 inline void __gmp_set_expr(mpf_ptr f, const mpq_class &q)
2228 mpf_set_q(f, q.get_mpq_t());
2232 inline void __gmp_set_expr(mpf_ptr f, const __gmp_expr<mpq_t, T> &expr)
2234 mpq_class temp(expr);
2235 mpf_set_q(f, temp.get_mpq_t());
2239 inline void __gmp_set_expr(mpf_ptr f, const mpf_class &g)
2241 mpf_set(f, g.get_mpf_t());
2245 inline void __gmp_set_expr(mpf_ptr f, const __gmp_expr<mpf_t, T> &expr)
2247 expr.eval(f, mpf_get_prec(f));
2251 /**************** Specializations of __gmp_expr ****************/
2252 /* The eval() method of __gmp_expr<T, U> evaluates the corresponding
2253 expression and assigns the result to its argument, which is either an
2254 mpz_t, mpq_t, or mpf_t as specified by the T argument.
2255 Compound expressions are evaluated recursively (temporaries are created
2256 to hold intermediate values), while for simple expressions the eval()
2257 method of the appropriate function object (available as the Op argument
2258 of either __gmp_unary_expr<T, Op> or __gmp_binary_expr<T, U, Op>) is
2262 /**************** Unary expressions ****************/
2264 - simple: argument is mp*_class, that is, __gmp_expr<T, T>
2265 - compound: argument is __gmp_expr<T, U> (with U not equal to T) */
2268 // simple expressions
2270 template <class T, class Op>
2271 class __gmp_expr<T, __gmp_unary_expr<__gmp_expr<T, T>, Op> >
2274 typedef __gmp_expr<T, T> val_type;
2276 __gmp_unary_expr<val_type, Op> expr;
2278 __gmp_expr(const val_type &val) : expr(val) { }
2279 void eval(typename __gmp_resolve_expr<T>::ptr_type p,
2280 unsigned long int = 0) const
2281 { Op::eval(p, expr.val.__get_mp()); }
2282 const val_type & get_val() const { return expr.val; }
2283 unsigned long int get_prec() const { return expr.val.get_prec(); }
2287 // compound expressions
2289 template <class T, class U, class Op>
2290 class __gmp_expr<T, __gmp_unary_expr<__gmp_expr<T, U>, Op> >
2293 typedef __gmp_expr<T, U> val_type;
2295 __gmp_unary_expr<val_type, Op> expr;
2297 __gmp_expr(const val_type &val) : expr(val) { }
2298 void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
2299 { __gmp_expr<T, T> temp(expr.val); Op::eval(p, temp.__get_mp()); }
2300 void eval(typename __gmp_resolve_expr<T>::ptr_type p,
2301 unsigned long int prec) const
2302 { __gmp_expr<T, T> temp(expr.val, prec); Op::eval(p, temp.__get_mp()); }
2303 const val_type & get_val() const { return expr.val; }
2304 unsigned long int get_prec() const { return expr.val.get_prec(); }
2308 /**************** Binary expressions ****************/
2310 - arguments are both mp*_class
2311 - one argument is mp*_class, one is a built-in type
2313 - one is mp*_class, one is __gmp_expr<T, U>
2314 - one is __gmp_expr<T, U>, one is built-in
2315 - both arguments are __gmp_expr<...> */
2318 // simple expressions
2320 template <class T, class Op>
2322 <T, __gmp_binary_expr<__gmp_expr<T, T>, __gmp_expr<T, T>, Op> >
2325 typedef __gmp_expr<T, T> val1_type;
2326 typedef __gmp_expr<T, T> val2_type;
2328 __gmp_binary_expr<val1_type, val2_type, Op> expr;
2330 __gmp_expr(const val1_type &val1, const val2_type &val2)
2331 : expr(val1, val2) { }
2332 void eval(typename __gmp_resolve_expr<T>::ptr_type p,
2333 unsigned long int = 0) const
2334 { Op::eval(p, expr.val1.__get_mp(), expr.val2.__get_mp()); }
2335 const val1_type & get_val1() const { return expr.val1; }
2336 const val2_type & get_val2() const { return expr.val2; }
2337 unsigned long int get_prec() const
2339 unsigned long int prec1 = expr.val1.get_prec(),
2340 prec2 = expr.val2.get_prec();
2341 return (prec1 > prec2) ? prec1 : prec2;
2346 // simple expressions, T is a built-in numerical type
2348 template <class T, class U, class Op>
2349 class __gmp_expr<T, __gmp_binary_expr<__gmp_expr<T, T>, U, Op> >
2352 typedef __gmp_expr<T, T> val1_type;
2353 typedef U val2_type;
2355 __gmp_binary_expr<val1_type, val2_type, Op> expr;
2357 __gmp_expr(const val1_type &val1, const val2_type &val2)
2358 : expr(val1, val2) { }
2359 void eval(typename __gmp_resolve_expr<T>::ptr_type p,
2360 unsigned long int = 0) const
2361 { Op::eval(p, expr.val1.__get_mp(), expr.val2); }
2362 const val1_type & get_val1() const { return expr.val1; }
2363 const val2_type & get_val2() const { return expr.val2; }
2364 unsigned long int get_prec() const { return expr.val1.get_prec(); }
2367 template <class T, class U, class Op>
2368 class __gmp_expr<T, __gmp_binary_expr<U, __gmp_expr<T, T>, Op> >
2371 typedef U val1_type;
2372 typedef __gmp_expr<T, T> val2_type;
2374 __gmp_binary_expr<val1_type, val2_type, Op> expr;
2376 __gmp_expr(const val1_type &val1, const val2_type &val2)
2377 : expr(val1, val2) { }
2378 void eval(typename __gmp_resolve_expr<T>::ptr_type p,
2379 unsigned long int = 0) const
2380 { Op::eval(p, expr.val1, expr.val2.__get_mp()); }
2381 const val1_type & get_val1() const { return expr.val1; }
2382 const val2_type & get_val2() const { return expr.val2; }
2383 unsigned long int get_prec() const { return expr.val2.get_prec(); }
2387 // compound expressions, one argument is a subexpression
2389 template <class T, class U, class V, class Op>
2391 <T, __gmp_binary_expr<__gmp_expr<T, T>, __gmp_expr<U, V>, Op> >
2394 typedef __gmp_expr<T, T> val1_type;
2395 typedef __gmp_expr<U, V> val2_type;
2397 __gmp_binary_expr<val1_type, val2_type, Op> expr;
2399 __gmp_expr(const val1_type &val1, const val2_type &val2)
2400 : expr(val1, val2) { }
2401 void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
2403 __gmp_expr<T, T> temp(expr.val2);
2404 Op::eval(p, expr.val1.__get_mp(), temp.__get_mp());
2406 void eval(typename __gmp_resolve_expr<T>::ptr_type p,
2407 unsigned long int prec) const
2409 __gmp_expr<T, T> temp(expr.val2, prec);
2410 Op::eval(p, expr.val1.__get_mp(), temp.__get_mp());
2412 const val1_type & get_val1() const { return expr.val1; }
2413 const val2_type & get_val2() const { return expr.val2; }
2414 unsigned long int get_prec() const
2416 unsigned long int prec1 = expr.val1.get_prec(),
2417 prec2 = expr.val2.get_prec();
2418 return (prec1 > prec2) ? prec1 : prec2;
2422 template <class T, class U, class V, class Op>
2424 <T, __gmp_binary_expr<__gmp_expr<U, V>, __gmp_expr<T, T>, Op> >
2427 typedef __gmp_expr<U, V> val1_type;
2428 typedef __gmp_expr<T, T> val2_type;
2430 __gmp_binary_expr<val1_type, val2_type, Op> expr;
2432 __gmp_expr(const val1_type &val1, const val2_type &val2)
2433 : expr(val1, val2) { }
2434 void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
2436 __gmp_expr<T, T> temp(expr.val1);
2437 Op::eval(p, temp.__get_mp(), expr.val2.__get_mp());
2439 void eval(typename __gmp_resolve_expr<T>::ptr_type p,
2440 unsigned long int prec) const
2442 __gmp_expr<T, T> temp(expr.val1, prec);
2443 Op::eval(p, temp.__get_mp(), expr.val2.__get_mp());
2445 const val1_type & get_val1() const { return expr.val1; }
2446 const val2_type & get_val2() const { return expr.val2; }
2447 unsigned long int get_prec() const
2449 unsigned long int prec1 = expr.val1.get_prec(),
2450 prec2 = expr.val2.get_prec();
2451 return (prec1 > prec2) ? prec1 : prec2;
2455 template <class T, class U, class Op>
2457 <T, __gmp_binary_expr<__gmp_expr<T, T>, __gmp_expr<T, U>, Op> >
2460 typedef __gmp_expr<T, T> val1_type;
2461 typedef __gmp_expr<T, U> 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_expr<T, T> temp(expr.val2);
2470 Op::eval(p, expr.val1.__get_mp(), temp.__get_mp());
2472 void eval(typename __gmp_resolve_expr<T>::ptr_type p,
2473 unsigned long int prec) const
2475 __gmp_expr<T, T> temp(expr.val2, prec);
2476 Op::eval(p, expr.val1.__get_mp(), temp.__get_mp());
2478 const val1_type & get_val1() const { return expr.val1; }
2479 const val2_type & get_val2() const { return expr.val2; }
2480 unsigned long int get_prec() const
2482 unsigned long int prec1 = expr.val1.get_prec(),
2483 prec2 = expr.val2.get_prec();
2484 return (prec1 > prec2) ? prec1 : prec2;
2488 template <class T, class U, class Op>
2490 <T, __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<T, T>, Op> >
2493 typedef __gmp_expr<T, U> val1_type;
2494 typedef __gmp_expr<T, T> val2_type;
2496 __gmp_binary_expr<val1_type, val2_type, Op> expr;
2498 __gmp_expr(const val1_type &val1, const val2_type &val2)
2499 : expr(val1, val2) { }
2500 void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
2502 __gmp_expr<T, T> temp(expr.val1);
2503 Op::eval(p, temp.__get_mp(), expr.val2.__get_mp());
2505 void eval(typename __gmp_resolve_expr<T>::ptr_type p,
2506 unsigned long int prec) const
2508 __gmp_expr<T, T> temp(expr.val1, prec);
2509 Op::eval(p, temp.__get_mp(), expr.val2.__get_mp());
2511 const val1_type & get_val1() const { return expr.val1; }
2512 const val2_type & get_val2() const { return expr.val2; }
2513 unsigned long int get_prec() const
2515 unsigned long int prec1 = expr.val1.get_prec(),
2516 prec2 = expr.val2.get_prec();
2517 return (prec1 > prec2) ? prec1 : prec2;
2522 // one argument is a subexpression, one is a built-in
2524 template <class T, class U, class V, class Op>
2525 class __gmp_expr<T, __gmp_binary_expr<__gmp_expr<T, U>, V, Op> >
2528 typedef __gmp_expr<T, U> val1_type;
2529 typedef V val2_type;
2531 __gmp_binary_expr<val1_type, val2_type, Op> expr;
2533 __gmp_expr(const val1_type &val1, const val2_type &val2)
2534 : expr(val1, val2) { }
2535 void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
2537 __gmp_expr<T, T> temp(expr.val1);
2538 Op::eval(p, temp.__get_mp(), expr.val2);
2540 void eval(typename __gmp_resolve_expr<T>::ptr_type p,
2541 unsigned long int prec) const
2543 __gmp_expr<T, T> temp(expr.val1, prec);
2544 Op::eval(p, temp.__get_mp(), expr.val2);
2546 const val1_type & get_val1() const { return expr.val1; }
2547 const val2_type & get_val2() const { return expr.val2; }
2548 unsigned long int get_prec() const { return expr.val1.get_prec(); }
2551 template <class T, class U, class V, class Op>
2552 class __gmp_expr<T, __gmp_binary_expr<U, __gmp_expr<T, V>, Op> >
2555 typedef U val1_type;
2556 typedef __gmp_expr<T, V> val2_type;
2558 __gmp_binary_expr<val1_type, val2_type, Op> expr;
2560 __gmp_expr(const val1_type &val1, const val2_type &val2)
2561 : expr(val1, val2) { }
2562 void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
2564 __gmp_expr<T, T> temp(expr.val2);
2565 Op::eval(p, expr.val1, temp.__get_mp());
2567 void eval(typename __gmp_resolve_expr<T>::ptr_type p,
2568 unsigned long int prec) const
2570 __gmp_expr<T, T> temp(expr.val2, prec);
2571 Op::eval(p, expr.val1, temp.__get_mp());
2573 const val1_type & get_val1() const { return expr.val1; }
2574 const val2_type & get_val2() const { return expr.val2; }
2575 unsigned long int get_prec() const { return expr.val2.get_prec(); }
2579 // both arguments are subexpressions
2581 template <class T, class U, class V, class W, class Op>
2583 <T, __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<V, W>, Op> >
2586 typedef __gmp_expr<T, U> val1_type;
2587 typedef __gmp_expr<V, W> val2_type;
2589 __gmp_binary_expr<val1_type, val2_type, Op> expr;
2591 __gmp_expr(const val1_type &val1, const val2_type &val2)
2592 : expr(val1, val2) { }
2593 void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
2595 __gmp_expr<T, T> temp1(expr.val1), temp2(expr.val2);
2596 Op::eval(p, temp1.__get_mp(), temp2.__get_mp());
2598 void eval(typename __gmp_resolve_expr<T>::ptr_type p,
2599 unsigned long int prec) const
2601 __gmp_expr<T, T> temp1(expr.val1, prec), temp2(expr.val2, prec);
2602 Op::eval(p, temp1.__get_mp(), temp2.__get_mp());
2604 const val1_type & get_val1() const { return expr.val1; }
2605 const val2_type & get_val2() const { return expr.val2; }
2606 unsigned long int get_prec() const
2608 unsigned long int prec1 = expr.val1.get_prec(),
2609 prec2 = expr.val2.get_prec();
2610 return (prec1 > prec2) ? prec1 : prec2;
2614 template <class T, class U, class V, class W, class Op>
2616 <T, __gmp_binary_expr<__gmp_expr<U, V>, __gmp_expr<T, W>, Op> >
2619 typedef __gmp_expr<U, V> val1_type;
2620 typedef __gmp_expr<T, W> val2_type;
2622 __gmp_binary_expr<val1_type, val2_type, Op> expr;
2624 __gmp_expr(const val1_type &val1, const val2_type &val2)
2625 : expr(val1, val2) { }
2626 void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
2628 __gmp_expr<T, T> temp1(expr.val1), temp2(expr.val2);
2629 Op::eval(p, temp1.__get_mp(), temp2.__get_mp());
2631 void eval(typename __gmp_resolve_expr<T>::ptr_type p,
2632 unsigned long int prec) const
2634 __gmp_expr<T, T> temp1(expr.val1, prec), temp2(expr.val2, prec);
2635 Op::eval(p, temp1.__get_mp(), temp2.__get_mp());
2637 const val1_type & get_val1() const { return expr.val1; }
2638 const val2_type & get_val2() const { return expr.val2; }
2639 unsigned long int get_prec() const
2641 unsigned long int prec1 = expr.val1.get_prec(),
2642 prec2 = expr.val2.get_prec();
2643 return (prec1 > prec2) ? prec1 : prec2;
2647 template <class T, class U, class V, class Op>
2649 <T, __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<T, V>, Op> >
2652 typedef __gmp_expr<T, U> val1_type;
2653 typedef __gmp_expr<T, V> val2_type;
2655 __gmp_binary_expr<val1_type, val2_type, Op> expr;
2657 __gmp_expr(const val1_type &val1, const val2_type &val2)
2658 : expr(val1, val2) { }
2659 void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
2661 __gmp_expr<T, T> temp1(expr.val1), temp2(expr.val2);
2662 Op::eval(p, temp1.__get_mp(), temp2.__get_mp());
2664 void eval(typename __gmp_resolve_expr<T>::ptr_type p,
2665 unsigned long int prec) const
2667 __gmp_expr<T, T> temp1(expr.val1, prec), temp2(expr.val2, prec);
2668 Op::eval(p, temp1.__get_mp(), temp2.__get_mp());
2670 const val1_type & get_val1() const { return expr.val1; }
2671 const val2_type & get_val2() const { return expr.val2; }
2672 unsigned long int get_prec() const
2674 unsigned long int prec1 = expr.val1.get_prec(),
2675 prec2 = expr.val2.get_prec();
2676 return (prec1 > prec2) ? prec1 : prec2;
2681 /**************** Special cases ****************/
2683 /* Some operations (i.e., add and subtract) with mixed mpz/mpq arguments
2684 can be done directly without first converting the mpz to mpq.
2685 Appropriate specializations of __gmp_expr are required. */
2688 #define __GMPZQ_DEFINE_EXPR(eval_fun) \
2691 class __gmp_expr<mpq_t, __gmp_binary_expr<mpz_class, mpq_class, eval_fun> > \
2694 typedef mpz_class val1_type; \
2695 typedef mpq_class val2_type; \
2697 __gmp_binary_expr<val1_type, val2_type, eval_fun> expr; \
2699 __gmp_expr(const val1_type &val1, const val2_type &val2) \
2700 : expr(val1, val2) { } \
2701 void eval(mpq_ptr q) const \
2702 { eval_fun::eval(q, expr.val1.get_mpz_t(), expr.val2.get_mpq_t()); } \
2703 const val1_type & get_val1() const { return expr.val1; } \
2704 const val2_type & get_val2() const { return expr.val2; } \
2705 unsigned long int get_prec() const { return mpf_get_default_prec(); } \
2709 class __gmp_expr<mpq_t, __gmp_binary_expr<mpq_class, mpz_class, eval_fun> > \
2712 typedef mpq_class val1_type; \
2713 typedef mpz_class val2_type; \
2715 __gmp_binary_expr<val1_type, val2_type, eval_fun> expr; \
2717 __gmp_expr(const val1_type &val1, const val2_type &val2) \
2718 : expr(val1, val2) { } \
2719 void eval(mpq_ptr q) const \
2720 { eval_fun::eval(q, expr.val1.get_mpq_t(), expr.val2.get_mpz_t()); } \
2721 const val1_type & get_val1() const { return expr.val1; } \
2722 const val2_type & get_val2() const { return expr.val2; } \
2723 unsigned long int get_prec() const { return mpf_get_default_prec(); } \
2726 template <class T> \
2728 <mpq_t, __gmp_binary_expr<mpz_class, __gmp_expr<mpq_t, T>, eval_fun> > \
2731 typedef mpz_class val1_type; \
2732 typedef __gmp_expr<mpq_t, T> val2_type; \
2734 __gmp_binary_expr<val1_type, val2_type, eval_fun> expr; \
2736 __gmp_expr(const val1_type &val1, const val2_type &val2) \
2737 : expr(val1, val2) { } \
2738 void eval(mpq_ptr q) const \
2740 mpq_class temp(expr.val2); \
2741 eval_fun::eval(q, expr.val1.get_mpz_t(), temp.get_mpq_t()); \
2743 const val1_type & get_val1() const { return expr.val1; } \
2744 const val2_type & get_val2() const { return expr.val2; } \
2745 unsigned long int get_prec() const { return mpf_get_default_prec(); } \
2748 template <class T> \
2750 <mpq_t, __gmp_binary_expr<mpq_class, __gmp_expr<mpz_t, T>, eval_fun> > \
2753 typedef mpq_class val1_type; \
2754 typedef __gmp_expr<mpz_t, T> val2_type; \
2756 __gmp_binary_expr<val1_type, val2_type, eval_fun> expr; \
2758 __gmp_expr(const val1_type &val1, const val2_type &val2) \
2759 : expr(val1, val2) { } \
2760 void eval(mpq_ptr q) const \
2762 mpz_class temp(expr.val2); \
2763 eval_fun::eval(q, expr.val1.get_mpq_t(), temp.get_mpz_t()); \
2765 const val1_type & get_val1() const { return expr.val1; } \
2766 const val2_type & get_val2() const { return expr.val2; } \
2767 unsigned long int get_prec() const { return mpf_get_default_prec(); } \
2770 template <class T> \
2772 <mpq_t, __gmp_binary_expr<__gmp_expr<mpz_t, T>, mpq_class, eval_fun> > \
2775 typedef __gmp_expr<mpz_t, T> val1_type; \
2776 typedef mpq_class val2_type; \
2778 __gmp_binary_expr<val1_type, val2_type, eval_fun> expr; \
2780 __gmp_expr(const val1_type &val1, const val2_type &val2) \
2781 : expr(val1, val2) { } \
2782 void eval(mpq_ptr q) const \
2784 mpz_class temp(expr.val1); \
2785 eval_fun::eval(q, temp.get_mpz_t(), expr.val2.get_mpq_t()); \
2787 const val1_type & get_val1() const { return expr.val1; } \
2788 const val2_type & get_val2() const { return expr.val2; } \
2789 unsigned long int get_prec() const { return mpf_get_default_prec(); } \
2792 template <class T> \
2794 <mpq_t, __gmp_binary_expr<__gmp_expr<mpq_t, T>, mpz_class, eval_fun> > \
2797 typedef __gmp_expr<mpq_t, T> val1_type; \
2798 typedef mpz_class val2_type; \
2800 __gmp_binary_expr<val1_type, val2_type, eval_fun> expr; \
2802 __gmp_expr(const val1_type &val1, const val2_type &val2) \
2803 : expr(val1, val2) { } \
2804 void eval(mpq_ptr q) const \
2806 mpq_class temp(expr.val1); \
2807 eval_fun::eval(q, temp.get_mpq_t(), expr.val2.get_mpz_t()); \
2809 const val1_type & get_val1() const { return expr.val1; } \
2810 const val2_type & get_val2() const { return expr.val2; } \
2811 unsigned long int get_prec() const { return mpf_get_default_prec(); } \
2814 template <class T, class U> \
2815 class __gmp_expr<mpq_t, __gmp_binary_expr \
2816 <__gmp_expr<mpz_t, T>, __gmp_expr<mpq_t, U>, eval_fun> > \
2819 typedef __gmp_expr<mpz_t, T> val1_type; \
2820 typedef __gmp_expr<mpq_t, U> val2_type; \
2822 __gmp_binary_expr<val1_type, val2_type, eval_fun> expr; \
2824 __gmp_expr(const val1_type &val1, const val2_type &val2) \
2825 : expr(val1, val2) { } \
2826 void eval(mpq_ptr q) const \
2828 mpz_class temp1(expr.val1); \
2829 mpq_class temp2(expr.val2); \
2830 eval_fun::eval(q, temp1.get_mpz_t(), temp2.get_mpq_t()); \
2832 const val1_type & get_val1() const { return expr.val1; } \
2833 const val2_type & get_val2() const { return expr.val2; } \
2834 unsigned long int get_prec() const { return mpf_get_default_prec(); } \
2837 template <class T, class U> \
2838 class __gmp_expr<mpq_t, __gmp_binary_expr \
2839 <__gmp_expr<mpq_t, T>, __gmp_expr<mpz_t, U>, eval_fun> > \
2842 typedef __gmp_expr<mpq_t, T> val1_type; \
2843 typedef __gmp_expr<mpz_t, U> val2_type; \
2845 __gmp_binary_expr<val1_type, val2_type, eval_fun> expr; \
2847 __gmp_expr(const val1_type &val1, const val2_type &val2) \
2848 : expr(val1, val2) { } \
2849 void eval(mpq_ptr q) const \
2851 mpq_class temp1(expr.val1); \
2852 mpz_class temp2(expr.val2); \
2853 eval_fun::eval(q, temp1.get_mpq_t(), temp2.get_mpz_t()); \
2855 const val1_type & get_val1() const { return expr.val1; } \
2856 const val2_type & get_val2() const { return expr.val2; } \
2857 unsigned long int get_prec() const { return mpf_get_default_prec(); } \
2861 __GMPZQ_DEFINE_EXPR(__gmp_binary_plus)
2862 __GMPZQ_DEFINE_EXPR(__gmp_binary_minus)
2865 /* Integer ternary expressions of the kind `a+b*c' or `a*b+c' can be
2866 evaluated directly via mpz_addmul */
2869 #define __GMP_DEFINE_TERNARY_EXPR(eval_fun1, eval_fun2, eval_both) \
2872 class __gmp_expr<mpz_t, __gmp_binary_expr<mpz_class, __gmp_expr \
2873 <mpz_t, __gmp_binary_expr<mpz_class, mpz_class, eval_fun1> >, eval_fun2> > \
2876 typedef mpz_class val1_type; \
2877 typedef __gmp_expr \
2878 <mpz_t, __gmp_binary_expr<mpz_class, mpz_class, eval_fun1> > val2_type; \
2880 __gmp_binary_expr<val1_type, val2_type, eval_fun2> expr; \
2882 __gmp_expr(const val1_type &val1, const val2_type &val2) \
2883 : expr(val1, val2) { } \
2884 void eval(mpz_ptr z) const \
2886 (z, expr.val1.get_mpz_t(), expr.val2.get_val1().get_mpz_t(), \
2887 expr.val2.get_val2().get_mpz_t()); } \
2888 const val1_type & get_val1() const { return expr.val1; } \
2889 const val2_type & get_val2() const { return expr.val2; } \
2890 unsigned long int get_prec() const { return mpf_get_default_prec(); } \
2893 template <class T> \
2894 class __gmp_expr<mpz_t, __gmp_binary_expr<mpz_class, __gmp_expr \
2895 <mpz_t, __gmp_binary_expr<mpz_class, T, eval_fun1> >, eval_fun2> > \
2898 typedef mpz_class val1_type; \
2899 typedef __gmp_expr \
2900 <mpz_t, __gmp_binary_expr<mpz_class, T, eval_fun1> > val2_type; \
2902 __gmp_binary_expr<val1_type, val2_type, eval_fun2> expr; \
2904 __gmp_expr(const val1_type &val1, const val2_type &val2) \
2905 : expr(val1, val2) { } \
2906 void eval(mpz_ptr z) const \
2908 (z, expr.val1.get_mpz_t(), expr.val2.get_val1().get_mpz_t(), \
2909 expr.val2.get_val2()); } \
2910 const val1_type & get_val1() const { return expr.val1; } \
2911 const val2_type & get_val2() const { return expr.val2; } \
2912 unsigned long int get_prec() const { return mpf_get_default_prec(); } \
2915 template <class T> \
2916 class __gmp_expr<mpz_t, __gmp_binary_expr<mpz_class, __gmp_expr \
2917 <mpz_t, __gmp_binary_expr<T, mpz_class, eval_fun1> >, eval_fun2> > \
2920 typedef mpz_class val1_type; \
2921 typedef __gmp_expr \
2922 <mpz_t, __gmp_binary_expr<T, mpz_class, eval_fun1> > val2_type; \
2924 __gmp_binary_expr<val1_type, val2_type, eval_fun2> expr; \
2926 __gmp_expr(const val1_type &val1, const val2_type &val2) \
2927 : expr(val1, val2) { } \
2928 void eval(mpz_ptr z) const \
2930 (z, expr.val1.get_mpz_t(), expr.val2.get_val1(), \
2931 expr.val2.get_val2().get_mpz_t()); } \
2932 const val1_type & get_val1() const { return expr.val1; } \
2933 const val2_type & get_val2() const { return expr.val2; } \
2934 unsigned long int get_prec() const { return mpf_get_default_prec(); } \
2937 template <class T> \
2938 class __gmp_expr<mpz_t, __gmp_binary_expr<mpz_class, __gmp_expr \
2939 <mpz_t, __gmp_binary_expr<mpz_class, __gmp_expr<mpz_t, T>, eval_fun1> >, \
2943 typedef mpz_class val1_type; \
2944 typedef __gmp_expr<mpz_t, __gmp_binary_expr \
2945 <mpz_class, __gmp_expr<mpz_t, T>, eval_fun1> > val2_type; \
2947 __gmp_binary_expr<val1_type, val2_type, eval_fun2> expr; \
2949 __gmp_expr(const val1_type &val1, const val2_type &val2) \
2950 : expr(val1, val2) { } \
2951 void eval(mpz_ptr z) const \
2953 mpz_class temp(expr.val2.get_val2()); \
2955 (z, expr.val1.get_mpz_t(), expr.val2.get_val1().get_mpz_t(), \
2956 temp.get_mpz_t()); \
2958 const val1_type & get_val1() const { return expr.val1; } \
2959 const val2_type & get_val2() const { return expr.val2; } \
2960 unsigned long int get_prec() const { return mpf_get_default_prec(); } \
2963 template <class T> \
2964 class __gmp_expr<mpz_t, __gmp_binary_expr<mpz_class, __gmp_expr \
2965 <mpz_t, __gmp_binary_expr<__gmp_expr<mpz_t, T>, mpz_class, eval_fun1> >, \
2969 typedef mpz_class val1_type; \
2970 typedef __gmp_expr<mpz_t, __gmp_binary_expr \
2971 <__gmp_expr<mpz_t, T>, mpz_class, eval_fun1> > val2_type; \
2973 __gmp_binary_expr<val1_type, val2_type, eval_fun2> expr; \
2975 __gmp_expr(const val1_type &val1, const val2_type &val2) \
2976 : expr(val1, val2) { } \
2977 void eval(mpz_ptr z) const \
2979 mpz_class temp(expr.val2.get_val1()); \
2980 eval_both::eval(z, expr.val1.get_mpz_t(), temp.get_mpz_t(), \
2981 expr.val2.get_val2().get_mpz_t()); \
2983 const val1_type & get_val1() const { return expr.val1; } \
2984 const val2_type & get_val2() const { return expr.val2; } \
2985 unsigned long int get_prec() const { return mpf_get_default_prec(); } \
2988 template <class T, class U> \
2989 class __gmp_expr<mpz_t, __gmp_binary_expr<mpz_class, __gmp_expr \
2990 <mpz_t, __gmp_binary_expr<__gmp_expr<mpz_t, T>, U, eval_fun1> >, \
2994 typedef mpz_class val1_type; \
2995 typedef __gmp_expr<mpz_t, __gmp_binary_expr \
2996 <__gmp_expr<mpz_t, T>, U, eval_fun1> > val2_type; \
2998 __gmp_binary_expr<val1_type, val2_type, eval_fun2> expr; \
3000 __gmp_expr(const val1_type &val1, const val2_type &val2) \
3001 : expr(val1, val2) { } \
3002 void eval(mpz_ptr z) const \
3004 mpz_class temp(expr.val2.get_val1()); \
3006 (z, expr.val1.get_mpz_t(), temp.get_mpz_t(), expr.val2.get_val2()); \
3008 const val1_type & get_val1() const { return expr.val1; } \
3009 const val2_type & get_val2() const { return expr.val2; } \
3010 unsigned long int get_prec() const { return mpf_get_default_prec(); } \
3013 template <class T, class U> \
3014 class __gmp_expr<mpz_t, __gmp_binary_expr<mpz_class, __gmp_expr \
3015 <mpz_t, __gmp_binary_expr<T, __gmp_expr<mpz_t, U>, eval_fun1> >, \
3019 typedef mpz_class val1_type; \
3020 typedef __gmp_expr<mpz_t, __gmp_binary_expr \
3021 <T, __gmp_expr<mpz_t, U>, eval_fun1> > val2_type; \
3023 __gmp_binary_expr<val1_type, val2_type, eval_fun2> expr; \
3025 __gmp_expr(const val1_type &val1, const val2_type &val2) \
3026 : expr(val1, val2) { } \
3027 void eval(mpz_ptr z) const \
3029 mpz_class temp(expr.val2.get_val2()); \
3031 (z, expr.val1.get_mpz_t(), expr.val2.get_val1(), temp.get_mpz_t()); \
3033 const val1_type & get_val1() const { return expr.val1; } \
3034 const val2_type & get_val2() const { return expr.val2; } \
3035 unsigned long int get_prec() const { return mpf_get_default_prec(); } \
3038 template <class T, class U> \
3039 class __gmp_expr<mpz_t, __gmp_binary_expr<mpz_class, __gmp_expr \
3040 <mpz_t, __gmp_binary_expr<__gmp_expr<mpz_t, T>, __gmp_expr<mpz_t, U>, \
3041 eval_fun1> >, eval_fun2> > \
3044 typedef mpz_class val1_type; \
3045 typedef __gmp_expr<mpz_t, __gmp_binary_expr \
3046 <__gmp_expr<mpz_t, T>, __gmp_expr<mpz_t, U>, eval_fun1> > val2_type; \
3048 __gmp_binary_expr<val1_type, val2_type, eval_fun2> expr; \
3050 __gmp_expr(const val1_type &val1, const val2_type &val2) \
3051 : expr(val1, val2) { } \
3052 void eval(mpz_ptr z) const \
3054 mpz_class temp1(expr.val2.get_val1()); \
3055 mpz_class temp2(expr.val2.get_val2()); \
3057 (z, expr.val1.get_mpz_t(), temp1.get_mpz_t(), temp2.get_mpz_t()); \
3059 const val1_type & get_val1() const { return expr.val1; } \
3060 const val2_type & get_val2() const { return expr.val2; } \
3061 unsigned long int get_prec() const { return mpf_get_default_prec(); } \
3064 template <class T> \
3065 class __gmp_expr<mpz_t, __gmp_binary_expr<__gmp_expr<mpz_t, T>, \
3066 __gmp_expr<mpz_t, __gmp_binary_expr<mpz_class, mpz_class, eval_fun1> >, \
3070 typedef __gmp_expr<mpz_t, T> val1_type; \
3071 typedef __gmp_expr \
3072 <mpz_t, __gmp_binary_expr<mpz_class, mpz_class, eval_fun1> > val2_type; \
3074 __gmp_binary_expr<val1_type, val2_type, eval_fun2> expr; \
3076 __gmp_expr(const val1_type &val1, const val2_type &val2) \
3077 : expr(val1, val2) { } \
3078 void eval(mpz_ptr z) const \
3080 mpz_class temp(expr.val1); \
3081 eval_both::eval(z, temp.get_mpz_t(), expr.val2.get_val1().get_mpz_t(), \
3082 expr.val2.get_val2().get_mpz_t()); \
3084 const val1_type & get_val1() const { return expr.val1; } \
3085 const val2_type & get_val2() const { return expr.val2; } \
3086 unsigned long int get_prec() const { return mpf_get_default_prec(); } \
3089 template <class T, class U> \
3090 class __gmp_expr<mpz_t, __gmp_binary_expr<__gmp_expr<mpz_t, T>, \
3091 __gmp_expr<mpz_t, __gmp_binary_expr<mpz_class, U, eval_fun1> >, \
3095 typedef __gmp_expr<mpz_t, T> val1_type; \
3096 typedef __gmp_expr \
3097 <mpz_t, __gmp_binary_expr<mpz_class, U, eval_fun1> > val2_type; \
3099 __gmp_binary_expr<val1_type, val2_type, eval_fun2> expr; \
3101 __gmp_expr(const val1_type &val1, const val2_type &val2) \
3102 : expr(val1, val2) { } \
3103 void eval(mpz_ptr z) const \
3105 mpz_class temp(expr.val1); \
3106 eval_both::eval(z, temp.get_mpz_t(), expr.val2.get_val1().get_mpz_t(), \
3107 expr.val2.get_val2()); \
3109 const val1_type & get_val1() const { return expr.val1; } \
3110 const val2_type & get_val2() const { return expr.val2; } \
3111 unsigned long int get_prec() const { return mpf_get_default_prec(); } \
3114 template <class T, class U> \
3115 class __gmp_expr<mpz_t, __gmp_binary_expr<__gmp_expr<mpz_t, T>, \
3116 __gmp_expr<mpz_t, __gmp_binary_expr<U, mpz_class, eval_fun1> >, \
3120 typedef __gmp_expr<mpz_t, T> val1_type; \
3121 typedef __gmp_expr \
3122 <mpz_t, __gmp_binary_expr<U, mpz_class, eval_fun1> > val2_type; \
3124 __gmp_binary_expr<val1_type, val2_type, eval_fun2> expr; \
3126 __gmp_expr(const val1_type &val1, const val2_type &val2) \
3127 : expr(val1, val2) { } \
3128 void eval(mpz_ptr z) const \
3130 mpz_class temp(expr.val1); \
3131 eval_both::eval(z, temp.get_mpz_t(), expr.val2.get_val1(), \
3132 expr.val2.get_val2().get_mpz_t()); \
3134 const val1_type & get_val1() const { return expr.val1; } \
3135 const val2_type & get_val2() const { return expr.val2; } \
3136 unsigned long int get_prec() const { return mpf_get_default_prec(); } \
3139 template <class T, class U> \
3140 class __gmp_expr<mpz_t, __gmp_binary_expr<__gmp_expr<mpz_t, T>, \
3141 __gmp_expr<mpz_t, __gmp_binary_expr<mpz_class, __gmp_expr<mpz_t, U>, \
3142 eval_fun1> >, eval_fun2> > \
3145 typedef __gmp_expr<mpz_t, T> val1_type; \
3146 typedef __gmp_expr<mpz_t, __gmp_binary_expr \
3147 <mpz_class, __gmp_expr<mpz_t, U>, eval_fun1> > val2_type; \
3149 __gmp_binary_expr<val1_type, val2_type, eval_fun2> expr; \
3151 __gmp_expr(const val1_type &val1, const val2_type &val2) \
3152 : expr(val1, val2) { } \
3153 void eval(mpz_ptr z) const \
3155 mpz_class temp1(expr.val1); \
3156 mpz_class temp2(expr.val2.get_val2()); \
3158 (z, temp1.get_mpz_t(), expr.val2.get_val1().get_mpz_t(), \
3159 temp2.get_mpz_t()); \
3161 const val1_type & get_val1() const { return expr.val1; } \
3162 const val2_type & get_val2() const { return expr.val2; } \
3163 unsigned long int get_prec() const { return mpf_get_default_prec(); } \
3166 template <class T, class U> \
3167 class __gmp_expr<mpz_t, __gmp_binary_expr<__gmp_expr<mpz_t, T>, \
3168 __gmp_expr<mpz_t, __gmp_binary_expr<__gmp_expr<mpz_t, U>, mpz_class, \
3169 eval_fun1> >, eval_fun2> > \
3172 typedef __gmp_expr<mpz_t, T> val1_type; \
3173 typedef __gmp_expr<mpz_t, __gmp_binary_expr \
3174 <__gmp_expr<mpz_t, U>, mpz_class, eval_fun1> > val2_type; \
3176 __gmp_binary_expr<val1_type, val2_type, eval_fun2> expr; \
3178 __gmp_expr(const val1_type &val1, const val2_type &val2) \
3179 : expr(val1, val2) { } \
3180 void eval(mpz_ptr z) const \
3182 mpz_class temp1(expr.val1); \
3183 mpz_class temp2(expr.val2.get_val1()); \
3184 eval_both::eval(z, temp1.get_mpz_t(), temp2.get_mpz_t(), \
3185 expr.val2.get_val2().get_mpz_t()); \
3187 const val1_type & get_val1() const { return expr.val1; } \
3188 const val2_type & get_val2() const { return expr.val2; } \
3189 unsigned long int get_prec() const { return mpf_get_default_prec(); } \
3192 template <class T, class U, class V> \
3193 class __gmp_expr<mpz_t, __gmp_binary_expr<__gmp_expr<mpz_t, T>, \
3194 __gmp_expr<mpz_t, __gmp_binary_expr<__gmp_expr<mpz_t, U>, V, \
3195 eval_fun1> >, eval_fun2> > \
3198 typedef __gmp_expr<mpz_t, T> val1_type; \
3199 typedef __gmp_expr<mpz_t, __gmp_binary_expr \
3200 <__gmp_expr<mpz_t, U>, V, eval_fun1> > val2_type; \
3202 __gmp_binary_expr<val1_type, val2_type, eval_fun2> expr; \
3204 __gmp_expr(const val1_type &val1, const val2_type &val2) \
3205 : expr(val1, val2) { } \
3206 void eval(mpz_ptr z) const \
3208 mpz_class temp1(expr.val1); \
3209 mpz_class temp2(expr.val2.get_val1()); \
3211 (z, temp1.get_mpz_t(), temp2.get_mpz_t(), expr.val2.get_val2()); \
3213 const val1_type & get_val1() const { return expr.val1; } \
3214 const val2_type & get_val2() const { return expr.val2; } \
3215 unsigned long int get_prec() const { return mpf_get_default_prec(); } \
3218 template <class T, class U, class V> \
3219 class __gmp_expr<mpz_t, __gmp_binary_expr<__gmp_expr<mpz_t, T>, \
3220 __gmp_expr<mpz_t, __gmp_binary_expr<U, __gmp_expr<mpz_t, V>, \
3221 eval_fun1> >, eval_fun2> > \
3224 typedef __gmp_expr<mpz_t, T> val1_type; \
3225 typedef __gmp_expr<mpz_t, __gmp_binary_expr \
3226 <U, __gmp_expr<mpz_t, V>, eval_fun1> > val2_type; \
3228 __gmp_binary_expr<val1_type, val2_type, eval_fun2> expr; \
3230 __gmp_expr(const val1_type &val1, const val2_type &val2) \
3231 : expr(val1, val2) { } \
3232 void eval(mpz_ptr z) const \
3234 mpz_class temp1(expr.val1); \
3235 mpz_class temp2(expr.val2.get_val2()); \
3237 (z, temp1.get_mpz_t(), expr.val2.get_val1(), temp2.get_mpz_t()); \
3239 const val1_type & get_val1() const { return expr.val1; } \
3240 const val2_type & get_val2() const { return expr.val2; } \
3241 unsigned long int get_prec() const { return mpf_get_default_prec(); } \
3244 template <class T, class U, class V> \
3245 class __gmp_expr<mpz_t, __gmp_binary_expr<__gmp_expr<mpz_t, T>, \
3246 __gmp_expr<mpz_t, __gmp_binary_expr<__gmp_expr<mpz_t, U>, \
3247 __gmp_expr<mpz_t, V>, eval_fun1> >, eval_fun2> > \
3250 typedef __gmp_expr<mpz_t, T> val1_type; \
3251 typedef __gmp_expr<mpz_t, __gmp_binary_expr \
3252 <__gmp_expr<mpz_t, U>, __gmp_expr<mpz_t, V>, eval_fun1> > val2_type; \
3254 __gmp_binary_expr<val1_type, val2_type, eval_fun2> expr; \
3256 __gmp_expr(const val1_type &val1, const val2_type &val2) \
3257 : expr(val1, val2) { } \
3258 void eval(mpz_ptr z) const \
3260 mpz_class temp1(expr.val1); \
3261 mpz_class temp2(expr.val2.get_val1()); \
3262 mpz_class temp3(expr.val2.get_val2()); \
3264 (z, temp1.get_mpz_t(), temp2.get_mpz_t(), temp3.get_mpz_t()); \
3266 const val1_type & get_val1() const { return expr.val1; } \
3267 const val2_type & get_val2() const { return expr.val2; } \
3268 unsigned long int get_prec() const { return mpf_get_default_prec(); } \
3272 __GMP_DEFINE_TERNARY_EXPR(__gmp_binary_multiplies, __gmp_binary_plus,
3273 __gmp_ternary_addmul)
3274 __GMP_DEFINE_TERNARY_EXPR(__gmp_binary_multiplies, __gmp_binary_minus,
3275 __gmp_ternary_submul)
3277 /**************** Macros for defining functions ****************/
3278 /* Results of operators and functions are instances of __gmp_expr<T, U>.
3279 T determines the numerical type of the expression: it can be either
3280 mpz_t, mpq_t, or mpf_t. When the arguments of a binary
3281 expression have different numerical types, __gmp_resolve_expr is used
3282 to determine the "larger" type.
3283 U is either __gmp_unary_expr<V, Op> or __gmp_binary_expr<V, W, Op>,
3284 where V and W are the arguments' types -- they can in turn be
3285 expressions, thus allowing to build compound expressions to any
3286 degree of complexity.
3287 Op is a function object that must have an eval() method accepting
3288 appropriate arguments.
3289 Actual evaluation of a __gmp_expr<T, U> object is done when it gets
3290 assigned to an mp*_class ("lazy" evaluation): this is done by calling
3291 its eval() method. */
3294 // non-member unary operators and functions
3296 #define __GMP_DEFINE_UNARY_FUNCTION(fun, eval_fun) \
3298 template <class T, class U> \
3299 inline __gmp_expr<T, __gmp_unary_expr<__gmp_expr<T, U>, eval_fun> > \
3300 fun(const __gmp_expr<T, U> &expr) \
3302 return __gmp_expr<T, __gmp_unary_expr<__gmp_expr<T, U>, eval_fun> >(expr); \
3305 #define __GMP_DEFINE_UNARY_TYPE_FUNCTION(type, fun, eval_fun) \
3307 template <class T, class U> \
3308 inline type fun(const __gmp_expr<T, U> &expr) \
3310 typename __gmp_resolve_temp<T, T, U>::temp_type temp(expr); \
3311 return eval_fun::eval(temp.__get_mp()); \
3315 // non-member binary operators and functions
3317 #define __GMPP_DEFINE_BINARY_FUNCTION(fun, eval_fun) \
3319 template <class T, class U, class V, class W> \
3320 inline __gmp_expr<typename __gmp_resolve_expr<T, V>::value_type, \
3321 __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<V, W>, eval_fun> > \
3322 fun(const __gmp_expr<T, U> &expr1, const __gmp_expr<V, W> &expr2) \
3324 return __gmp_expr<typename __gmp_resolve_expr<T, V>::value_type, \
3325 __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<V, W>, eval_fun> > \
3329 #define __GMPNN_DEFINE_BINARY_FUNCTION(fun, eval_fun, type, bigtype) \
3331 template <class T, class U> \
3333 <T, __gmp_binary_expr<__gmp_expr<T, U>, bigtype, eval_fun> > \
3334 fun(const __gmp_expr<T, U> &expr, type t) \
3337 <T, __gmp_binary_expr<__gmp_expr<T, U>, bigtype, eval_fun> >(expr, t); \
3340 template <class T, class U> \
3342 <T, __gmp_binary_expr<bigtype, __gmp_expr<T, U>, eval_fun> > \
3343 fun(type t, const __gmp_expr<T, U> &expr) \
3346 <T, __gmp_binary_expr<bigtype, __gmp_expr<T, U>, eval_fun> >(t, expr); \
3349 #define __GMPNS_DEFINE_BINARY_FUNCTION(fun, eval_fun, type) \
3350 __GMPNN_DEFINE_BINARY_FUNCTION(fun, eval_fun, type, signed long int)
3352 #define __GMPNU_DEFINE_BINARY_FUNCTION(fun, eval_fun, type) \
3353 __GMPNN_DEFINE_BINARY_FUNCTION(fun, eval_fun, type, unsigned long int)
3355 #define __GMPND_DEFINE_BINARY_FUNCTION(fun, eval_fun, type) \
3356 __GMPNN_DEFINE_BINARY_FUNCTION(fun, eval_fun, type, double)
3358 #define __GMPNLD_DEFINE_BINARY_FUNCTION(fun, eval_fun, type) \
3359 __GMPNN_DEFINE_BINARY_FUNCTION(fun, eval_fun, type, long double)
3361 #define __GMPN_DEFINE_BINARY_FUNCTION(fun, eval_fun) \
3362 __GMPNS_DEFINE_BINARY_FUNCTION(fun, eval_fun, signed char) \
3363 __GMPNU_DEFINE_BINARY_FUNCTION(fun, eval_fun, unsigned char) \
3364 __GMPNS_DEFINE_BINARY_FUNCTION(fun, eval_fun, signed int) \
3365 __GMPNU_DEFINE_BINARY_FUNCTION(fun, eval_fun, unsigned int) \
3366 __GMPNS_DEFINE_BINARY_FUNCTION(fun, eval_fun, signed short int) \
3367 __GMPNU_DEFINE_BINARY_FUNCTION(fun, eval_fun, unsigned short int) \
3368 __GMPNS_DEFINE_BINARY_FUNCTION(fun, eval_fun, signed long int) \
3369 __GMPNU_DEFINE_BINARY_FUNCTION(fun, eval_fun, unsigned long int) \
3370 __GMPND_DEFINE_BINARY_FUNCTION(fun, eval_fun, float) \
3371 __GMPND_DEFINE_BINARY_FUNCTION(fun, eval_fun, double) \
3372 __GMPNLD_DEFINE_BINARY_FUNCTION(fun, eval_fun, long double)
3374 #define __GMP_DEFINE_BINARY_FUNCTION(fun, eval_fun) \
3375 __GMPP_DEFINE_BINARY_FUNCTION(fun, eval_fun) \
3376 __GMPN_DEFINE_BINARY_FUNCTION(fun, eval_fun)
3379 #define __GMP_DEFINE_BINARY_FUNCTION_UI(fun, eval_fun) \
3381 template <class T, class U> \
3383 <T, __gmp_binary_expr<__gmp_expr<T, U>, unsigned long int, eval_fun> > \
3384 fun(const __gmp_expr<T, U> &expr, unsigned long int l) \
3386 return __gmp_expr<T, __gmp_binary_expr \
3387 <__gmp_expr<T, U>, unsigned long int, eval_fun> >(expr, l); \
3391 #define __GMPP_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun) \
3393 template <class T, class U, class V, class W> \
3394 inline type fun(const __gmp_expr<T, U> &expr1, \
3395 const __gmp_expr<V, W> &expr2) \
3397 typedef typename __gmp_resolve_expr<T, V>::value_type eval_type; \
3398 typename __gmp_resolve_temp<eval_type, T, U>::temp_type temp1(expr1); \
3399 typename __gmp_resolve_temp<eval_type, V, W>::temp_type temp2(expr2); \
3400 return eval_fun::eval(temp1.__get_mp(), temp2.__get_mp()); \
3403 #define __GMPNN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, \
3406 template <class T, class U> \
3407 inline type fun(const __gmp_expr<T, U> &expr, type2 t) \
3409 typename __gmp_resolve_temp<T, T, U>::temp_type temp(expr); \
3410 return eval_fun::eval(temp.__get_mp(), static_cast<bigtype>(t)); \
3413 template <class T, class U> \
3414 inline type fun(type2 t, const __gmp_expr<T, U> &expr) \
3416 typename __gmp_resolve_temp<T, T, U>::temp_type temp(expr); \
3417 return eval_fun::eval(static_cast<bigtype>(t), temp.__get_mp()); \
3420 #define __GMPNS_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, type2) \
3421 __GMPNN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, \
3422 type2, signed long int)
3424 #define __GMPNU_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, type2) \
3425 __GMPNN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, \
3426 type2, unsigned long int)
3428 #define __GMPND_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, type2) \
3429 __GMPNN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, type2, double)
3431 #define __GMPNLD_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, type2) \
3432 __GMPNN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, type2, long double)
3434 #define __GMPN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun) \
3435 __GMPNS_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, signed char) \
3436 __GMPNU_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, unsigned char) \
3437 __GMPNS_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, signed int) \
3438 __GMPNU_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, unsigned int) \
3439 __GMPNS_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, signed short int) \
3440 __GMPNU_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, unsigned short int) \
3441 __GMPNS_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, signed long int) \
3442 __GMPNU_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, unsigned long int) \
3443 __GMPND_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, float) \
3444 __GMPND_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, double) \
3445 __GMPNLD_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, long double)
3447 #define __GMP_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun) \
3448 __GMPP_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun) \
3449 __GMPN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun)
3454 #define __GMPP_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun) \
3456 template <class T, class U> \
3457 inline type##_class & type##_class::fun(const __gmp_expr<T, U> &expr) \
3459 __gmp_set_expr(mp, __gmp_expr<type##_t, __gmp_binary_expr \
3460 <type##_class, __gmp_expr<T, U>, eval_fun> >(*this, expr)); \
3464 #define __GMPNN_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, \
3467 inline type##_class & type##_class::fun(type2 t) \
3469 __gmp_set_expr(mp, __gmp_expr<type##_t, __gmp_binary_expr \
3470 <type##_class, bigtype, eval_fun> >(*this, t)); \
3474 #define __GMPNS_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, type2) \
3475 __GMPNN_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, \
3476 type2, signed long int)
3478 #define __GMPNU_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, type2) \
3479 __GMPNN_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, \
3480 type2, unsigned long int)
3482 #define __GMPND_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, type2) \
3483 __GMPNN_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, type2, double)
3485 #define __GMPNLD_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, type2) \
3486 __GMPNN_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, type2, long double)
3488 #define __GMPN_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun) \
3489 __GMPNS_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, signed char) \
3490 __GMPNU_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, unsigned char) \
3491 __GMPNS_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, signed int) \
3492 __GMPNU_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, unsigned int) \
3493 __GMPNS_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, signed short int) \
3494 __GMPNU_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, unsigned short int) \
3495 __GMPNS_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, signed long int) \
3496 __GMPNU_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, unsigned long int) \
3497 __GMPND_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, float) \
3498 __GMPND_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, double) \
3499 /* __GMPNLD_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, long double) */
3501 #define __GMP_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun) \
3502 __GMPP_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun) \
3503 __GMPN_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun)
3505 #define __GMPZ_DEFINE_COMPOUND_OPERATOR(fun, eval_fun) \
3506 __GMP_DEFINE_COMPOUND_OPERATOR(mpz, fun, eval_fun)
3508 #define __GMPZZ_DEFINE_COMPOUND_OPERATOR(fun, eval_fun) \
3509 __GMPP_DEFINE_COMPOUND_OPERATOR(mpz, fun, eval_fun)
3511 #define __GMPQ_DEFINE_COMPOUND_OPERATOR(fun, eval_fun) \
3512 __GMP_DEFINE_COMPOUND_OPERATOR(mpq, fun, eval_fun)
3514 #define __GMPF_DEFINE_COMPOUND_OPERATOR(fun, eval_fun) \
3515 __GMP_DEFINE_COMPOUND_OPERATOR(mpf, fun, eval_fun)
3519 #define __GMP_DEFINE_COMPOUND_OPERATOR_UI(type, fun, eval_fun) \
3521 inline type##_class & type##_class::fun(unsigned long int l) \
3523 __gmp_set_expr(mp, __gmp_expr<type##_t, __gmp_binary_expr \
3524 <type##_class, unsigned long int, eval_fun> >(*this, l)); \
3528 #define __GMPZ_DEFINE_COMPOUND_OPERATOR_UI(fun, eval_fun) \
3529 __GMP_DEFINE_COMPOUND_OPERATOR_UI(mpz, fun, eval_fun)
3531 #define __GMPQ_DEFINE_COMPOUND_OPERATOR_UI(fun, eval_fun) \
3532 __GMP_DEFINE_COMPOUND_OPERATOR_UI(mpq, fun, eval_fun)
3534 #define __GMPF_DEFINE_COMPOUND_OPERATOR_UI(fun, eval_fun) \
3535 __GMP_DEFINE_COMPOUND_OPERATOR_UI(mpf, fun, eval_fun)
3539 #define __GMP_DEFINE_INCREMENT_OPERATOR(type, fun, eval_fun) \
3541 inline type##_class & type##_class::fun() \
3543 eval_fun::eval(mp); \
3547 inline type##_class type##_class::fun(int) \
3549 type##_class temp(*this); \
3550 eval_fun::eval(mp); \
3554 #define __GMPZ_DEFINE_INCREMENT_OPERATOR(fun, eval_fun) \
3555 __GMP_DEFINE_INCREMENT_OPERATOR(mpz, fun, eval_fun)
3557 #define __GMPQ_DEFINE_INCREMENT_OPERATOR(fun, eval_fun) \
3558 __GMP_DEFINE_INCREMENT_OPERATOR(mpq, fun, eval_fun)
3560 #define __GMPF_DEFINE_INCREMENT_OPERATOR(fun, eval_fun) \
3561 __GMP_DEFINE_INCREMENT_OPERATOR(mpf, fun, eval_fun)
3565 /**************** Arithmetic operators and functions ****************/
3567 // non-member operators and functions
3569 __GMP_DEFINE_UNARY_FUNCTION(operator+, __gmp_unary_plus)
3570 __GMP_DEFINE_UNARY_FUNCTION(operator-, __gmp_unary_minus)
3571 __GMP_DEFINE_UNARY_FUNCTION(operator~, __gmp_unary_com)
3573 __GMP_DEFINE_BINARY_FUNCTION(operator+, __gmp_binary_plus)
3574 __GMP_DEFINE_BINARY_FUNCTION(operator-, __gmp_binary_minus)
3575 __GMP_DEFINE_BINARY_FUNCTION(operator*, __gmp_binary_multiplies)
3576 __GMP_DEFINE_BINARY_FUNCTION(operator/, __gmp_binary_divides)
3577 __GMP_DEFINE_BINARY_FUNCTION(operator%, __gmp_binary_modulus)
3578 __GMP_DEFINE_BINARY_FUNCTION(operator&, __gmp_binary_and)
3579 __GMP_DEFINE_BINARY_FUNCTION(operator|, __gmp_binary_ior)
3580 __GMP_DEFINE_BINARY_FUNCTION(operator^, __gmp_binary_xor)
3582 __GMP_DEFINE_BINARY_FUNCTION_UI(operator<<, __gmp_binary_lshift)
3583 __GMP_DEFINE_BINARY_FUNCTION_UI(operator>>, __gmp_binary_rshift)
3585 __GMP_DEFINE_BINARY_TYPE_FUNCTION(bool, operator==, __gmp_binary_equal)
3586 __GMP_DEFINE_BINARY_TYPE_FUNCTION(bool, operator!=, __gmp_binary_not_equal)
3587 __GMP_DEFINE_BINARY_TYPE_FUNCTION(bool, operator<, __gmp_binary_less)
3588 __GMP_DEFINE_BINARY_TYPE_FUNCTION(bool, operator<=, __gmp_binary_less_equal)
3589 __GMP_DEFINE_BINARY_TYPE_FUNCTION(bool, operator>, __gmp_binary_greater)
3590 __GMP_DEFINE_BINARY_TYPE_FUNCTION(bool, operator>=, \
3591 __gmp_binary_greater_equal)
3593 __GMP_DEFINE_UNARY_FUNCTION(abs, __gmp_abs_function)
3594 __GMP_DEFINE_UNARY_FUNCTION(trunc, __gmp_trunc_function)
3595 __GMP_DEFINE_UNARY_FUNCTION(floor, __gmp_floor_function)
3596 __GMP_DEFINE_UNARY_FUNCTION(ceil, __gmp_ceil_function)
3597 __GMP_DEFINE_UNARY_FUNCTION(sqrt, __gmp_sqrt_function)
3598 __GMP_DEFINE_BINARY_FUNCTION(hypot, __gmp_hypot_function)
3600 __GMP_DEFINE_UNARY_TYPE_FUNCTION(int, sgn, __gmp_sgn_function)
3601 __GMP_DEFINE_BINARY_TYPE_FUNCTION(int, cmp, __gmp_cmp_function)
3603 // member operators for mpz_class
3605 __GMPZ_DEFINE_COMPOUND_OPERATOR(operator+=, __gmp_binary_plus)
3606 __GMPZ_DEFINE_COMPOUND_OPERATOR(operator-=, __gmp_binary_minus)
3607 __GMPZ_DEFINE_COMPOUND_OPERATOR(operator*=, __gmp_binary_multiplies)
3608 __GMPZ_DEFINE_COMPOUND_OPERATOR(operator/=, __gmp_binary_divides)
3609 __GMPZ_DEFINE_COMPOUND_OPERATOR(operator%=, __gmp_binary_modulus)
3611 __GMPZZ_DEFINE_COMPOUND_OPERATOR(operator&=, __gmp_binary_and)
3612 __GMPZZ_DEFINE_COMPOUND_OPERATOR(operator|=, __gmp_binary_ior)
3613 __GMPZZ_DEFINE_COMPOUND_OPERATOR(operator^=, __gmp_binary_xor)
3615 __GMPZ_DEFINE_COMPOUND_OPERATOR_UI(operator<<=, __gmp_binary_lshift)
3616 __GMPZ_DEFINE_COMPOUND_OPERATOR_UI(operator>>=, __gmp_binary_rshift)
3618 __GMPZ_DEFINE_INCREMENT_OPERATOR(operator++, __gmp_unary_increment)
3619 __GMPZ_DEFINE_INCREMENT_OPERATOR(operator--, __gmp_unary_decrement)
3621 // member operators for mpq_class
3623 __GMPQ_DEFINE_COMPOUND_OPERATOR(operator+=, __gmp_binary_plus)
3624 __GMPQ_DEFINE_COMPOUND_OPERATOR(operator-=, __gmp_binary_minus)
3625 __GMPQ_DEFINE_COMPOUND_OPERATOR(operator*=, __gmp_binary_multiplies)
3626 __GMPQ_DEFINE_COMPOUND_OPERATOR(operator/=, __gmp_binary_divides)
3628 __GMPQ_DEFINE_COMPOUND_OPERATOR_UI(operator<<=, __gmp_binary_lshift)
3629 __GMPQ_DEFINE_COMPOUND_OPERATOR_UI(operator>>=, __gmp_binary_rshift)
3631 __GMPQ_DEFINE_INCREMENT_OPERATOR(operator++, __gmp_unary_increment)
3632 __GMPQ_DEFINE_INCREMENT_OPERATOR(operator--, __gmp_unary_decrement)
3634 // member operators for mpf_class
3636 __GMPF_DEFINE_COMPOUND_OPERATOR(operator+=, __gmp_binary_plus)
3637 __GMPF_DEFINE_COMPOUND_OPERATOR(operator-=, __gmp_binary_minus)
3638 __GMPF_DEFINE_COMPOUND_OPERATOR(operator*=, __gmp_binary_multiplies)
3639 __GMPF_DEFINE_COMPOUND_OPERATOR(operator/=, __gmp_binary_divides)
3641 __GMPF_DEFINE_COMPOUND_OPERATOR_UI(operator<<=, __gmp_binary_lshift)
3642 __GMPF_DEFINE_COMPOUND_OPERATOR_UI(operator>>=, __gmp_binary_rshift)
3644 __GMPF_DEFINE_INCREMENT_OPERATOR(operator++, __gmp_unary_increment)
3645 __GMPF_DEFINE_INCREMENT_OPERATOR(operator--, __gmp_unary_decrement)
3649 /**************** Class wrapper for gmp_randstate_t ****************/
3651 class __gmp_urandomb_value { };
3652 class __gmp_urandomm_value { };
3655 class __gmp_expr<mpz_t, __gmp_urandomb_value>
3658 __gmp_randstate_struct *state;
3659 unsigned long int bits;
3661 __gmp_expr(gmp_randstate_t s, unsigned long int l) : state(s), bits(l) { }
3662 void eval(mpz_ptr z) const { __gmp_rand_function::eval(z, state, bits); }
3663 unsigned long int get_prec() const { return mpf_get_default_prec(); }
3667 class __gmp_expr<mpz_t, __gmp_urandomm_value>
3670 __gmp_randstate_struct *state;
3673 __gmp_expr(gmp_randstate_t s, const mpz_class &z) : state(s), range(z) { }
3674 void eval(mpz_ptr z) const
3675 { __gmp_rand_function::eval(z, state, range.get_mpz_t()); }
3676 unsigned long int get_prec() const { return mpf_get_default_prec(); }
3680 class __gmp_expr<mpf_t, __gmp_urandomb_value>
3683 __gmp_randstate_struct *state;
3684 unsigned long int bits;
3686 __gmp_expr(gmp_randstate_t s, unsigned long int l) : state(s), bits(l) { }
3687 void eval(mpf_ptr f, unsigned long int prec) const
3688 { __gmp_rand_function::eval(f, state, (bits>0) ? get_prec() : prec); }
3689 unsigned long int get_prec() const
3692 return mpf_get_default_prec();
3699 typedef void __gmp_randinit_default_t (gmp_randstate_t);
3700 typedef void __gmp_randinit_lc_2exp_t (gmp_randstate_t, mpz_srcptr, unsigned long int, unsigned long int);
3701 typedef int __gmp_randinit_lc_2exp_size_t (gmp_randstate_t, unsigned long int);
3707 gmp_randstate_t state;
3709 // copy construction and assignment not allowed
3710 gmp_randclass(const gmp_randclass &);
3711 void operator=(const gmp_randclass &);
3713 // constructors and destructor
3714 gmp_randclass(gmp_randalg_t alg, unsigned long int size)
3718 case GMP_RAND_ALG_LC: // no other cases for now
3720 gmp_randinit(state, alg, size);
3725 // gmp_randinit_default
3726 gmp_randclass(__gmp_randinit_default_t* f) { f(state); }
3728 // gmp_randinit_lc_2exp
3729 gmp_randclass(__gmp_randinit_lc_2exp_t* f,
3730 mpz_class z, unsigned long int l1, unsigned long int l2)
3731 { f(state, z.get_mpz_t(), l1, l2); }
3733 // gmp_randinit_lc_2exp_size
3734 gmp_randclass(__gmp_randinit_lc_2exp_size_t* f,
3735 unsigned long int size)
3737 if (f (state, size) == 0)
3738 throw std::length_error ("gmp_randinit_lc_2exp_size");
3741 ~gmp_randclass() { gmp_randclear(state); }
3744 void seed(); // choose a random seed some way (?)
3745 void seed(unsigned long int s) { gmp_randseed_ui(state, s); }
3746 void seed(const mpz_class &z) { gmp_randseed(state, z.get_mpz_t()); }
3748 // get random number
3749 __gmp_expr<mpz_t, __gmp_urandomb_value> get_z_bits(unsigned long int l)
3750 { return __gmp_expr<mpz_t, __gmp_urandomb_value>(state, l); }
3751 __gmp_expr<mpz_t, __gmp_urandomb_value> get_z_bits(const mpz_class &z)
3752 { return get_z_bits(z.get_ui()); }
3754 __gmp_expr<mpz_t, __gmp_urandomm_value> get_z_range(const mpz_class &z)
3755 { return __gmp_expr<mpz_t, __gmp_urandomm_value>(state, z); }
3757 __gmp_expr<mpf_t, __gmp_urandomb_value> get_f(unsigned long int prec = 0)
3758 { return __gmp_expr<mpf_t, __gmp_urandomb_value>(state, prec); }
3762 /**************** #undef all private macros ****************/
3764 #undef __GMPP_DECLARE_COMPOUND_OPERATOR
3765 #undef __GMPN_DECLARE_COMPOUND_OPERATOR
3766 #undef __GMP_DECLARE_COMPOUND_OPERATOR
3767 #undef __GMP_DECLARE_COMPOUND_OPERATOR_UI
3768 #undef __GMP_DECLARE_INCREMENT_OPERATOR
3770 #undef __GMPZQ_DEFINE_EXPR
3771 #undef __GMP_DEFINE_TERNARY_EXPR
3773 #undef __GMP_DEFINE_UNARY_FUNCTION
3774 #undef __GMP_DEFINE_UNARY_TYPE_FUNCTION
3776 #undef __GMPP_DEFINE_BINARY_FUNCTION
3777 #undef __GMPNN_DEFINE_BINARY_FUNCTION
3778 #undef __GMPNS_DEFINE_BINARY_FUNCTION
3779 #undef __GMPNU_DEFINE_BINARY_FUNCTION
3780 #undef __GMPND_DEFINE_BINARY_FUNCTION
3781 #undef __GMPNLD_DEFINE_BINARY_FUNCTION
3782 #undef __GMPN_DEFINE_BINARY_FUNCTION
3783 #undef __GMP_DEFINE_BINARY_FUNCTION
3785 #undef __GMP_DEFINE_BINARY_FUNCTION_UI
3787 #undef __GMPP_DEFINE_BINARY_TYPE_FUNCTION
3788 #undef __GMPNN_DEFINE_BINARY_TYPE_FUNCTION
3789 #undef __GMPNS_DEFINE_BINARY_TYPE_FUNCTION
3790 #undef __GMPNU_DEFINE_BINARY_TYPE_FUNCTION
3791 #undef __GMPND_DEFINE_BINARY_TYPE_FUNCTION
3792 #undef __GMPNLD_DEFINE_BINARY_TYPE_FUNCTION
3793 #undef __GMPN_DEFINE_BINARY_TYPE_FUNCTION
3794 #undef __GMP_DEFINE_BINARY_TYPE_FUNCTION
3796 #undef __GMPP_DECLARE_COMPOUND_OPERATOR
3797 #undef __GMPN_DECLARE_COMPOUND_OPERATOR
3798 #undef __GMP_DECLARE_COMPOUND_OPERATOR
3800 #undef __GMP_DECLARE_COMPOUND_OPERATOR_UI
3801 #undef __GMP_DECLARE_INCREMENT_OPERATOR
3803 #undef __GMPZ_DEFINE_COMPOUND_OPERATOR
3804 #undef __GMPZZ_DEFINE_COMPOUND_OPERATOR
3805 #undef __GMPZN_DEFINE_COMPOUND_OPERATOR
3806 #undef __GMPZNN_DEFINE_COMPOUND_OPERATOR
3807 #undef __GMPZNS_DEFINE_COMPOUND_OPERATOR
3808 #undef __GMPZNU_DEFINE_COMPOUND_OPERATOR
3809 #undef __GMPZND_DEFINE_COMPOUND_OPERATOR
3810 #undef __GMPZNLD_DEFINE_COMPOUND_OPERATOR
3812 #undef __GMPP_DEFINE_COMPOUND_OPERATOR
3813 #undef __GMPNN_DEFINE_COMPOUND_OPERATOR
3814 #undef __GMPNS_DEFINE_COMPOUND_OPERATOR
3815 #undef __GMPNU_DEFINE_COMPOUND_OPERATOR
3816 #undef __GMPND_DEFINE_COMPOUND_OPERATOR
3817 #undef __GMPNLD_DEFINE_COMPOUND_OPERATOR
3818 #undef __GMPN_DEFINE_COMPOUND_OPERATOR
3819 #undef __GMP_DEFINE_COMPOUND_OPERATOR
3821 #undef __GMPZ_DEFINE_COMPOUND_OPERATOR
3822 #undef __GMPZZ_DEFINE_COMPOUND_OPERATOR
3823 #undef __GMPQ_DEFINE_COMPOUND_OPERATOR
3824 #undef __GMPF_DEFINE_COMPOUND_OPERATOR
3826 #undef __GMP_DEFINE_COMPOUND_OPERATOR_UI
3827 #undef __GMPZ_DEFINE_COMPOUND_OPERATOR_UI
3828 #undef __GMPQ_DEFINE_COMPOUND_OPERATOR_UI
3829 #undef __GMPF_DEFINE_COMPOUND_OPERATOR_UI
3831 #undef __GMP_DEFINE_INCREMENT_OPERATOR
3832 #undef __GMPZ_DEFINE_INCREMENT_OPERATOR
3833 #undef __GMPQ_DEFINE_INCREMENT_OPERATOR
3834 #undef __GMPF_DEFINE_INCREMENT_OPERATOR
3836 #endif /* __GMP_PLUSPLUS__ */