Annotation of OpenXM_contrib/gmp/gmpxx.h, Revision 1.1.1.1
1.1 ohara 1: /* gmpxx.h -- C++ class wrapper for GMP types. -*- C++ -*-
2:
3: Copyright 2001, 2002 Free Software Foundation, Inc.
4:
5: This file is part of the GNU MP Library.
6:
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.
11:
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.
16:
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., 59 Temple Place - Suite 330, Boston,
20: MA 02111-1307, USA. */
21:
22: /* the C++ compiler must implement the following features:
23: - member templates
24: - partial specialization of templates
25: - namespace support
26: for g++, this means version 2.91 or higher
27: for other compilers, I don't know */
28: #ifdef __GNUC__
29: #if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 91)
30: #error gmpxx.h requires g++ version 2.91 (egcs 1.1.2) or higher
31: #endif
32: #endif
33:
34: #ifndef __GMP_PLUSPLUS__
35: #define __GMP_PLUSPLUS__
36:
37: #include <iosfwd>
38: #include <string>
39: #include <gmp.h>
40:
41:
42: /**************** Function objects ****************/
43: /* Any evaluation of a __gmp_expr ends up calling one of these functions
44: all intermediate functions being inline, the evaluation should optimize
45: to a direct call to the relevant function, thus yielding no overhead
46: over the C interface.
47: Functions with mpfr_t arguments are wrapped by an #ifdef test because
48: mpfr isn't installed by default */
49:
50: struct __gmp_unary_plus
51: {
52: static void eval(mpz_ptr z, mpz_srcptr w) { mpz_set(z, w); }
53: static void eval(mpq_ptr q, mpq_srcptr r) { mpq_set(q, r); }
54: static void eval(mpf_ptr f, mpf_srcptr g) { mpf_set(f, g); }
55: #ifdef __MPFR_H
56: static void eval(mpfr_ptr f, mpfr_srcptr g, mp_rnd_t mode)
57: { mpfr_set(f, g, mode); }
58: #endif
59: };
60:
61: struct __gmp_unary_minus
62: {
63: static void eval(mpz_ptr z, mpz_srcptr w) { mpz_neg(z, w); }
64: static void eval(mpq_ptr q, mpq_srcptr r) { mpq_neg(q, r); }
65: static void eval(mpf_ptr f, mpf_srcptr g) { mpf_neg(f, g); }
66: #ifdef __MPFR_H
67: static void eval(mpfr_ptr f, mpfr_srcptr g, mp_rnd_t mode)
68: { mpfr_neg(f, g, mode); }
69: #endif
70: };
71:
72: struct __gmp_unary_com
73: {
74: static void eval(mpz_ptr z, mpz_srcptr w) { mpz_com(z, w); }
75: };
76:
77: struct __gmp_binary_plus
78: {
79: static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v)
80: { mpz_add(z, w, v); }
81:
82: static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l)
83: { mpz_add_ui(z, w, l); }
84: static void eval(mpz_ptr z, unsigned long int l, mpz_srcptr w)
85: { mpz_add_ui(z, w, l); }
86: static void eval(mpz_ptr z, mpz_srcptr w, signed long int l)
87: {
88: if (l >= 0)
89: mpz_add_ui(z, w, l);
90: else
91: mpz_sub_ui(z, w, -l);
92: }
93: static void eval(mpz_ptr z, signed long int l, mpz_srcptr w)
94: {
95: if (l >= 0)
96: mpz_add_ui(z, w, l);
97: else
98: mpz_sub_ui(z, w, -l);
99: }
100: static void eval(mpz_ptr z, mpz_srcptr w, double d)
101: {
102: mpz_t temp;
103: mpz_init_set_d(temp, d);
104: mpz_add(z, w, temp);
105: mpz_clear(temp);
106: }
107: static void eval(mpz_ptr z, double d, mpz_srcptr w)
108: {
109: mpz_t temp;
110: mpz_init_set_d(temp, d);
111: mpz_add(z, temp, w);
112: mpz_clear(temp);
113: }
114:
115: static void eval(mpq_ptr q, mpq_srcptr r, mpq_srcptr s)
116: { mpq_add(q, r, s); }
117:
118: static void eval(mpq_ptr q, mpq_srcptr r, unsigned long int l)
119: {
120: mpq_t temp;
121: mpq_init(temp);
122: mpq_set_ui(temp, l, 1);
123: mpq_add(q, r, temp);
124: mpq_clear(temp);
125: }
126: static void eval(mpq_ptr q, unsigned long int l, mpq_srcptr r)
127: {
128: mpq_t temp;
129: mpq_init(temp);
130: mpq_set_ui(temp, l, 1);
131: mpq_add(q, temp, r);
132: mpq_clear(temp);
133: }
134: static void eval(mpq_ptr q, mpq_srcptr r, signed long int l)
135: {
136: mpq_t temp;
137: mpq_init(temp);
138: mpq_set_si(temp, l, 1);
139: mpq_add(q, r, temp);
140: mpq_clear(temp);
141: }
142: static void eval(mpq_ptr q, signed long int l, mpq_srcptr r)
143: {
144: mpq_t temp;
145: mpq_init(temp);
146: mpq_set_si(temp, l, 1);
147: mpq_add(q, temp, r);
148: mpq_clear(temp);
149: }
150: static void eval(mpq_ptr q, mpq_srcptr r, double d)
151: {
152: mpq_t temp;
153: mpq_init(temp);
154: mpq_set_d(temp, d);
155: mpq_add(q, r, temp);
156: mpq_clear(temp);
157: }
158: static void eval(mpq_ptr q, double d, mpq_srcptr r)
159: {
160: mpq_t temp;
161: mpq_init(temp);
162: mpq_set_d(temp, d);
163: mpq_add(q, temp, r);
164: mpq_clear(temp);
165: }
166:
167: static void eval(mpq_ptr q, mpq_srcptr r, mpz_srcptr z)
168: {
169: mpq_set(q, r);
170: mpz_addmul(mpq_numref(q), mpq_denref(q), z);
171: }
172: static void eval(mpq_ptr q, mpz_srcptr z, mpq_srcptr r)
173: {
174: mpq_set(q, r);
175: mpz_addmul(mpq_numref(q), mpq_denref(q), z);
176: }
177:
178: static void eval(mpf_ptr f, mpf_srcptr g, mpf_srcptr h)
179: { mpf_add(f, g, h); }
180:
181: static void eval(mpf_ptr f, mpf_srcptr g, unsigned long int l)
182: { mpf_add_ui(f, g, l); }
183: static void eval(mpf_ptr f, unsigned long int l, mpf_srcptr g)
184: { mpf_add_ui(f, g, l); }
185: static void eval(mpf_ptr f, mpf_srcptr g, signed long int l)
186: {
187: if (l >= 0)
188: mpf_add_ui(f, g, l);
189: else
190: mpf_sub_ui(f, g, -l);
191: }
192: static void eval(mpf_ptr f, signed long int l, mpf_srcptr g)
193: {
194: if (l >= 0)
195: mpf_add_ui(f, g, l);
196: else
197: mpf_sub_ui(f, g, -l);
198: }
199: static void eval(mpf_ptr f, mpf_srcptr g, double d)
200: {
201: mpf_t temp;
202: mpf_init2(temp, 8*sizeof(double));
203: mpf_set_d(temp, d);
204: mpf_add(f, g, temp);
205: mpf_clear(temp);
206: }
207: static void eval(mpf_ptr f, double d, mpf_srcptr g)
208: {
209: mpf_t temp;
210: mpf_init2(temp, 8*sizeof(double));
211: mpf_set_d(temp, d);
212: mpf_add(f, temp, g);
213: mpf_clear(temp);
214: }
215:
216: #ifdef __MPFR_H
217: static void eval(mpfr_ptr f, mpfr_srcptr g, mpfr_srcptr h, mp_rnd_t mode)
218: { mpfr_add(f, g, h, mode); }
219:
220: static void eval(mpfr_ptr f, mpfr_srcptr g, unsigned long int l,
221: mp_rnd_t mode)
222: { mpfr_add_ui(f, g, l, mode); }
223: static void eval(mpfr_ptr f, unsigned long int l, mpfr_srcptr g,
224: mp_rnd_t mode)
225: { mpfr_add_ui(f, g, l, mode); }
226: static void eval(mpfr_ptr f, mpfr_srcptr g, signed long int l,
227: mp_rnd_t mode)
228: {
229: if (l >= 0)
230: mpfr_add_ui(f, g, l, mode);
231: else
232: mpfr_sub_ui(f, g, -l, mode);
233: }
234: static void eval(mpfr_ptr f, signed long int l, mpfr_srcptr g,
235: mp_rnd_t mode)
236: {
237: if (l >= 0)
238: mpfr_add_ui(f, g, l, mode);
239: else
240: mpfr_sub_ui(f, g, -l, mode);
241: }
242: static void eval(mpfr_ptr f, mpfr_srcptr g, double d, mp_rnd_t mode)
243: {
244: mpfr_t temp;
245: mpfr_init2(temp, 8*sizeof(double));
246: mpfr_set_d(temp, d, mode);
247: mpfr_add(f, g, temp, mode);
248: mpfr_clear(temp);
249: }
250: static void eval(mpfr_ptr f, double d, mpfr_srcptr g, mp_rnd_t mode)
251: {
252: mpfr_t temp;
253: mpfr_init2(temp, 8*sizeof(double));
254: mpfr_set_d(temp, d, mode);
255: mpfr_add(f, temp, g, mode);
256: mpfr_clear(temp);
257: }
258: #endif
259: };
260:
261: struct __gmp_binary_minus
262: {
263: static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v)
264: { mpz_sub(z, w, v); }
265:
266: static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l)
267: { mpz_sub_ui(z, w, l); }
268: static void eval(mpz_ptr z, unsigned long int l, mpz_srcptr w)
269: { mpz_ui_sub(z, l, w); }
270: static void eval(mpz_ptr z, mpz_srcptr w, signed long int l)
271: {
272: if (l >= 0)
273: mpz_sub_ui(z, w, l);
274: else
275: mpz_add_ui(z, w, -l);
276: }
277: static void eval(mpz_ptr z, signed long int l, mpz_srcptr w)
278: {
279: if (l >= 0)
280: mpz_ui_sub(z, l, w);
281: else
282: {
283: mpz_add_ui(z, w, -l);
284: mpz_neg(z, z);
285: }
286: }
287: static void eval(mpz_ptr z, mpz_srcptr w, double d)
288: {
289: mpz_t temp;
290: mpz_init_set_d(temp, d);
291: mpz_sub(z, w, temp);
292: mpz_clear(temp);
293: }
294: static void eval(mpz_ptr z, double d, mpz_srcptr w)
295: {
296: mpz_t temp;
297: mpz_init_set_d(temp, d);
298: mpz_sub(z, temp, w);
299: mpz_clear(temp);
300: }
301:
302: static void eval(mpq_ptr q, mpq_srcptr r, mpq_srcptr s)
303: { mpq_sub(q, r, s); }
304:
305: static void eval(mpq_ptr q, mpq_srcptr r, unsigned long int l)
306: {
307: mpq_t temp;
308: mpq_init(temp);
309: mpq_set_ui(temp, l, 1);
310: mpq_sub(q, r, temp);
311: mpq_clear(temp);
312: }
313: static void eval(mpq_ptr q, unsigned long int l, mpq_srcptr r)
314: {
315: mpq_t temp;
316: mpq_init(temp);
317: mpq_set_ui(temp, l, 1);
318: mpq_sub(q, temp, r);
319: mpq_clear(temp);
320: }
321: static void eval(mpq_ptr q, mpq_srcptr r, signed long int l)
322: {
323: mpq_t temp;
324: mpq_init(temp);
325: mpq_set_si(temp, l, 1);
326: mpq_sub(q, r, temp);
327: mpq_clear(temp);
328: }
329: static void eval(mpq_ptr q, signed long int l, mpq_srcptr r)
330: {
331: mpq_t temp;
332: mpq_init(temp);
333: mpq_set_si(temp, l, 1);
334: mpq_sub(q, temp, r);
335: mpq_clear(temp);
336: }
337: static void eval(mpq_ptr q, mpq_srcptr r, double d)
338: {
339: mpq_t temp;
340: mpq_init(temp);
341: mpq_set_d(temp, d);
342: mpq_sub(q, r, temp);
343: mpq_clear(temp);
344: }
345: static void eval(mpq_ptr q, double d, mpq_srcptr r)
346: {
347: mpq_t temp;
348: mpq_init(temp);
349: mpq_set_d(temp, d);
350: mpq_sub(q, temp, r);
351: mpq_clear(temp);
352: }
353:
354: static void eval(mpq_ptr q, mpq_srcptr r, mpz_srcptr z)
355: {
356: mpq_set(q, r);
357: mpz_submul(mpq_numref(q), mpq_denref(q), z);
358: }
359: static void eval(mpq_ptr q, mpz_srcptr z, mpq_srcptr r)
360: {
361: mpq_neg(q, r);
362: mpz_addmul(mpq_numref(q), mpq_denref(q), z);
363: }
364:
365: static void eval(mpf_ptr f, mpf_srcptr g, mpf_srcptr h)
366: { mpf_sub(f, g, h); }
367:
368: static void eval(mpf_ptr f, mpf_srcptr g, unsigned long int l)
369: { mpf_sub_ui(f, g, l); }
370: static void eval(mpf_ptr f, unsigned long int l, mpf_srcptr g)
371: { mpf_ui_sub(f, l, g); }
372: static void eval(mpf_ptr f, mpf_srcptr g, signed long int l)
373: {
374: if (l >= 0)
375: mpf_sub_ui(f, g, l);
376: else
377: mpf_add_ui(f, g, -l);
378: }
379: static void eval(mpf_ptr f, signed long int l, mpf_srcptr g)
380: {
381: if (l >= 0)
382: mpf_sub_ui(f, g, l);
383: else
384: mpf_add_ui(f, g, -l);
385: mpf_neg(f, f);
386: }
387: static void eval(mpf_ptr f, mpf_srcptr g, double d)
388: {
389: mpf_t temp;
390: mpf_init2(temp, 8*sizeof(double));
391: mpf_set_d(temp, d);
392: mpf_sub(f, g, temp);
393: mpf_clear(temp);
394: }
395: static void eval(mpf_ptr f, double d, mpf_srcptr g)
396: {
397: mpf_t temp;
398: mpf_init2(temp, 8*sizeof(double));
399: mpf_set_d(temp, d);
400: mpf_sub(f, temp, g);
401: mpf_clear(temp);
402: }
403:
404: #ifdef __MPFR_H
405: static void eval(mpfr_ptr f, mpfr_srcptr g, mpfr_srcptr h, mp_rnd_t mode)
406: { mpfr_sub(f, g, h, mode); }
407:
408: static void eval(mpfr_ptr f, mpfr_srcptr g, unsigned long int l,
409: mp_rnd_t mode)
410: { mpfr_sub_ui(f, g, l, mode); }
411: static void eval(mpfr_ptr f, unsigned long int l, mpfr_srcptr g,
412: mp_rnd_t mode)
413: { mpfr_ui_sub(f, l, g, mode); }
414: static void eval(mpfr_ptr f, mpfr_srcptr g, signed long int l,
415: mp_rnd_t mode)
416: {
417: if (l >= 0)
418: mpfr_sub_ui(f, g, l, mode);
419: else
420: mpfr_add_ui(f, g, -l, mode);
421: }
422: static void eval(mpfr_ptr f, signed long int l, mpfr_srcptr g,
423: mp_rnd_t mode)
424: {
425: if (l >= 0)
426: mpfr_sub_ui(f, g, l, mode);
427: else
428: mpfr_add_ui(f, g, -l, mode);
429: mpfr_neg(f, f, mode);
430: }
431: static void eval(mpfr_ptr f, mpfr_srcptr g, double d, mp_rnd_t mode)
432: {
433: mpfr_t temp;
434: mpfr_init2(temp, 8*sizeof(double));
435: mpfr_set_d(temp, d, mode);
436: mpfr_sub(f, g, temp, mode);
437: mpfr_clear(temp);
438: }
439: static void eval(mpfr_ptr f, double d, mpfr_srcptr g, mp_rnd_t mode)
440: {
441: mpfr_t temp;
442: mpfr_init2(temp, 8*sizeof(double));
443: mpfr_set_d(temp, d, mode);
444: mpfr_sub(f, temp, g, mode);
445: mpfr_clear(temp);
446: }
447: #endif
448: };
449:
450: struct __gmp_binary_multiplies
451: {
452: static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v)
453: { mpz_mul(z, w, v); }
454:
455: static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l)
456: { mpz_mul_ui(z, w, l); }
457: static void eval(mpz_ptr z, unsigned long int l, mpz_srcptr w)
458: { mpz_mul_ui(z, w, l); }
459: static void eval(mpz_ptr z, mpz_srcptr w, signed long int l)
460: {
461: if (l >= 0)
462: mpz_mul_ui(z, w, l);
463: else
464: {
465: mpz_mul_ui(z, w, -l);
466: mpz_neg(z, z);
467: }
468: }
469: static void eval(mpz_ptr z, signed long int l, mpz_srcptr w)
470: {
471: if (l >= 0)
472: mpz_mul_ui(z, w, l);
473: else
474: {
475: mpz_mul_ui(z, w, -l);
476: mpz_neg(z, z);
477: }
478: }
479: static void eval(mpz_ptr z, mpz_srcptr w, double d)
480: {
481: mpz_t temp;
482: mpz_init_set_d(temp, d);
483: mpz_mul(z, w, temp);
484: mpz_clear(temp);
485: }
486: static void eval(mpz_ptr z, double d, mpz_srcptr w)
487: {
488: mpz_t temp;
489: mpz_init_set_d(temp, d);
490: mpz_mul(z, temp, w);
491: mpz_clear(temp);
492: }
493:
494: static void eval(mpq_ptr q, mpq_srcptr r, mpq_srcptr s)
495: { mpq_mul(q, r, s); }
496:
497: static void eval(mpq_ptr q, mpq_srcptr r, unsigned long int l)
498: {
499: mpq_t temp;
500: mpq_init(temp);
501: mpq_set_ui(temp, l, 1);
502: mpq_mul(q, r, temp);
503: mpq_clear(temp);
504: }
505: static void eval(mpq_ptr q, unsigned long int l, mpq_srcptr r)
506: {
507: mpq_t temp;
508: mpq_init(temp);
509: mpq_set_ui(temp, l, 1);
510: mpq_mul(q, temp, r);
511: mpq_clear(temp);
512: }
513: static void eval(mpq_ptr q, mpq_srcptr r, signed long int l)
514: {
515: mpq_t temp;
516: mpq_init(temp);
517: mpq_set_si(temp, l, 1);
518: mpq_mul(q, r, temp);
519: mpq_clear(temp);
520: }
521: static void eval(mpq_ptr q, signed long int l, mpq_srcptr r)
522: {
523: mpq_t temp;
524: mpq_init(temp);
525: mpq_set_si(temp, l, 1);
526: mpq_mul(q, temp, r);
527: mpq_clear(temp);
528: }
529: static void eval(mpq_ptr q, mpq_srcptr r, double d)
530: {
531: mpq_t temp;
532: mpq_init(temp);
533: mpq_set_d(temp, d);
534: mpq_mul(q, r, temp);
535: mpq_clear(temp);
536: }
537: static void eval(mpq_ptr q, double d, mpq_srcptr r)
538: {
539: mpq_t temp;
540: mpq_init(temp);
541: mpq_set_d(temp, d);
542: mpq_mul(q, temp, r);
543: mpq_clear(temp);
544: }
545:
546: static void eval(mpf_ptr f, mpf_srcptr g, mpf_srcptr h)
547: { mpf_mul(f, g, h); }
548:
549: static void eval(mpf_ptr f, mpf_srcptr g, unsigned long int l)
550: { mpf_mul_ui(f, g, l); }
551: static void eval(mpf_ptr f, unsigned long int l, mpf_srcptr g)
552: { mpf_mul_ui(f, g, l); }
553: static void eval(mpf_ptr f, mpf_srcptr g, signed long int l)
554: {
555: if (l >= 0)
556: mpf_mul_ui(f, g, l);
557: else
558: {
559: mpf_mul_ui(f, g, -l);
560: mpf_neg(f, f);
561: }
562: }
563: static void eval(mpf_ptr f, signed long int l, mpf_srcptr g)
564: {
565: if (l >= 0)
566: mpf_mul_ui(f, g, l);
567: else
568: {
569: mpf_mul_ui(f, g, -l);
570: mpf_neg(f, f);
571: }
572: }
573: static void eval(mpf_ptr f, mpf_srcptr g, double d)
574: {
575: mpf_t temp;
576: mpf_init2(temp, 8*sizeof(double));
577: mpf_set_d(temp, d);
578: mpf_mul(f, g, temp);
579: mpf_clear(temp);
580: }
581: static void eval(mpf_ptr f, double d, mpf_srcptr g)
582: {
583: mpf_t temp;
584: mpf_init2(temp, 8*sizeof(double));
585: mpf_set_d(temp, d);
586: mpf_mul(f, temp, g);
587: mpf_clear(temp);
588: }
589:
590: #ifdef __MPFR_H
591: static void eval(mpfr_ptr f, mpfr_srcptr g, mpfr_srcptr h, mp_rnd_t mode)
592: { mpfr_mul(f, g, h, mode); }
593:
594: static void eval(mpfr_ptr f, mpfr_srcptr g, unsigned long int l,
595: mp_rnd_t mode)
596: { mpfr_mul_ui(f, g, l, mode); }
597: static void eval(mpfr_ptr f, unsigned long int l, mpfr_srcptr g,
598: mp_rnd_t mode)
599: { mpfr_mul_ui(f, g, l, mode); }
600: static void eval(mpfr_ptr f, mpfr_srcptr g, signed long int l,
601: mp_rnd_t mode)
602: {
603: if (l >= 0)
604: mpfr_mul_ui(f, g, l, mode);
605: else
606: {
607: mpfr_mul_ui(f, g, -l, mode);
608: mpfr_neg(f, f, mode);
609: }
610: }
611: static void eval(mpfr_ptr f, signed long int l, mpfr_srcptr g,
612: mp_rnd_t mode)
613: {
614: if (l >= 0)
615: mpfr_mul_ui(f, g, l, mode);
616: else
617: {
618: mpfr_mul_ui(f, g, -l, mode);
619: mpfr_neg(f, f, mode);
620: }
621: }
622: static void eval(mpfr_ptr f, mpfr_srcptr g, double d, mp_rnd_t mode)
623: {
624: mpfr_t temp;
625: mpfr_init2(temp, 8*sizeof(double));
626: mpfr_set_d(temp, d, mode);
627: mpfr_mul(f, g, temp, mode);
628: mpfr_clear(temp);
629: }
630: static void eval(mpfr_ptr f, double d, mpfr_srcptr g, mp_rnd_t mode)
631: {
632: mpfr_t temp;
633: mpfr_init2(temp, 8*sizeof(double));
634: mpfr_set_d(temp, d, mode);
635: mpfr_mul(f, temp, g, mode);
636: mpfr_clear(temp);
637: }
638: #endif
639: };
640:
641: struct __gmp_binary_divides
642: {
643: static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v)
644: { mpz_tdiv_q(z, w, v); }
645:
646: static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l)
647: { mpz_tdiv_q_ui(z, w, l); }
648: static void eval(mpz_ptr z, unsigned long int l, mpz_srcptr w)
649: {
650: if (mpz_sgn(w) >= 0)
651: {
652: if (mpz_fits_ulong_p(w))
653: mpz_set_ui(z, l / mpz_get_ui(w));
654: else
655: mpz_set_ui(z, 0);
656: }
657: else
658: {
659: mpz_neg(z, w);
660: if (mpz_fits_ulong_p(z))
661: {
662: mpz_set_ui(z, l / mpz_get_ui(z));
663: mpz_neg(z, z);
664: }
665: else
666: mpz_set_ui(z, 0);
667: }
668: }
669: static void eval(mpz_ptr z, mpz_srcptr w, signed long int l)
670: {
671: if (l >= 0)
672: mpz_tdiv_q_ui(z, w, l);
673: else
674: {
675: mpz_tdiv_q_ui(z, w, -l);
676: mpz_neg(z, z);
677: }
678: }
679: static void eval(mpz_ptr z, signed long int l, mpz_srcptr w)
680: {
681: if (mpz_fits_slong_p(w))
682: mpz_set_si(z, l / mpz_get_si(w));
683: else
684: mpz_set_si(z, 0);
685: }
686: static void eval(mpz_ptr z, mpz_srcptr w, double d)
687: {
688: mpz_t temp;
689: mpz_init_set_d(temp, d);
690: mpz_tdiv_q(z, w, temp);
691: mpz_clear(temp);
692: }
693: static void eval(mpz_ptr z, double d, mpz_srcptr w)
694: {
695: mpz_t temp;
696: mpz_init_set_d(temp, d);
697: mpz_tdiv_q(z, temp, w);
698: mpz_clear(temp);
699: }
700:
701: static void eval(mpq_ptr q, mpq_srcptr r, mpq_srcptr s)
702: { mpq_div(q, r, s); }
703:
704: static void eval(mpq_ptr q, mpq_srcptr r, unsigned long int l)
705: {
706: mpq_t temp;
707: mpq_init(temp);
708: mpq_set_ui(temp, l, 1);
709: mpq_div(q, r, temp);
710: mpq_clear(temp);
711: }
712: static void eval(mpq_ptr q, unsigned long int l, mpq_srcptr r)
713: {
714: mpq_t temp;
715: mpq_init(temp);
716: mpq_set_ui(temp, l, 1);
717: mpq_div(q, temp, r);
718: mpq_clear(temp);
719: }
720: static void eval(mpq_ptr q, mpq_srcptr r, signed long int l)
721: {
722: mpq_t temp;
723: mpq_init(temp);
724: mpq_set_si(temp, l, 1);
725: mpq_div(q, r, temp);
726: mpq_clear(temp);
727: }
728: static void eval(mpq_ptr q, signed long int l, mpq_srcptr r)
729: {
730: mpq_t temp;
731: mpq_init(temp);
732: mpq_set_si(temp, l, 1);
733: mpq_div(q, temp, r);
734: mpq_clear(temp);
735: }
736: static void eval(mpq_ptr q, mpq_srcptr r, double d)
737: {
738: mpq_t temp;
739: mpq_init(temp);
740: mpq_set_d(temp, d);
741: mpq_div(q, r, temp);
742: mpq_clear(temp);
743: }
744: static void eval(mpq_ptr q, double d, mpq_srcptr r)
745: {
746: mpq_t temp;
747: mpq_init(temp);
748: mpq_set_d(temp, d);
749: mpq_div(q, temp, r);
750: mpq_clear(temp);
751: }
752:
753: static void eval(mpf_ptr f, mpf_srcptr g, mpf_srcptr h)
754: { mpf_div(f, g, h); }
755:
756: static void eval(mpf_ptr f, mpf_srcptr g, unsigned long int l)
757: { mpf_div_ui(f, g, l); }
758: static void eval(mpf_ptr f, unsigned long int l, mpf_srcptr g)
759: { mpf_ui_div(f, l, g); }
760: static void eval(mpf_ptr f, mpf_srcptr g, signed long int l)
761: {
762: if (l >= 0)
763: mpf_div_ui(f, g, l);
764: else
765: {
766: mpf_div_ui(f, g, -l);
767: mpf_neg(f, f);
768: }
769: }
770: static void eval(mpf_ptr f, signed long int l, mpf_srcptr g)
771: {
772: if (l >= 0)
773: mpf_ui_div(f, l, g);
774: else
775: {
776: mpf_ui_div(f, -l, g);
777: mpf_neg(f, f);
778: }
779: }
780: static void eval(mpf_ptr f, mpf_srcptr g, double d)
781: {
782: mpf_t temp;
783: mpf_init2(temp, 8*sizeof(double));
784: mpf_set_d(temp, d);
785: mpf_div(f, g, temp);
786: mpf_clear(temp);
787: }
788: static void eval(mpf_ptr f, double d, mpf_srcptr g)
789: {
790: mpf_t temp;
791: mpf_init2(temp, 8*sizeof(double));
792: mpf_set_d(temp, d);
793: mpf_div(f, temp, g);
794: mpf_clear(temp);
795: }
796:
797: #ifdef __MPFR_H
798: static void eval(mpfr_ptr f, mpfr_srcptr g, mpfr_srcptr h, mp_rnd_t mode)
799: { mpfr_div(f, g, h, mode); }
800:
801: static void eval(mpfr_ptr f, mpfr_srcptr g, unsigned long int l,
802: mp_rnd_t mode)
803: { mpfr_div_ui(f, g, l, mode); }
804: static void eval(mpfr_ptr f, unsigned long int l, mpfr_srcptr g,
805: mp_rnd_t mode)
806: { mpfr_ui_div(f, l, g, mode); }
807: static void eval(mpfr_ptr f, mpfr_srcptr g, signed long int l,
808: mp_rnd_t mode)
809: {
810: if (l >= 0)
811: mpfr_div_ui(f, g, l, mode);
812: else
813: {
814: mpfr_div_ui(f, g, -l, mode);
815: mpfr_neg(f, f, mode);
816: }
817: }
818: static void eval(mpfr_ptr f, signed long int l, mpfr_srcptr g,
819: mp_rnd_t mode)
820: {
821: if (l >= 0)
822: mpfr_ui_div(f, l, g, mode);
823: else
824: {
825: mpfr_ui_div(f, -l, g, mode);
826: mpfr_neg(f, f, mode);
827: }
828: }
829: static void eval(mpfr_ptr f, mpfr_srcptr g, double d, mp_rnd_t mode)
830: {
831: mpfr_t temp;
832: mpfr_init2(temp, 8*sizeof(double));
833: mpfr_set_d(temp, d, mode);
834: mpfr_div(f, g, temp, mode);
835: mpfr_clear(temp);
836: }
837: static void eval(mpfr_ptr f, double d, mpfr_srcptr g, mp_rnd_t mode)
838: {
839: mpfr_t temp;
840: mpfr_init2(temp, 8*sizeof(double));
841: mpfr_set_d(temp, d, mode);
842: mpfr_div(f, temp, g, mode);
843: mpfr_clear(temp);
844: }
845: #endif
846: };
847:
848: struct __gmp_binary_modulus
849: {
850: static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v)
851: { mpz_tdiv_r(z, w, v); }
852:
853: static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l)
854: { mpz_tdiv_r_ui(z, w, l); }
855: static void eval(mpz_ptr z, unsigned long int l, mpz_srcptr w)
856: {
857: if (mpz_sgn(w) >= 0)
858: {
859: if (mpz_fits_ulong_p(w))
860: mpz_set_ui(z, l % mpz_get_ui(w));
861: else
862: mpz_set_ui(z, l);
863: }
864: else
865: {
866: mpz_neg(z, w);
867: if (mpz_fits_ulong_p(z))
868: mpz_set_ui(z, l % mpz_get_ui(z));
869: else
870: mpz_set_ui(z, l);
871: }
872: }
873: static void eval(mpz_ptr z, mpz_srcptr w, signed long int l)
874: {
875: if (l >= 0)
876: mpz_mod_ui(z, w, l);
877: else
878: mpz_mod_ui(z, w, -l);
879: }
880: static void eval(mpz_ptr z, signed long int l, mpz_srcptr w)
881: {
882: if (mpz_fits_slong_p(w))
883: mpz_set_si(z, l % mpz_get_si(w));
884: else
885: mpz_set_si(z, l);
886: }
887: static void eval(mpz_ptr z, mpz_srcptr w, double d)
888: {
889: mpz_t temp;
890: mpz_init_set_d(temp, d);
891: mpz_tdiv_r(z, w, temp);
892: mpz_clear(temp);
893: }
894: static void eval(mpz_ptr z, double d, mpz_srcptr w)
895: {
896: mpz_t temp;
897: mpz_init_set_d(temp, d);
898: mpz_tdiv_r(z, temp, w);
899: mpz_clear(temp);
900: }
901: };
902:
903: struct __gmp_binary_and
904: {
905: static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v)
906: { mpz_and(z, w, v); }
907: };
908:
909: struct __gmp_binary_ior
910: {
911: static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v)
912: { mpz_ior(z, w, v); }
913: };
914:
915: struct __gmp_binary_xor
916: {
917: static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v)
918: { mpz_xor(z, w, v); }
919: };
920:
921: struct __gmp_binary_lshift
922: {
923: static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l)
924: { mpz_mul_2exp(z, w, l); }
925: static void eval(mpq_ptr q, mpq_srcptr r, unsigned long int l)
926: { mpq_mul_2exp(q, r, l); }
927: static void eval(mpf_ptr f, mpf_srcptr g, unsigned long int l)
928: { mpf_mul_2exp(f, g, l); }
929: #ifdef __MPFR_H
930: static void eval(mpfr_ptr f, mpfr_srcptr g, unsigned long int l,
931: mp_rnd_t mode)
932: { mpfr_mul_2exp(f, g, l, mode); }
933: #endif
934: };
935:
936: struct __gmp_binary_rshift
937: {
938: static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l)
939: { mpz_tdiv_q_2exp(z, w, l); }
940: static void eval(mpq_ptr q, mpq_srcptr r, unsigned long int l)
941: { mpq_div_2exp(q, r, l); }
942: static void eval(mpf_ptr f, mpf_srcptr g, unsigned long int l)
943: { mpf_div_2exp(f, g, l); }
944: #ifdef __MPFR_H
945: static void eval(mpfr_ptr f, mpfr_srcptr g, unsigned long int l,
946: mp_rnd_t mode)
947: { mpfr_div_2exp(f, g, l, mode); }
948: #endif
949: };
950:
951: struct __gmp_binary_equal
952: {
953: static bool eval(mpz_srcptr z, mpz_srcptr w) { return mpz_cmp(z, w) == 0; }
954:
955: static bool eval(mpz_srcptr z, unsigned long int l)
956: { return mpz_cmp_ui(z, l) == 0; }
957: static bool eval(unsigned long int l, mpz_srcptr z)
958: { return mpz_cmp_ui(z, l) == 0; }
959: static bool eval(mpz_srcptr z, signed long int l)
960: { return mpz_cmp_si(z, l) == 0; }
961: static bool eval(signed long int l, mpz_srcptr z)
962: { return mpz_cmp_si(z, l) == 0; }
963: static bool eval(mpz_srcptr z, double d)
964: { return mpz_cmp_d(z, d) == 0; }
965: static bool eval(double d, mpz_srcptr z)
966: { return mpz_cmp_d(z, d) == 0; }
967:
968: static bool eval(mpq_srcptr q, mpq_srcptr r)
969: { return mpq_equal(q, r) != 0; }
970:
971: static bool eval(mpq_srcptr q, unsigned long int l)
972: { return mpq_cmp_ui(q, l, 1) == 0; }
973: static bool eval(unsigned long int l, mpq_srcptr q)
974: { return mpq_cmp_ui(q, l, 1) == 0; }
975: static bool eval(mpq_srcptr q, signed long int l)
976: { return mpq_cmp_si(q, l, 1) == 0; }
977: static bool eval(signed long int l, mpq_srcptr q)
978: { return mpq_cmp_si(q, l, 1) == 0; }
979: static bool eval(mpq_srcptr q, double d)
980: {
981: bool b;
982: mpq_t temp;
983: mpq_init(temp);
984: mpq_set_d(temp, d);
985: b = (mpq_equal(q, temp) != 0);
986: mpq_clear(temp);
987: return b;
988: }
989: static bool eval(double d, mpq_srcptr q)
990: {
991: bool b;
992: mpq_t temp;
993: mpq_init(temp);
994: mpq_set_d(temp, d);
995: b = (mpq_equal(temp, q) != 0);
996: mpq_clear(temp);
997: return b;
998: }
999:
1000: static bool eval(mpf_srcptr f, mpf_srcptr g) { return mpf_cmp(f, g) == 0; }
1001:
1002: static bool eval(mpf_srcptr f, unsigned long int l)
1003: { return mpf_cmp_ui(f, l) == 0; }
1004: static bool eval(unsigned long int l, mpf_srcptr f)
1005: { return mpf_cmp_ui(f, l) == 0; }
1006: static bool eval(mpf_srcptr f, signed long int l)
1007: { return mpf_cmp_si(f, l) == 0; }
1008: static bool eval(signed long int l, mpf_srcptr f)
1009: { return mpf_cmp_si(f, l) == 0; }
1010: static bool eval(mpf_srcptr f, double d)
1011: { return mpf_cmp_d(f, d) == 0; }
1012: static bool eval(double d, mpf_srcptr f)
1013: { return mpf_cmp_d(f, d) == 0; }
1014:
1015: #ifdef __MPFR_H
1016: static bool eval(mpfr_srcptr f, mpfr_srcptr g)
1017: { return mpfr_cmp(f, g) == 0; }
1018:
1019: static bool eval(mpfr_srcptr f, unsigned long int l)
1020: { return mpfr_cmp_ui(f, l) == 0; }
1021: static bool eval(unsigned long int l, mpfr_srcptr f)
1022: { return mpfr_cmp_ui(f, l) == 0; }
1023: static bool eval(mpfr_srcptr f, signed long int l)
1024: {
1025: if (mpfr_sgn(f) >= 0)
1026: {
1027: if (l >= 0)
1028: return mpfr_cmp_ui(f, l) == 0;
1029: else
1030: return false;
1031: }
1032: else
1033: {
1034: if (l >= 0)
1035: return false;
1036: else
1037: {
1038: bool b;
1039: mpfr_t temp;
1040: mpfr_init2(temp, mpfr_get_prec(f));
1041: mpfr_neg(temp, f, __gmp_default_rounding_mode);
1042: b = (mpfr_cmp_ui(temp, -l) == 0);
1043: mpfr_clear(temp);
1044: return b;
1045: }
1046: }
1047: }
1048: static bool eval(signed long int l, mpfr_srcptr f)
1049: {
1050: if (mpfr_sgn(f) >= 0)
1051: {
1052: if (l >= 0)
1053: return mpfr_cmp_ui(f, l) == 0;
1054: else
1055: return false;
1056: }
1057: else
1058: {
1059: if (l >= 0)
1060: return false;
1061: else
1062: {
1063: bool b;
1064: mpfr_t temp;
1065: mpfr_init2(temp, mpfr_get_prec(f));
1066: mpfr_neg(temp, f, __gmp_default_rounding_mode);
1067: b = (mpfr_cmp_ui(temp, -l) == 0);
1068: mpfr_clear(temp);
1069: return b;
1070: }
1071: }
1072: }
1073: static bool eval(mpfr_srcptr f, double d)
1074: {
1075: bool b;
1076: mpfr_t temp;
1077: mpfr_init2(temp, 8*sizeof(double));
1078: mpfr_set_d(temp, d, __gmp_default_rounding_mode);
1079: b = (mpfr_cmp(f, temp) == 0);
1080: mpfr_clear(temp);
1081: return b;
1082: }
1083: static bool eval(double d, mpfr_srcptr f)
1084: {
1085: bool b;
1086: mpfr_t temp;
1087: mpfr_init2(temp, 8*sizeof(double));
1088: mpfr_set_d(temp, d, __gmp_default_rounding_mode);
1089: b = (mpfr_cmp(temp, f) == 0);
1090: mpfr_clear(temp);
1091: return b;
1092: }
1093: #endif
1094: };
1095:
1096: struct __gmp_binary_not_equal
1097: {
1098: static bool eval(mpz_srcptr z, mpz_srcptr w) { return mpz_cmp(z, w) != 0; }
1099:
1100: static bool eval(mpz_srcptr z, unsigned long int l)
1101: { return mpz_cmp_ui(z, l) != 0; }
1102: static bool eval(unsigned long int l, mpz_srcptr z)
1103: { return mpz_cmp_ui(z, l) != 0; }
1104: static bool eval(mpz_srcptr z, signed long int l)
1105: { return mpz_cmp_si(z, l) != 0; }
1106: static bool eval(signed long int l, mpz_srcptr z)
1107: { return mpz_cmp_si(z, l) != 0; }
1108: static bool eval(mpz_srcptr z, double d)
1109: { return mpz_cmp_d(z, d) != 0; }
1110: static bool eval(double d, mpz_srcptr z)
1111: { return mpz_cmp_d(z, d) != 0; }
1112:
1113: static bool eval(mpq_srcptr q, mpq_srcptr r)
1114: { return mpq_equal(q, r) == 0; }
1115:
1116: static bool eval(mpq_srcptr q, unsigned long int l)
1117: { return mpq_cmp_ui(q, l, 1) != 0; }
1118: static bool eval(unsigned long int l, mpq_srcptr q)
1119: { return mpq_cmp_ui(q, l, 1) != 0; }
1120: static bool eval(mpq_srcptr q, signed long int l)
1121: { return mpq_cmp_si(q, l, 1) != 0; }
1122: static bool eval(signed long int l, mpq_srcptr q)
1123: { return mpq_cmp_si(q, l, 1) != 0; }
1124: static bool eval(mpq_srcptr q, double d)
1125: {
1126: bool b;
1127: mpq_t temp;
1128: mpq_init(temp);
1129: mpq_set_d(temp, d);
1130: b = (mpq_equal(q, temp) == 0);
1131: mpq_clear(temp);
1132: return b;
1133: }
1134: static bool eval(double d, mpq_srcptr q)
1135: {
1136: bool b;
1137: mpq_t temp;
1138: mpq_init(temp);
1139: mpq_set_d(temp, d);
1140: b = (mpq_equal(temp, q) == 0);
1141: mpq_clear(temp);
1142: return b;
1143: }
1144:
1145: static bool eval(mpf_srcptr f, mpf_srcptr g) { return mpf_cmp(f, g) != 0; }
1146:
1147: static bool eval(mpf_srcptr f, unsigned long int l)
1148: { return mpf_cmp_ui(f, l) != 0; }
1149: static bool eval(unsigned long int l, mpf_srcptr f)
1150: { return mpf_cmp_ui(f, l) != 0; }
1151: static bool eval(mpf_srcptr f, signed long int l)
1152: { return mpf_cmp_si(f, l) != 0; }
1153: static bool eval(signed long int l, mpf_srcptr f)
1154: { return mpf_cmp_si(f, l) != 0; }
1155: static bool eval(mpf_srcptr f, double d)
1156: { return mpf_cmp_d(f, d) != 0; }
1157: static bool eval(double d, mpf_srcptr f)
1158: { return mpf_cmp_d(f, d) != 0; }
1159:
1160: #ifdef __MPFR_H
1161: static bool eval(mpfr_srcptr f, mpfr_srcptr g)
1162: { return mpfr_cmp(f, g) != 0; }
1163:
1164: static bool eval(mpfr_srcptr f, unsigned long int l)
1165: { return mpfr_cmp_ui(f, l) != 0; }
1166: static bool eval(unsigned long int l, mpfr_srcptr f)
1167: { return mpfr_cmp_ui(f, l) != 0; }
1168: static bool eval(mpfr_srcptr f, signed long int l)
1169: {
1170: if (mpfr_sgn(f) >= 0)
1171: {
1172: if (l >= 0)
1173: return mpfr_cmp_ui(f, l) != 0;
1174: else
1175: return true;
1176: }
1177: else
1178: {
1179: if (l >= 0)
1180: return true;
1181: else
1182: {
1183: bool b;
1184: mpfr_t temp;
1185: mpfr_init2(temp, mpfr_get_prec(f));
1186: mpfr_neg(temp, f, __gmp_default_rounding_mode);
1187: b = (mpfr_cmp_ui(temp, -l) != 0);
1188: mpfr_clear(temp);
1189: return b;
1190: }
1191: }
1192: }
1193: static bool eval(signed long int l, mpfr_srcptr f)
1194: {
1195: if (mpfr_sgn(f) >= 0)
1196: {
1197: if (l >= 0)
1198: return mpfr_cmp_ui(f, l) != 0;
1199: else
1200: return true;
1201: }
1202: else
1203: {
1204: if (l >= 0)
1205: return true;
1206: else
1207: {
1208: bool b;
1209: mpfr_t temp;
1210: mpfr_init2(temp, mpfr_get_prec(f));
1211: mpfr_neg(temp, f, __gmp_default_rounding_mode);
1212: b = (mpfr_cmp_ui(temp, -l) != 0);
1213: mpfr_clear(temp);
1214: return b;
1215: }
1216: }
1217: }
1218: static bool eval(mpfr_srcptr f, double d)
1219: {
1220: bool b;
1221: mpfr_t temp;
1222: mpfr_init2(temp, 8*sizeof(double));
1223: mpfr_set_d(temp, d, __gmp_default_rounding_mode);
1224: b = (mpfr_cmp(f, temp) != 0);
1225: mpfr_clear(temp);
1226: return b;
1227: }
1228: static bool eval(double d, mpfr_srcptr f)
1229: {
1230: bool b;
1231: mpfr_t temp;
1232: mpfr_init2(temp, 8*sizeof(double));
1233: mpfr_set_d(temp, d, __gmp_default_rounding_mode);
1234: b = (mpfr_cmp(temp, f) != 0);
1235: mpfr_clear(temp);
1236: return b;
1237: }
1238: #endif
1239: };
1240:
1241: struct __gmp_binary_less
1242: {
1243: static bool eval(mpz_srcptr z, mpz_srcptr w) { return mpz_cmp(z, w) < 0; }
1244:
1245: static bool eval(mpz_srcptr z, unsigned long int l)
1246: { return mpz_cmp_ui(z, l) < 0; }
1247: static bool eval(unsigned long int l, mpz_srcptr z)
1248: { return mpz_cmp_ui(z, l) > 0; }
1249: static bool eval(mpz_srcptr z, signed long int l)
1250: { return mpz_cmp_si(z, l) < 0; }
1251: static bool eval(signed long int l, mpz_srcptr z)
1252: { return mpz_cmp_si(z, l) > 0; }
1253: static bool eval(mpz_srcptr z, double d)
1254: { return mpz_cmp_d(z, d) < 0; }
1255: static bool eval(double d, mpz_srcptr z)
1256: { return mpz_cmp_d(z, d) > 0; }
1257:
1258: static bool eval(mpq_srcptr q, mpq_srcptr r) { return mpq_cmp(q, r) < 0; }
1259:
1260: static bool eval(mpq_srcptr q, unsigned long int l)
1261: { return mpq_cmp_ui(q, l, 1) < 0; }
1262: static bool eval(unsigned long int l, mpq_srcptr q)
1263: { return mpq_cmp_ui(q, l, 1) > 0; }
1264: static bool eval(mpq_srcptr q, signed long int l)
1265: { return mpq_cmp_si(q, l, 1) < 0; }
1266: static bool eval(signed long int l, mpq_srcptr q)
1267: { return mpq_cmp_si(q, l, 1) > 0; }
1268: static bool eval(mpq_srcptr q, double d)
1269: {
1270: bool b;
1271: mpq_t temp;
1272: mpq_init(temp);
1273: mpq_set_d(temp, d);
1274: b = (mpq_cmp(q, temp) < 0);
1275: mpq_clear(temp);
1276: return b;
1277: }
1278: static bool eval(double d, mpq_srcptr q)
1279: {
1280: bool b;
1281: mpq_t temp;
1282: mpq_init(temp);
1283: mpq_set_d(temp, d);
1284: b = (mpq_cmp(temp, q) < 0);
1285: mpq_clear(temp);
1286: return b;
1287: }
1288:
1289: static bool eval(mpf_srcptr f, mpf_srcptr g) { return mpf_cmp(f, g) < 0; }
1290:
1291: static bool eval(mpf_srcptr f, unsigned long int l)
1292: { return mpf_cmp_ui(f, l) < 0; }
1293: static bool eval(unsigned long int l, mpf_srcptr f)
1294: { return mpf_cmp_ui(f, l) > 0; }
1295: static bool eval(mpf_srcptr f, signed long int l)
1296: { return mpf_cmp_si(f, l) < 0; }
1297: static bool eval(signed long int l, mpf_srcptr f)
1298: { return mpf_cmp_si(f, l) > 0; }
1299: static bool eval(mpf_srcptr f, double d)
1300: { return mpf_cmp_d(f, d) < 0; }
1301: static bool eval(double d, mpf_srcptr f)
1302: { return mpf_cmp_d(f, d) > 0; }
1303:
1304: #ifdef __MPFR_H
1305: static bool eval(mpfr_srcptr f, mpfr_srcptr g)
1306: { return mpfr_cmp(f, g) < 0; }
1307:
1308: static bool eval(mpfr_srcptr f, unsigned long int l)
1309: { return mpfr_cmp_ui(f, l) < 0; }
1310: static bool eval(unsigned long int l, mpfr_srcptr f)
1311: { return mpfr_cmp_ui(f, l) > 0; }
1312: static bool eval(mpfr_srcptr f, signed long int l)
1313: {
1314: if (mpfr_sgn(f) >= 0)
1315: {
1316: if (l >= 0)
1317: return mpfr_cmp_ui(f, l) < 0;
1318: else
1319: return false;
1320: }
1321: else
1322: {
1323: if (l >= 0)
1324: return true;
1325: else
1326: {
1327: bool b;
1328: mpfr_t temp;
1329: mpfr_init2(temp, mpfr_get_prec(f));
1330: mpfr_neg(temp, f, __gmp_default_rounding_mode);
1331: b = (mpfr_cmp_ui(temp, -l) > 0);
1332: mpfr_clear(temp);
1333: return b;
1334: }
1335: }
1336: }
1337: static bool eval(signed long int l, mpfr_srcptr f)
1338: {
1339: if (mpfr_sgn(f) >= 0)
1340: {
1341: if (l >= 0)
1342: return mpfr_cmp_ui(f, l) > 0;
1343: else
1344: return true;
1345: }
1346: else
1347: {
1348: if (l >= 0)
1349: return false;
1350: else
1351: {
1352: bool b;
1353: mpfr_t temp;
1354: mpfr_init2(temp, mpfr_get_prec(f));
1355: mpfr_neg(temp, f, __gmp_default_rounding_mode);
1356: b = (mpfr_cmp_ui(temp, -l) < 0);
1357: mpfr_clear(temp);
1358: return b;
1359: }
1360: }
1361: }
1362: static bool eval(mpfr_srcptr f, double d)
1363: {
1364: bool b;
1365: mpfr_t temp;
1366: mpfr_init2(temp, 8*sizeof(double));
1367: mpfr_set_d(temp, d, __gmp_default_rounding_mode);
1368: b = (mpfr_cmp(f, temp) < 0);
1369: mpfr_clear(temp);
1370: return b;
1371: }
1372: static bool eval(double d, mpfr_srcptr f)
1373: {
1374: bool b;
1375: mpfr_t temp;
1376: mpfr_init2(temp, 8*sizeof(double));
1377: mpfr_set_d(temp, d, __gmp_default_rounding_mode);
1378: b = (mpfr_cmp(temp, f) < 0);
1379: mpfr_clear(temp);
1380: return b;
1381: }
1382: #endif
1383: };
1384:
1385: struct __gmp_binary_less_equal
1386: {
1387: static bool eval(mpz_srcptr z, mpz_srcptr w) { return mpz_cmp(z, w) <= 0; }
1388:
1389: static bool eval(mpz_srcptr z, unsigned long int l)
1390: { return mpz_cmp_ui(z, l) <= 0; }
1391: static bool eval(unsigned long int l, mpz_srcptr z)
1392: { return mpz_cmp_ui(z, l) >= 0; }
1393: static bool eval(mpz_srcptr z, signed long int l)
1394: { return mpz_cmp_si(z, l) <= 0; }
1395: static bool eval(signed long int l, mpz_srcptr z)
1396: { return mpz_cmp_si(z, l) >= 0; }
1397: static bool eval(mpz_srcptr z, double d)
1398: { return mpz_cmp_d(z, d) <= 0; }
1399: static bool eval(double d, mpz_srcptr z)
1400: { return mpz_cmp_d(z, d) >= 0; }
1401:
1402: static bool eval(mpq_srcptr q, mpq_srcptr r) { return mpq_cmp(q, r) <= 0; }
1403:
1404: static bool eval(mpq_srcptr q, unsigned long int l)
1405: { return mpq_cmp_ui(q, l, 1) <= 0; }
1406: static bool eval(unsigned long int l, mpq_srcptr q)
1407: { return mpq_cmp_ui(q, l, 1) >= 0; }
1408: static bool eval(mpq_srcptr q, signed long int l)
1409: { return mpq_cmp_si(q, l, 1) <= 0; }
1410: static bool eval(signed long int l, mpq_srcptr q)
1411: { return mpq_cmp_si(q, l, 1) >= 0; }
1412: static bool eval(mpq_srcptr q, double d)
1413: {
1414: bool b;
1415: mpq_t temp;
1416: mpq_init(temp);
1417: mpq_set_d(temp, d);
1418: b = (mpq_cmp(q, temp) <= 0);
1419: mpq_clear(temp);
1420: return b;
1421: }
1422: static bool eval(double d, mpq_srcptr q)
1423: {
1424: bool b;
1425: mpq_t temp;
1426: mpq_init(temp);
1427: mpq_set_d(temp, d);
1428: b = (mpq_cmp(temp, q) <= 0);
1429: mpq_clear(temp);
1430: return b;
1431: }
1432:
1433: static bool eval(mpf_srcptr f, mpf_srcptr g) { return mpf_cmp(f, g) <= 0; }
1434:
1435: static bool eval(mpf_srcptr f, unsigned long int l)
1436: { return mpf_cmp_ui(f, l) <= 0; }
1437: static bool eval(unsigned long int l, mpf_srcptr f)
1438: { return mpf_cmp_ui(f, l) >= 0; }
1439: static bool eval(mpf_srcptr f, signed long int l)
1440: { return mpf_cmp_si(f, l) <= 0; }
1441: static bool eval(signed long int l, mpf_srcptr f)
1442: { return mpf_cmp_si(f, l) >= 0; }
1443: static bool eval(mpf_srcptr f, double d)
1444: { return mpf_cmp_d(f, d) <= 0; }
1445: static bool eval(double d, mpf_srcptr f)
1446: { return mpf_cmp_d(f, d) >= 0; }
1447:
1448: #ifdef __MPFR_H
1449: static bool eval(mpfr_srcptr f, mpfr_srcptr g)
1450: { return mpfr_cmp(f, g) <= 0; }
1451:
1452: static bool eval(mpfr_srcptr f, unsigned long int l)
1453: { return mpfr_cmp_ui(f, l) <= 0; }
1454: static bool eval(unsigned long int l, mpfr_srcptr f)
1455: { return mpfr_cmp_ui(f, l) >= 0; }
1456: static bool eval(mpfr_srcptr f, signed long int l)
1457: {
1458: if (mpfr_sgn(f) >= 0)
1459: {
1460: if (l >= 0)
1461: return mpfr_cmp_ui(f, l) <= 0;
1462: else
1463: return false;
1464: }
1465: else
1466: {
1467: if (l >= 0)
1468: return true;
1469: else
1470: {
1471: bool b;
1472: mpfr_t temp;
1473: mpfr_init2(temp, mpfr_get_prec(f));
1474: mpfr_neg(temp, f, __gmp_default_rounding_mode);
1475: b = (mpfr_cmp_ui(temp, -l) >= 0);
1476: mpfr_clear(temp);
1477: return b;
1478: }
1479: }
1480: }
1481: static bool eval(signed long int l, mpfr_srcptr f)
1482: {
1483: if (mpfr_sgn(f) >= 0)
1484: {
1485: if (l >= 0)
1486: return mpfr_cmp_ui(f, l) >= 0;
1487: else
1488: return true;
1489: }
1490: else
1491: {
1492: if (l >= 0)
1493: return false;
1494: else
1495: {
1496: bool b;
1497: mpfr_t temp;
1498: mpfr_init2(temp, mpfr_get_prec(f));
1499: mpfr_neg(temp, f, __gmp_default_rounding_mode);
1500: b = (mpfr_cmp_ui(temp, -l) <= 0);
1501: mpfr_clear(temp);
1502: return b;
1503: }
1504: }
1505: }
1506: static bool eval(mpfr_srcptr f, double d)
1507: {
1508: bool b;
1509: mpfr_t temp;
1510: mpfr_init2(temp, 8*sizeof(double));
1511: mpfr_set_d(temp, d, __gmp_default_rounding_mode);
1512: b = (mpfr_cmp(f, temp) <= 0);
1513: mpfr_clear(temp);
1514: return b;
1515: }
1516: static bool eval(double d, mpfr_srcptr f)
1517: {
1518: bool b;
1519: mpfr_t temp;
1520: mpfr_init2(temp, 8*sizeof(double));
1521: mpfr_set_d(temp, d, __gmp_default_rounding_mode);
1522: b = (mpfr_cmp(temp, f) <= 0);
1523: mpfr_clear(temp);
1524: return b;
1525: }
1526: #endif
1527: };
1528:
1529: struct __gmp_binary_greater
1530: {
1531: static bool eval(mpz_srcptr z, mpz_srcptr w) { return mpz_cmp(z, w) > 0; }
1532:
1533: static bool eval(mpz_srcptr z, unsigned long int l)
1534: { return mpz_cmp_ui(z, l) > 0; }
1535: static bool eval(unsigned long int l, mpz_srcptr z)
1536: { return mpz_cmp_ui(z, l) < 0; }
1537: static bool eval(mpz_srcptr z, signed long int l)
1538: { return mpz_cmp_si(z, l) > 0; }
1539: static bool eval(signed long int l, mpz_srcptr z)
1540: { return mpz_cmp_si(z, l) < 0; }
1541: static bool eval(mpz_srcptr z, double d)
1542: { return mpz_cmp_d(z, d) > 0; }
1543: static bool eval(double d, mpz_srcptr z)
1544: { return mpz_cmp_d(z, d) < 0; }
1545:
1546: static bool eval(mpq_srcptr q, mpq_srcptr r) { return mpq_cmp(q, r) > 0; }
1547:
1548: static bool eval(mpq_srcptr q, unsigned long int l)
1549: { return mpq_cmp_ui(q, l, 1) > 0; }
1550: static bool eval(unsigned long int l, mpq_srcptr q)
1551: { return mpq_cmp_ui(q, l, 1) < 0; }
1552: static bool eval(mpq_srcptr q, signed long int l)
1553: { return mpq_cmp_si(q, l, 1) > 0; }
1554: static bool eval(signed long int l, mpq_srcptr q)
1555: { return mpq_cmp_si(q, l, 1) < 0; }
1556: static bool eval(mpq_srcptr q, double d)
1557: {
1558: bool b;
1559: mpq_t temp;
1560: mpq_init(temp);
1561: mpq_set_d(temp, d);
1562: b = (mpq_cmp(q, temp) > 0);
1563: mpq_clear(temp);
1564: return b;
1565: }
1566: static bool eval(double d, mpq_srcptr q)
1567: {
1568: bool b;
1569: mpq_t temp;
1570: mpq_init(temp);
1571: mpq_set_d(temp, d);
1572: b = (mpq_cmp(temp, q) > 0);
1573: mpq_clear(temp);
1574: return b;
1575: }
1576:
1577: static bool eval(mpf_srcptr f, mpf_srcptr g) { return mpf_cmp(f, g) > 0; }
1578:
1579: static bool eval(mpf_srcptr f, unsigned long int l)
1580: { return mpf_cmp_ui(f, l) > 0; }
1581: static bool eval(unsigned long int l, mpf_srcptr f)
1582: { return mpf_cmp_ui(f, l) < 0; }
1583: static bool eval(mpf_srcptr f, signed long int l)
1584: { return mpf_cmp_si(f, l) > 0; }
1585: static bool eval(signed long int l, mpf_srcptr f)
1586: { return mpf_cmp_si(f, l) < 0; }
1587: static bool eval(mpf_srcptr f, double d)
1588: { return mpf_cmp_d(f, d) > 0; }
1589: static bool eval(double d, mpf_srcptr f)
1590: { return mpf_cmp_d(f, d) < 0; }
1591:
1592: #ifdef __MPFR_H
1593: static bool eval(mpfr_srcptr f, mpfr_srcptr g)
1594: { return mpfr_cmp(f, g) > 0; }
1595:
1596: static bool eval(mpfr_srcptr f, unsigned long int l)
1597: { return mpfr_cmp_ui(f, l) > 0; }
1598: static bool eval(unsigned long int l, mpfr_srcptr f)
1599: { return mpfr_cmp_ui(f, l) < 0; }
1600: static bool eval(mpfr_srcptr f, signed long int l)
1601: {
1602: if (mpfr_sgn(f) >= 0)
1603: {
1604: if (l >= 0)
1605: return mpfr_cmp_ui(f, l) > 0;
1606: else
1607: return true;
1608: }
1609: else
1610: {
1611: if (l >= 0)
1612: return false;
1613: else
1614: {
1615: bool b;
1616: mpfr_t temp;
1617: mpfr_init2(temp, mpfr_get_prec(f));
1618: mpfr_neg(temp, f, __gmp_default_rounding_mode);
1619: b = (mpfr_cmp_ui(temp, -l) < 0);
1620: mpfr_clear(temp);
1621: return b;
1622: }
1623: }
1624: }
1625: static bool eval(signed long int l, mpfr_srcptr f)
1626: {
1627: if (mpfr_sgn(f) >= 0)
1628: {
1629: if (l >= 0)
1630: return mpfr_cmp_ui(f, l) < 0;
1631: else
1632: return false;
1633: }
1634: else
1635: {
1636: if (l >= 0)
1637: return true;
1638: else
1639: {
1640: bool b;
1641: mpfr_t temp;
1642: mpfr_init2(temp, mpfr_get_prec(f));
1643: mpfr_neg(temp, f, __gmp_default_rounding_mode);
1644: b = (mpfr_cmp_ui(temp, -l) > 0);
1645: mpfr_clear(temp);
1646: return b;
1647: }
1648: }
1649: }
1650: static bool eval(mpfr_srcptr f, double d)
1651: {
1652: bool b;
1653: mpfr_t temp;
1654: mpfr_init2(temp, 8*sizeof(double));
1655: mpfr_set_d(temp, d, __gmp_default_rounding_mode);
1656: b = (mpfr_cmp(f, temp) > 0);
1657: mpfr_clear(temp);
1658: return b;
1659: }
1660: static bool eval(double d, mpfr_srcptr f)
1661: {
1662: bool b;
1663: mpfr_t temp;
1664: mpfr_init2(temp, 8*sizeof(double));
1665: mpfr_set_d(temp, d, __gmp_default_rounding_mode);
1666: b = (mpfr_cmp(temp, f) > 0);
1667: mpfr_clear(temp);
1668: return b;
1669: }
1670: #endif
1671: };
1672:
1673: struct __gmp_binary_greater_equal
1674: {
1675: static bool eval(mpz_srcptr z, mpz_srcptr w) { return mpz_cmp(z, w) >= 0; }
1676:
1677: static bool eval(mpz_srcptr z, unsigned long int l)
1678: { return mpz_cmp_ui(z, l) >= 0; }
1679: static bool eval(unsigned long int l, mpz_srcptr z)
1680: { return mpz_cmp_ui(z, l) <= 0; }
1681: static bool eval(mpz_srcptr z, signed long int l)
1682: { return mpz_cmp_si(z, l) >= 0; }
1683: static bool eval(signed long int l, mpz_srcptr z)
1684: { return mpz_cmp_si(z, l) <= 0; }
1685: static bool eval(mpz_srcptr z, double d)
1686: { return mpz_cmp_d(z, d) >= 0; }
1687: static bool eval(double d, mpz_srcptr z)
1688: { return mpz_cmp_d(z, d) <= 0; }
1689:
1690: static bool eval(mpq_srcptr q, mpq_srcptr r) { return mpq_cmp(q, r) >= 0; }
1691:
1692: static bool eval(mpq_srcptr q, unsigned long int l)
1693: { return mpq_cmp_ui(q, l, 1) >= 0; }
1694: static bool eval(unsigned long int l, mpq_srcptr q)
1695: { return mpq_cmp_ui(q, l, 1) <= 0; }
1696: static bool eval(mpq_srcptr q, signed long int l)
1697: { return mpq_cmp_si(q, l, 1) >= 0; }
1698: static bool eval(signed long int l, mpq_srcptr q)
1699: { return mpq_cmp_si(q, l, 1) <= 0; }
1700: static bool eval(mpq_srcptr q, double d)
1701: {
1702: bool b;
1703: mpq_t temp;
1704: mpq_init(temp);
1705: mpq_set_d(temp, d);
1706: b = (mpq_cmp(q, temp) >= 0);
1707: mpq_clear(temp);
1708: return b;
1709: }
1710: static bool eval(double d, mpq_srcptr q)
1711: {
1712: bool b;
1713: mpq_t temp;
1714: mpq_init(temp);
1715: mpq_set_d(temp, d);
1716: b = (mpq_cmp(temp, q) >= 0);
1717: mpq_clear(temp);
1718: return b;
1719: }
1720:
1721: static bool eval(mpf_srcptr f, mpf_srcptr g) { return mpf_cmp(f, g) >= 0; }
1722:
1723: static bool eval(mpf_srcptr f, unsigned long int l)
1724: { return mpf_cmp_ui(f, l) >= 0; }
1725: static bool eval(unsigned long int l, mpf_srcptr f)
1726: { return mpf_cmp_ui(f, l) <= 0; }
1727: static bool eval(mpf_srcptr f, signed long int l)
1728: { return mpf_cmp_si(f, l) >= 0; }
1729: static bool eval(signed long int l, mpf_srcptr f)
1730: { return mpf_cmp_si(f, l) <= 0; }
1731: static bool eval(mpf_srcptr f, double d)
1732: { return mpf_cmp_d(f, d) >= 0; }
1733: static bool eval(double d, mpf_srcptr f)
1734: { return mpf_cmp_d(f, d) <= 0; }
1735:
1736: #ifdef __MPFR_H
1737: static bool eval(mpfr_srcptr f, mpfr_srcptr g)
1738: { return mpfr_cmp(f, g) >= 0; }
1739:
1740: static bool eval(mpfr_srcptr f, unsigned long int l)
1741: { return mpfr_cmp_ui(f, l) >= 0; }
1742: static bool eval(unsigned long int l, mpfr_srcptr f)
1743: { return mpfr_cmp_ui(f, l) <= 0; }
1744: static bool eval(mpfr_srcptr f, signed long int l)
1745: {
1746: if (mpfr_sgn(f) >= 0)
1747: {
1748: if (l >= 0)
1749: return mpfr_cmp_ui(f, l) >= 0;
1750: else
1751: return true;
1752: }
1753: else
1754: {
1755: if (l >= 0)
1756: return false;
1757: else
1758: {
1759: bool b;
1760: mpfr_t temp;
1761: mpfr_init2(temp, mpfr_get_prec(f));
1762: mpfr_neg(temp, f, __gmp_default_rounding_mode);
1763: b = (mpfr_cmp_ui(temp, -l) <= 0);
1764: mpfr_clear(temp);
1765: return b;
1766: }
1767: }
1768: }
1769: static bool eval(signed long int l, mpfr_srcptr f)
1770: {
1771: if (mpfr_sgn(f) >= 0)
1772: {
1773: if (l >= 0)
1774: return mpfr_cmp_ui(f, l) <= 0;
1775: else
1776: return false;
1777: }
1778: else
1779: {
1780: if (l >= 0)
1781: return true;
1782: else
1783: {
1784: bool b;
1785: mpfr_t temp;
1786: mpfr_init2(temp, mpfr_get_prec(f));
1787: mpfr_neg(temp, f, __gmp_default_rounding_mode);
1788: b = (mpfr_cmp_ui(temp, -l) >= 0);
1789: mpfr_clear(temp);
1790: return b;
1791: }
1792: }
1793: }
1794: static bool eval(mpfr_srcptr f, double d)
1795: {
1796: bool b;
1797: mpfr_t temp;
1798: mpfr_init2(temp, 8*sizeof(double));
1799: mpfr_set_d(temp, d, __gmp_default_rounding_mode);
1800: b = (mpfr_cmp(f, temp) >= 0);
1801: mpfr_clear(temp);
1802: return b;
1803: }
1804: static bool eval(double d, mpfr_srcptr f)
1805: {
1806: bool b;
1807: mpfr_t temp;
1808: mpfr_init2(temp, 8*sizeof(double));
1809: mpfr_set_d(temp, d, __gmp_default_rounding_mode);
1810: b = (mpfr_cmp(temp, f) >= 0);
1811: mpfr_clear(temp);
1812: return b;
1813: }
1814: #endif
1815: };
1816:
1817: struct __gmp_unary_increment
1818: {
1819: static void eval(mpz_ptr z, mpz_srcptr w) { mpz_add_ui(z, w, 1); }
1820: static void eval(mpq_ptr q, mpq_srcptr r)
1821: { mpz_add(mpq_numref(q), mpq_numref(r), mpq_denref(r)); }
1822: static void eval(mpf_ptr f, mpf_srcptr g) { mpf_add_ui(f, g, 1); }
1823: #ifdef __MPFR_H
1824: static void eval(mpfr_ptr f, mpfr_srcptr g, mp_rnd_t mode)
1825: { mpfr_add_ui(f, g, 1, mode); }
1826: #endif
1827: };
1828:
1829: struct __gmp_unary_decrement
1830: {
1831: static void eval(mpz_ptr z, mpz_srcptr w) { mpz_sub_ui(z, w, 1); }
1832: static void eval(mpq_ptr q, mpq_srcptr r)
1833: { mpz_sub(mpq_numref(q), mpq_numref(r), mpq_denref(r)); }
1834: static void eval(mpf_ptr f, mpf_srcptr g) { mpf_sub_ui(f, g, 1); }
1835: #ifdef __MPFR_H
1836: static void eval(mpfr_ptr f, mpfr_srcptr g, mp_rnd_t mode)
1837: { mpfr_sub_ui(f, g, 1, mode); }
1838: #endif
1839: };
1840:
1841: struct __gmp_abs_function
1842: {
1843: static void eval(mpz_ptr z, mpz_srcptr w) { mpz_abs(z, w); }
1844: static void eval(mpq_ptr q, mpq_srcptr r) { mpq_abs(q, r); }
1845: static void eval(mpf_ptr f, mpf_srcptr g) { mpf_abs(f, g); }
1846: #ifdef __MPFR_H
1847: static void eval(mpfr_ptr f, mpfr_srcptr g, mp_rnd_t mode)
1848: { mpfr_abs(f, g, mode); }
1849: #endif
1850: };
1851:
1852: struct __gmp_trunc_function
1853: {
1854: static void eval(mpf_ptr f, mpf_srcptr g) { mpf_trunc(f, g); }
1855: #ifdef __MPFR_H
1856: static void eval(mpfr_ptr f, mpfr_srcptr g, mp_rnd_t) { mpfr_trunc(f, g); }
1857: #endif
1858: };
1859:
1860: struct __gmp_floor_function
1861: {
1862: static void eval(mpf_ptr f, mpf_srcptr g) { mpf_floor(f, g); }
1863: #ifdef __MPFR_H
1864: static void eval(mpfr_ptr f, mpfr_srcptr g, mp_rnd_t) { mpfr_floor(f, g); }
1865: #endif
1866: };
1867:
1868: struct __gmp_ceil_function
1869: {
1870: static void eval(mpf_ptr f, mpf_srcptr g) { mpf_ceil(f, g); }
1871: #ifdef __MPFR_H
1872: static void eval(mpfr_ptr f, mpfr_srcptr g, mp_rnd_t) { mpfr_ceil(f, g); }
1873: #endif
1874: };
1875:
1876: struct __gmp_sqrt_function
1877: {
1878: static void eval(mpz_ptr z, mpz_srcptr w) { mpz_sqrt(z, w); }
1879: static void eval(mpf_ptr f, mpf_srcptr g) { mpf_sqrt(f, g); }
1880: #ifdef __MPFR_H
1881: static void eval(mpfr_ptr f, mpfr_srcptr g, mp_rnd_t mode)
1882: { mpfr_sqrt(f, g, mode); }
1883: #endif
1884: };
1885:
1886: struct __gmp_hypot_function
1887: {
1888: static void eval(mpf_ptr f, mpf_srcptr g, mpf_srcptr h)
1889: {
1890: mpf_t temp;
1891: mpf_init2(temp, mpf_get_prec(f));
1892: mpf_mul(temp, g, g);
1893: mpf_mul(f, h, h);
1894: mpf_add(f, f, temp);
1895: mpf_sqrt(f, f);
1896: mpf_clear(temp);
1897: }
1898:
1899: static void eval(mpf_ptr f, mpf_srcptr g, unsigned long int l)
1900: {
1901: mpf_t temp;
1902: mpf_init2(temp, mpf_get_prec(f));
1903: mpf_mul(temp, g, g);
1904: mpf_set_ui(f, l);
1905: mpf_mul(f, f, f);
1906: mpf_add(f, f, temp);
1907: mpf_sqrt(f, f);
1908: mpf_clear(temp);
1909: }
1910: static void eval(mpf_ptr f, unsigned long int l, mpf_srcptr g)
1911: {
1912: mpf_t temp;
1913: mpf_init2(temp, mpf_get_prec(f));
1914: mpf_mul(temp, g, g);
1915: mpf_set_ui(f, l);
1916: mpf_mul(f, f, f);
1917: mpf_add(f, f, temp);
1918: mpf_sqrt(f, f);
1919: mpf_clear(temp);
1920: }
1921: static void eval(mpf_ptr f, mpf_srcptr g, signed long int l)
1922: {
1923: mpf_t temp;
1924: mpf_init2(temp, mpf_get_prec(f));
1925: mpf_mul(temp, g, g);
1926: mpf_set_si(f, l);
1927: mpf_mul(f, f, f);
1928: mpf_add(f, f, temp);
1929: mpf_sqrt(f, f);
1930: mpf_clear(temp);
1931: }
1932: static void eval(mpf_ptr f, signed long int l, mpf_srcptr g)
1933: {
1934: mpf_t temp;
1935: mpf_init2(temp, mpf_get_prec(f));
1936: mpf_mul(temp, g, g);
1937: mpf_set_si(f, l);
1938: mpf_mul(f, f, f);
1939: mpf_add(f, f, temp);
1940: mpf_sqrt(f, f);
1941: mpf_clear(temp);
1942: }
1943: static void eval(mpf_ptr f, mpf_srcptr g, double d)
1944: {
1945: mpf_t temp;
1946: mpf_init2(temp, mpf_get_prec(f));
1947: mpf_mul(temp, g, g);
1948: mpf_set_d(f, d);
1949: mpf_mul(f, f, f);
1950: mpf_add(f, f, temp);
1951: mpf_sqrt(f, f);
1952: mpf_clear(temp);
1953: }
1954: static void eval(mpf_ptr f, double d, mpf_srcptr g)
1955: {
1956: mpf_t temp;
1957: mpf_init2(temp, mpf_get_prec(f));
1958: mpf_mul(temp, g, g);
1959: mpf_set_d(f, d);
1960: mpf_mul(f, f, f);
1961: mpf_add(f, f, temp);
1962: mpf_sqrt(f, f);
1963: mpf_clear(temp);
1964: }
1965:
1966: #ifdef __MPFR_H
1967: static void eval(mpfr_ptr f, mpfr_srcptr g, mpfr_srcptr h, mp_rnd_t mode)
1968: {
1969: mpfr_t temp;
1970: mpfr_init2(temp, mpfr_get_prec(f));
1971: mpfr_mul(temp, g, g, mode);
1972: mpfr_mul(f, h, h, mode);
1973: mpfr_add(f, f, temp, mode);
1974: mpfr_sqrt(f, f, mode);
1975: mpfr_clear(temp);
1976: }
1977:
1978: static void eval(mpfr_ptr f, mpfr_srcptr g, unsigned long int l,
1979: mp_rnd_t mode)
1980: {
1981: mpfr_t temp;
1982: mpfr_init2(temp, mpfr_get_prec(f));
1983: mpfr_mul(temp, g, g, mode);
1984: mpfr_set_ui(f, l, mode);
1985: mpfr_mul(f, f, f, mode);
1986: mpfr_add(f, f, temp, mode);
1987: mpfr_sqrt(f, f, mode);
1988: mpfr_clear(temp);
1989: }
1990: static void eval(mpfr_ptr f, unsigned long int l, mpfr_srcptr g,
1991: mp_rnd_t mode)
1992: {
1993: mpfr_t temp;
1994: mpfr_init2(temp, mpfr_get_prec(f));
1995: mpfr_mul(temp, g, g, mode);
1996: mpfr_set_ui(f, l, mode);
1997: mpfr_mul(f, f, f, mode);
1998: mpfr_add(f, f, temp, mode);
1999: mpfr_sqrt(f, f, mode);
2000: mpfr_clear(temp);
2001: }
2002: static void eval(mpfr_ptr f, mpfr_srcptr g, signed long int l,
2003: mp_rnd_t mode)
2004: {
2005: mpfr_t temp;
2006: mpfr_init2(temp, mpfr_get_prec(f));
2007: mpfr_mul(temp, g, g, mode);
2008: mpfr_set_si(f, l, mode);
2009: mpfr_mul(f, f, f, mode);
2010: mpfr_add(f, f, temp, mode);
2011: mpfr_sqrt(f, f, mode);
2012: mpfr_clear(temp);
2013: }
2014: static void eval(mpfr_ptr f, signed long int l, mpfr_srcptr g,
2015: mp_rnd_t mode)
2016: {
2017: mpfr_t temp;
2018: mpfr_init2(temp, mpfr_get_prec(f));
2019: mpfr_mul(temp, g, g, mode);
2020: mpfr_set_si(f, l, mode);
2021: mpfr_mul(f, f, f, mode);
2022: mpfr_add(f, f, temp, mode);
2023: mpfr_sqrt(f, f, mode);
2024: mpfr_clear(temp);
2025: }
2026: static void eval(mpfr_ptr f, mpfr_srcptr g, double d, mp_rnd_t mode)
2027: {
2028: mpfr_t temp;
2029: mpfr_init2(temp, mpfr_get_prec(f));
2030: mpfr_mul(temp, g, g, mode);
2031: mpfr_set_d(f, d, mode);
2032: mpfr_mul(f, f, f, mode);
2033: mpfr_add(f, f, temp, mode);
2034: mpfr_sqrt(f, f, mode);
2035: mpfr_clear(temp);
2036: }
2037: static void eval(mpfr_ptr f, double d, mpfr_srcptr g, mp_rnd_t mode)
2038: {
2039: mpfr_t temp;
2040: mpfr_init2(temp, mpfr_get_prec(f));
2041: mpfr_mul(temp, g, g, mode);
2042: mpfr_set_d(f, d, mode);
2043: mpfr_mul(f, f, f, mode);
2044: mpfr_add(f, f, temp, mode);
2045: mpfr_sqrt(f, f, mode);
2046: mpfr_clear(temp);
2047: }
2048: #endif
2049: };
2050:
2051: struct __gmp_sgn_function
2052: {
2053: static int eval(mpz_srcptr z) { return mpz_sgn(z); }
2054: static int eval(mpq_srcptr q) { return mpq_sgn(q); }
2055: static int eval(mpf_srcptr f) { return mpf_sgn(f); }
2056: #ifdef __MPFR_H
2057: static int eval(mpfr_srcptr f) { return mpfr_cmp_ui(f, 0); }
2058: #endif
2059: };
2060:
2061: struct __gmp_cmp_function
2062: {
2063: static int eval(mpz_srcptr z, mpz_srcptr w) { return mpz_cmp(z, w); }
2064: static int eval(mpq_srcptr q, mpq_srcptr r) { return mpq_cmp(q, r); }
2065: static int eval(mpf_srcptr f, mpf_srcptr g) { return mpf_cmp(f, g); }
2066: #ifdef __MPFR_H
2067: static int eval(mpfr_srcptr f, mpfr_srcptr g) { return mpfr_cmp(f, g); }
2068: #endif
2069: };
2070:
2071: struct __gmp_rand_function
2072: {
2073: static void eval(mpz_ptr z, gmp_randstate_t s, unsigned long int l)
2074: { mpz_urandomb(z, s, l); }
2075: static void eval(mpz_ptr z, gmp_randstate_t s, mpz_srcptr w)
2076: { mpz_urandomm(z, s, w); }
2077: static void eval(mpf_ptr f, gmp_randstate_t s, unsigned long int prec)
2078: { mpf_urandomb(f, s, prec); }
2079: };
2080:
2081:
2082: /**************** Auxiliary classes ****************/
2083:
2084: /* this is the same as gmp_allocated_string in gmp-impl.h
2085: since gmp-impl.h is not publicly available, I redefine it here
2086: I use a different name to avoid possible clashes */
2087: struct __gmp_alloc_cstring
2088: {
2089: char *str;
2090: __gmp_alloc_cstring(char *s) { str = s; }
2091: ~__gmp_alloc_cstring() { __gmp_free_func(str, strlen(str)+1); }
2092: };
2093:
2094:
2095: template <class T, class U>
2096: class __gmp_expr;
2097:
2098: template <class T>
2099: struct __gmp_resolve_ref
2100: {
2101: typedef T ref_type;
2102: };
2103:
2104: template <class T, class U>
2105: struct __gmp_resolve_ref<__gmp_expr<T, U> >
2106: {
2107: typedef const __gmp_expr<T, U> & ref_type;
2108: };
2109:
2110: template <class T, class Op>
2111: struct __gmp_unary_expr
2112: {
2113: typename __gmp_resolve_ref<T>::ref_type val;
2114: __gmp_unary_expr(const T &v) : val(v) { }
2115: private:
2116: __gmp_unary_expr();
2117: };
2118:
2119: template <class T, class U, class Op>
2120: struct __gmp_binary_expr
2121: {
2122: typename __gmp_resolve_ref<T>::ref_type val1;
2123: typename __gmp_resolve_ref<U>::ref_type val2;
2124: __gmp_binary_expr(const T &v1, const U &v2) : val1(v1), val2(v2) { }
2125: private:
2126: __gmp_binary_expr();
2127: };
2128:
2129:
2130: class __gmpz_value { };
2131: class __gmpzref_value { };
2132: class __gmpq_value { };
2133: class __gmpf_value { };
2134:
2135:
2136: template <class T, class U>
2137: void __gmp_set_expr(mpz_ptr, const __gmp_expr<T, U> &);
2138: template <class T, class U>
2139: void __gmp_set_expr(mpq_ptr, const __gmp_expr<T, U> &);
2140: template <class T, class U>
2141: void __gmp_set_expr(mpf_ptr, const __gmp_expr<T, U> &);
2142:
2143:
2144: /**************** Macros for in-class declarations ****************/
2145: /* This is just repetitive code that is easier to maintain if it's written
2146: only once */
2147:
2148: #define __GMPZZ_DECLARE_COMPOUND_OPERATOR(fun) \
2149: template <class T, class U> \
2150: __gmp_expr<__gmpz_value, __gmpz_value> & fun(const __gmp_expr<T, U> &);
2151:
2152: #define __GMPZN_DECLARE_COMPOUND_OPERATOR(fun) \
2153: __gmp_expr & fun(signed char); \
2154: __gmp_expr & fun(unsigned char); \
2155: __gmp_expr & fun(signed int); \
2156: __gmp_expr & fun(unsigned int); \
2157: __gmp_expr & fun(signed short int); \
2158: __gmp_expr & fun(unsigned short int); \
2159: __gmp_expr & fun(signed long int); \
2160: __gmp_expr & fun(unsigned long int); \
2161: __gmp_expr & fun(float); \
2162: __gmp_expr & fun(double); \
2163: __gmp_expr & fun(long double);
2164:
2165: #define __GMPZ_DECLARE_COMPOUND_OPERATOR(fun) \
2166: __GMPZZ_DECLARE_COMPOUND_OPERATOR(fun) \
2167: __GMPZN_DECLARE_COMPOUND_OPERATOR(fun)
2168:
2169: #define __GMPZ_DECLARE_COMPOUND_OPERATOR_UI(fun) \
2170: __gmp_expr & fun(unsigned long int);
2171:
2172: #define __GMPZ_DECLARE_INCREMENT_OPERATOR(fun) \
2173: inline __gmp_expr & fun(); \
2174: inline __gmp_expr fun(int);
2175:
2176: #define __GMPZRR_DECLARE_COMPOUND_OPERATOR(fun) \
2177: template <class T, class U> \
2178: __gmp_expr<__gmpz_value, __gmpzref_value> & fun(const __gmp_expr<T, U> &);
2179:
2180: #define __GMPZRN_DECLARE_COMPOUND_OPERATOR(fun) \
2181: __gmp_expr & fun(signed char); \
2182: __gmp_expr & fun(unsigned char); \
2183: __gmp_expr & fun(signed int); \
2184: __gmp_expr & fun(unsigned int); \
2185: __gmp_expr & fun(signed short int); \
2186: __gmp_expr & fun(unsigned short int); \
2187: __gmp_expr & fun(signed long int); \
2188: __gmp_expr & fun(unsigned long int); \
2189: __gmp_expr & fun(float); \
2190: __gmp_expr & fun(double); \
2191: __gmp_expr & fun(long double);
2192:
2193: #define __GMPZR_DECLARE_COMPOUND_OPERATOR(fun) \
2194: __GMPZRR_DECLARE_COMPOUND_OPERATOR(fun) \
2195: __GMPZRN_DECLARE_COMPOUND_OPERATOR(fun)
2196:
2197: #define __GMPZR_DECLARE_COMPOUND_OPERATOR_UI(fun) \
2198: __gmp_expr & fun(unsigned long int);
2199:
2200: #define __GMPZR_DECLARE_INCREMENT_OPERATOR(fun) \
2201: inline __gmp_expr & fun(); \
2202: inline mpz_class fun(int);
2203:
2204: #define __GMPQQ_DECLARE_COMPOUND_OPERATOR(fun) \
2205: template <class T, class U> \
2206: __gmp_expr<__gmpq_value, __gmpq_value> & fun(const __gmp_expr<T, U> &);
2207:
2208: #define __GMPQN_DECLARE_COMPOUND_OPERATOR(fun) \
2209: __gmp_expr & fun(signed char); \
2210: __gmp_expr & fun(unsigned char); \
2211: __gmp_expr & fun(signed int); \
2212: __gmp_expr & fun(unsigned int); \
2213: __gmp_expr & fun(signed short int); \
2214: __gmp_expr & fun(unsigned short int); \
2215: __gmp_expr & fun(signed long int); \
2216: __gmp_expr & fun(unsigned long int); \
2217: __gmp_expr & fun(float); \
2218: __gmp_expr & fun(double); \
2219: __gmp_expr & fun(long double);
2220:
2221: #define __GMPQ_DECLARE_COMPOUND_OPERATOR(fun) \
2222: __GMPQQ_DECLARE_COMPOUND_OPERATOR(fun) \
2223: __GMPQN_DECLARE_COMPOUND_OPERATOR(fun)
2224:
2225: #define __GMPQ_DECLARE_COMPOUND_OPERATOR_UI(fun) \
2226: __gmp_expr & fun(unsigned long int);
2227:
2228: #define __GMPQ_DECLARE_INCREMENT_OPERATOR(fun) \
2229: inline __gmp_expr & fun(); \
2230: inline __gmp_expr fun(int);
2231:
2232: #define __GMPFF_DECLARE_COMPOUND_OPERATOR(fun) \
2233: template <class T, class U> \
2234: __gmp_expr<__gmpf_value, __gmpf_value> & fun(const __gmp_expr<T, U> &);
2235:
2236: #define __GMPFN_DECLARE_COMPOUND_OPERATOR(fun) \
2237: __gmp_expr & fun(signed char); \
2238: __gmp_expr & fun(unsigned char); \
2239: __gmp_expr & fun(signed int); \
2240: __gmp_expr & fun(unsigned int); \
2241: __gmp_expr & fun(signed short int); \
2242: __gmp_expr & fun(unsigned short int); \
2243: __gmp_expr & fun(signed long int); \
2244: __gmp_expr & fun(unsigned long int); \
2245: __gmp_expr & fun(float); \
2246: __gmp_expr & fun(double); \
2247: __gmp_expr & fun(long double);
2248:
2249: #define __GMPF_DECLARE_COMPOUND_OPERATOR(fun) \
2250: __GMPFF_DECLARE_COMPOUND_OPERATOR(fun) \
2251: __GMPFN_DECLARE_COMPOUND_OPERATOR(fun)
2252:
2253: #define __GMPF_DECLARE_COMPOUND_OPERATOR_UI(fun) \
2254: __gmp_expr & fun(unsigned long int);
2255:
2256: #define __GMPF_DECLARE_INCREMENT_OPERATOR(fun) \
2257: inline __gmp_expr & fun(); \
2258: inline __gmp_expr fun(int);
2259:
2260:
2261: /**************** mpz_class -- wrapper for mpz_t ****************/
2262:
2263: template <>
2264: class __gmp_expr<__gmpz_value, __gmpz_value>
2265: {
2266: private:
2267: mpz_t mp;
2268: public:
2269: unsigned long int get_prec() const { return mpf_get_default_prec(); }
2270:
2271: // constructors and destructor
2272: __gmp_expr() { mpz_init(mp); }
2273:
2274: __gmp_expr(const __gmp_expr &z) { mpz_init_set(mp, z.mp); }
2275: template <class T, class U>
2276: __gmp_expr(const __gmp_expr<T, U> &expr)
2277: { mpz_init(mp); __gmp_set_expr(mp, expr); }
2278:
2279: __gmp_expr(signed char c) { mpz_init_set_si(mp, c); }
2280: __gmp_expr(unsigned char c) { mpz_init_set_ui(mp, c); }
2281:
2282: __gmp_expr(signed int i) { mpz_init_set_si(mp, i); }
2283: __gmp_expr(unsigned int i) { mpz_init_set_ui(mp, i); }
2284:
2285: __gmp_expr(signed short int s) { mpz_init_set_si(mp, s); }
2286: __gmp_expr(unsigned short int s) { mpz_init_set_ui(mp, s); }
2287:
2288: __gmp_expr(signed long int l) { mpz_init_set_si(mp, l); }
2289: __gmp_expr(unsigned long int l) { mpz_init_set_ui(mp, l); }
2290:
2291: __gmp_expr(float f) { mpz_init_set_d(mp, f); }
2292: __gmp_expr(double d) { mpz_init_set_d(mp, d); }
2293: // __gmp_expr(long double ld) { mpz_init_set_d(mp, ld); }
2294:
2295: explicit __gmp_expr(const char *s)
2296:
2297: { mpz_init_set_str(mp, s, 0); }
2298: __gmp_expr(const char *s, int base)
2299: { mpz_init_set_str(mp, s, base); }
2300: explicit __gmp_expr(const std::string &s)
2301: { mpz_init_set_str(mp, s.c_str(), 0); }
2302: __gmp_expr(const std::string &s, int base)
2303: { mpz_init_set_str(mp, s.c_str(), base); }
2304:
2305: explicit __gmp_expr(mpz_srcptr z) { mpz_init_set(mp, z); }
2306:
2307: ~__gmp_expr() { mpz_clear(mp); }
2308:
2309: // assignment operators
2310: __gmp_expr & operator=(const __gmp_expr &z)
2311: { mpz_set(mp, z.mp); return *this; }
2312: template <class T, class U>
2313: __gmp_expr<__gmpz_value, __gmpz_value> & operator=
2314: (const __gmp_expr<T, U> &expr)
2315: { __gmp_set_expr(mp, expr); return *this; }
2316:
2317: __gmp_expr & operator=(signed char c) { mpz_set_si(mp, c); return *this; }
2318: __gmp_expr & operator=(unsigned char c) { mpz_set_ui(mp, c); return *this; }
2319:
2320: __gmp_expr & operator=(signed int i) { mpz_set_si(mp, i); return *this; }
2321: __gmp_expr & operator=(unsigned int i) { mpz_set_ui(mp, i); return *this; }
2322:
2323: __gmp_expr & operator=(signed short int s)
2324: { mpz_set_si(mp, s); return *this; }
2325: __gmp_expr & operator=(unsigned short int s)
2326: { mpz_set_ui(mp, s); return *this; }
2327:
2328: __gmp_expr & operator=(signed long int l)
2329: { mpz_set_si(mp, l); return *this; }
2330: __gmp_expr & operator=(unsigned long int l)
2331: { mpz_set_ui(mp, l); return *this; }
2332:
2333: __gmp_expr & operator=(float f) { mpz_set_d(mp, f); return *this; }
2334: __gmp_expr & operator=(double d) { mpz_set_d(mp, d); return *this; }
2335: /*
2336: __gmp_expr & operator=(long double ld) { mpz_set_ld(mp, ld); return *this; }
2337: */
2338:
2339: __gmp_expr & operator=(const char *s)
2340: { mpz_set_str(mp, s, 0); return *this; }
2341: __gmp_expr & operator=(const std::string &s)
2342: { mpz_set_str(mp, s.c_str(), 0); return *this; }
2343:
2344: // string input/output functions
2345: int set_str(const std::string &s, int base)
2346: { return mpz_set_str(mp, s.c_str(), base); }
2347: std::string get_str(int base = 10) const
2348: {
2349: __gmp_alloc_cstring temp(mpz_get_str(0, base, mp));
2350: return std::string(temp.str);
2351: }
2352:
2353: // conversion functions
2354: mpz_srcptr get_mpz_t() const { return mp; }
2355: mpz_ptr get_mpz_t() { return mp; }
2356:
2357: signed long int get_si() const { return mpz_get_si(mp); }
2358: unsigned long int get_ui() const { return mpz_get_ui(mp); }
2359: double get_d() const { return mpz_get_d(mp); } // should be long double
2360:
2361: // bool fits_schar_p() const { return mpz_fits_schar_p(mp); }
2362: // bool fits_uchar_p() const { return mpz_fits_uchar_p(mp); }
2363: bool fits_sint_p() const { return mpz_fits_sint_p(mp); }
2364: bool fits_uint_p() const { return mpz_fits_uint_p(mp); }
2365: bool fits_sshort_p() const { return mpz_fits_sshort_p(mp); }
2366: bool fits_ushort_p() const { return mpz_fits_ushort_p(mp); }
2367: bool fits_slong_p() const { return mpz_fits_slong_p(mp); }
2368: bool fits_ulong_p() const { return mpz_fits_ulong_p(mp); }
2369: // bool fits_float_p() const { return mpz_fits_float_p(mp); }
2370: // bool fits_double_p() const { return mpz_fits_double_p(mp); }
2371: // bool fits_ldouble_p() const { return mpz_fits_ldouble_p(mp); }
2372:
2373: // member operators
2374: __GMPZ_DECLARE_COMPOUND_OPERATOR(operator+=)
2375: __GMPZ_DECLARE_COMPOUND_OPERATOR(operator-=)
2376: __GMPZ_DECLARE_COMPOUND_OPERATOR(operator*=)
2377: __GMPZ_DECLARE_COMPOUND_OPERATOR(operator/=)
2378: __GMPZ_DECLARE_COMPOUND_OPERATOR(operator%=)
2379:
2380: __GMPZZ_DECLARE_COMPOUND_OPERATOR(operator&=)
2381: __GMPZZ_DECLARE_COMPOUND_OPERATOR(operator|=)
2382: __GMPZZ_DECLARE_COMPOUND_OPERATOR(operator^=)
2383:
2384: __GMPZ_DECLARE_COMPOUND_OPERATOR_UI(operator<<=)
2385: __GMPZ_DECLARE_COMPOUND_OPERATOR_UI(operator>>=)
2386:
2387: __GMPZ_DECLARE_INCREMENT_OPERATOR(operator++)
2388: __GMPZ_DECLARE_INCREMENT_OPERATOR(operator--)
2389: };
2390:
2391: typedef __gmp_expr<__gmpz_value, __gmpz_value> mpz_class;
2392:
2393:
2394: inline std::ostream & operator<<(std::ostream &o, const mpz_class &z)
2395: {
2396: return o << z.get_mpz_t();
2397: }
2398:
2399: template <class T>
2400: inline std::ostream & operator<<
2401: (std::ostream &o, const __gmp_expr<__gmpz_value, T> &expr)
2402: {
2403: mpz_class temp(expr);
2404: return o << temp.get_mpz_t();
2405: }
2406:
2407: inline std::istream & operator>>(std::istream &i, mpz_class &z)
2408: {
2409: return i >> z.get_mpz_t();
2410: }
2411:
2412:
2413: /**************** mpz_classref -- num/den of mpq_t ****************/
2414:
2415: template <>
2416: class __gmp_expr<__gmpz_value, __gmpzref_value>
2417: {
2418: friend class __gmp_expr<__gmpq_value, __gmpq_value>;
2419: private:
2420: mpz_ptr ref;
2421:
2422: __gmp_expr();
2423: // __gmp_expr(const __gmp_expr &);
2424: __gmp_expr(mpz_ptr z) : ref(z) { }
2425: __gmp_expr(mpz_srcptr z) : ref((mpz_ptr) z) { }
2426: public:
2427: unsigned long int get_prec() const { return mpf_get_default_prec(); }
2428:
2429: // assignment operators
2430: __gmp_expr & operator=(const __gmp_expr &z)
2431: { mpz_set(ref, z.ref); return *this; }
2432: __gmp_expr & operator=(const mpz_class &z)
2433: { mpz_set(ref, z.get_mpz_t()); return *this; }
2434: template <class T, class U>
2435: __gmp_expr<__gmpz_value, __gmpzref_value> & operator=
2436: (const __gmp_expr<T, U> &expr)
2437: { __gmp_set_expr(ref, expr); return *this; }
2438:
2439: __gmp_expr & operator=(signed char c) { mpz_set_si(ref, c); return *this; }
2440: __gmp_expr & operator=(unsigned char c)
2441: { mpz_set_ui(ref, c); return *this; }
2442:
2443: __gmp_expr & operator=(signed int i) { mpz_set_si(ref, i); return *this; }
2444: __gmp_expr & operator=(unsigned int i) { mpz_set_ui(ref, i); return *this; }
2445:
2446: __gmp_expr & operator=(signed short int s)
2447: { mpz_set_si(ref, s); return *this; }
2448: __gmp_expr & operator=(unsigned short int s)
2449: { mpz_set_ui(ref, s); return *this; }
2450:
2451: __gmp_expr & operator=(signed long int l)
2452: { mpz_set_si(ref, l); return *this; }
2453: __gmp_expr & operator=(unsigned long int l)
2454: { mpz_set_ui(ref, l); return *this; }
2455:
2456: __gmp_expr & operator=(float f) { mpz_set_d(ref, f); return *this; }
2457: __gmp_expr & operator=(double d) { mpz_set_d(ref, d); return *this; }
2458: /*
2459: __gmp_expr & operator=(long double ld)
2460: { mpz_set_ld(ref, ld); return *this; }
2461: */
2462:
2463: __gmp_expr & operator=(const char *s)
2464: { mpz_set_str(ref, s, 0); return *this; }
2465: __gmp_expr & operator=(const std::string &s)
2466: { mpz_set_str(ref, s.c_str(), 0); return *this; }
2467:
2468: // string input/output functions
2469: int set_str(const std::string &s, int base)
2470: { return mpz_set_str(ref, s.c_str(), base); }
2471: std::string get_str(int base = 10) const
2472: {
2473: __gmp_alloc_cstring temp(mpz_get_str(0, base, ref));
2474: return std::string(temp.str);
2475: }
2476:
2477: // conversion functions
2478: mpz_srcptr get_mpz_t() const { return ref; }
2479: mpz_ptr get_mpz_t() { return ref; }
2480:
2481: signed long int get_si() const { return mpz_get_si(ref); }
2482: unsigned long int get_ui() const { return mpz_get_ui(ref); }
2483: double get_d() const { return mpz_get_d(ref); } // should be long double
2484:
2485: // bool fits_bool_p() const { return mpz_fits_bool_p(ref); }
2486: // bool fits_schar_p() const { return mpz_fits_schar_p(ref); }
2487: // bool fits_uchar_p() const { return mpz_fits_uchar_p(ref); }
2488: bool fits_sint_p() const { return mpz_fits_sint_p(ref); }
2489: bool fits_uint_p() const { return mpz_fits_uint_p(ref); }
2490: bool fits_sshort_p() const { return mpz_fits_sshort_p(ref); }
2491: bool fits_ushort_p() const { return mpz_fits_ushort_p(ref); }
2492: bool fits_slong_p() const { return mpz_fits_slong_p(ref); }
2493: bool fits_ulong_p() const { return mpz_fits_ulong_p(ref); }
2494: // bool fits_float_p() const { return mpz_fits_float_p(ref); }
2495: // bool fits_double_p() const { return mpz_fits_double_p(ref); }
2496: // bool fits_ldouble_p() const { return mpz_fits_ldouble_p(ref); }
2497:
2498: // member operators
2499: __GMPZR_DECLARE_COMPOUND_OPERATOR(operator+=)
2500: __GMPZR_DECLARE_COMPOUND_OPERATOR(operator-=)
2501: __GMPZR_DECLARE_COMPOUND_OPERATOR(operator*=)
2502: __GMPZR_DECLARE_COMPOUND_OPERATOR(operator/=)
2503: __GMPZR_DECLARE_COMPOUND_OPERATOR(operator%=)
2504:
2505: __GMPZRR_DECLARE_COMPOUND_OPERATOR(operator&=)
2506: __GMPZRR_DECLARE_COMPOUND_OPERATOR(operator|=)
2507: __GMPZRR_DECLARE_COMPOUND_OPERATOR(operator^=)
2508:
2509: __GMPZR_DECLARE_COMPOUND_OPERATOR_UI(operator<<=)
2510: __GMPZR_DECLARE_COMPOUND_OPERATOR_UI(operator>>=)
2511:
2512: __GMPZR_DECLARE_INCREMENT_OPERATOR(operator++)
2513: __GMPZR_DECLARE_INCREMENT_OPERATOR(operator--)
2514: };
2515:
2516: typedef __gmp_expr<__gmpz_value, __gmpzref_value> mpz_classref;
2517:
2518:
2519: inline std::ostream & operator<<(std::ostream &o, const mpz_classref &z)
2520: {
2521: return o << z.get_mpz_t();
2522: }
2523:
2524: inline std::istream & operator>>(std::istream &i, mpz_classref &z)
2525: {
2526: return i >> z.get_mpz_t();
2527: }
2528:
2529: /**************** mpq_class -- wrapper for mpq_t ****************/
2530:
2531: template <>
2532: class __gmp_expr<__gmpq_value, __gmpq_value>
2533: {
2534: private:
2535: mpq_t mp;
2536: public:
2537: unsigned long int get_prec() const { return mpf_get_default_prec(); }
2538: void canonicalize() { mpq_canonicalize(mp); }
2539:
2540: // constructors and destructor
2541: __gmp_expr() { mpq_init(mp); }
2542:
2543: __gmp_expr(const __gmp_expr &q) { mpq_init(mp); mpq_set(mp, q.mp); }
2544: template <class T, class U>
2545: __gmp_expr(const __gmp_expr<T, U> &expr)
2546: { mpq_init(mp); __gmp_set_expr(mp, expr); }
2547:
2548: __gmp_expr(signed char c) { mpq_init(mp); mpq_set_si(mp, c, 1); }
2549: __gmp_expr(unsigned char c) { mpq_init(mp); mpq_set_ui(mp, c, 1); }
2550:
2551: __gmp_expr(signed int i) { mpq_init(mp); mpq_set_si(mp, i, 1); }
2552: __gmp_expr(unsigned int i) { mpq_init(mp); mpq_set_ui(mp, i, 1); }
2553:
2554: __gmp_expr(signed short int s) { mpq_init(mp); mpq_set_si(mp, s, 1); }
2555: __gmp_expr(unsigned short int s) { mpq_init(mp); mpq_set_ui(mp, s, 1); }
2556:
2557: __gmp_expr(signed long int l) { mpq_init(mp); mpq_set_si(mp, l, 1); }
2558: __gmp_expr(unsigned long int l) { mpq_init(mp); mpq_set_ui(mp, l, 1); }
2559:
2560: __gmp_expr(float f) { mpq_init(mp); mpq_set_d(mp, f); }
2561: __gmp_expr(double d) { mpq_init(mp); mpq_set_d(mp, d); }
2562: // __gmp_expr(long double ld) { mpq_init(mp); mpq_set_ld(mp, ld); }
2563:
2564: explicit __gmp_expr(const char *s)
2565: { mpq_init(mp); mpq_set_str(mp, s, 0); }
2566: __gmp_expr(const char *s, unsigned long int base)
2567: { mpq_init(mp); mpq_set_str(mp, s, base); }
2568: explicit __gmp_expr(const std::string &s)
2569: { mpq_init(mp); mpq_set_str(mp, s.c_str(), 0); }
2570: __gmp_expr(const std::string &s, unsigned long int base)
2571: { mpq_init(mp); mpq_set_str(mp, s.c_str(), base); }
2572:
2573: explicit __gmp_expr(mpq_srcptr q) { mpq_init(mp); mpq_set(mp, q); }
2574:
2575: __gmp_expr(const mpz_class &num, const mpz_class &den)
2576: {
2577: mpq_init(mp);
2578: mpz_set(mpq_numref(mp), num.get_mpz_t());
2579: mpz_set(mpq_denref(mp), den.get_mpz_t());
2580: }
2581: // this is defined later (after __gmpz_temp)
2582: template <class T, class U>
2583: __gmp_expr(const __gmp_expr<__gmpz_value, T> &,
2584: const __gmp_expr<__gmpz_value, U> &);
2585:
2586: ~__gmp_expr() { mpq_clear(mp); }
2587:
2588: // assignment operators
2589: __gmp_expr & operator=(const __gmp_expr &q)
2590: { mpq_set(mp, q.mp); return *this; }
2591: template <class T, class U>
2592: __gmp_expr<__gmpq_value, __gmpq_value> & operator=
2593: (const __gmp_expr<T, U> &expr)
2594: { __gmp_set_expr(mp, expr); return *this; }
2595:
2596: __gmp_expr & operator=(signed char c)
2597: { mpq_set_si(mp, c, 1); return *this; }
2598: __gmp_expr & operator=(unsigned char c)
2599: { mpq_set_ui(mp, c, 1); return *this; }
2600:
2601: __gmp_expr & operator=(signed int i) { mpq_set_si(mp, i, 1); return *this; }
2602: __gmp_expr & operator=(unsigned int i)
2603: { mpq_set_ui(mp, i, 1); return *this; }
2604:
2605: __gmp_expr & operator=(signed short int s)
2606: { mpq_set_si(mp, s, 1); return *this; }
2607: __gmp_expr & operator=(unsigned short int s)
2608: { mpq_set_ui(mp, s, 1); return *this; }
2609:
2610: __gmp_expr & operator=(signed long int l)
2611: { mpq_set_si(mp, l, 1); return *this; }
2612: __gmp_expr & operator=(unsigned long int l)
2613: { mpq_set_ui(mp, l, 1); return *this; }
2614:
2615: __gmp_expr & operator=(float f) { mpq_set_d(mp, f); return *this; }
2616: __gmp_expr & operator=(double d) { mpq_set_d(mp, d); return *this; }
2617: /*
2618: __gmp_expr & operator=(long double ld) { mpq_set_ld(mp, ld); return *this; }
2619: */
2620:
2621: __gmp_expr & operator=(const char *s)
2622: { mpq_set_str(mp, s, 0); return *this; }
2623: __gmp_expr & operator=(const std::string &s)
2624: { mpq_set_str(mp, s.c_str(), 0); return *this; }
2625:
2626: // string input/output functions
2627: int set_str(const std::string &s, int base)
2628: { return mpq_set_str(mp, s.c_str(), base); }
2629: std::string get_str(int base = 10) const
2630: {
2631: __gmp_alloc_cstring temp(mpq_get_str(0, base, mp));
2632: return std::string(temp.str);
2633: }
2634:
2635: // conversion functions
2636:
2637: // casting a reference to an mpz_t to mpz_class & is a dirty hack,
2638: // but works because the internal representation of mpz_class is
2639: // exactly an mpz_t
2640: const mpz_class & get_num() const
2641: { return reinterpret_cast<const mpz_class &>(*mpq_numref(mp)); }
2642: mpz_class & get_num()
2643: { return reinterpret_cast<mpz_class &>(*mpq_numref(mp)); }
2644: const mpz_class & get_den() const
2645: { return reinterpret_cast<const mpz_class &>(*mpq_denref(mp)); }
2646: mpz_class & get_den()
2647: { return reinterpret_cast<mpz_class &>(*mpq_denref(mp)); }
2648:
2649: mpq_srcptr get_mpq_t() const { return mp; }
2650: mpq_ptr get_mpq_t() { return mp; }
2651:
2652: mpz_srcptr get_num_mpz_t() const { return mpq_numref(mp); }
2653: mpz_ptr get_num_mpz_t() { return mpq_numref(mp); }
2654: mpz_srcptr get_den_mpz_t() const { return mpq_denref(mp); }
2655: mpz_ptr get_den_mpz_t() { return mpq_denref(mp); }
2656:
2657: double get_d() const { return mpq_get_d(mp); } // should be long double
2658:
2659: // compound assignments
2660: __GMPQ_DECLARE_COMPOUND_OPERATOR(operator+=)
2661: __GMPQ_DECLARE_COMPOUND_OPERATOR(operator-=)
2662: __GMPQ_DECLARE_COMPOUND_OPERATOR(operator*=)
2663: __GMPQ_DECLARE_COMPOUND_OPERATOR(operator/=)
2664:
2665: __GMPQ_DECLARE_COMPOUND_OPERATOR_UI(operator<<=)
2666: __GMPQ_DECLARE_COMPOUND_OPERATOR_UI(operator>>=)
2667:
2668: __GMPQ_DECLARE_INCREMENT_OPERATOR(operator++)
2669: __GMPQ_DECLARE_INCREMENT_OPERATOR(operator--)
2670: };
2671:
2672: typedef __gmp_expr<__gmpq_value, __gmpq_value> mpq_class;
2673:
2674:
2675: inline std::ostream & operator<<(std::ostream &o, const mpq_class &q)
2676: {
2677: return o << q.get_mpq_t();
2678: }
2679:
2680: template <class T>
2681: inline std::ostream & operator<<
2682: (std::ostream &o, const __gmp_expr<__gmpq_value, T> &expr)
2683: {
2684: mpq_class temp(expr);
2685: return o << temp.get_mpq_t();
2686: }
2687:
2688: inline std::istream & operator>>(std::istream &i, mpq_class &q)
2689: {
2690: i >> q.get_mpq_t();
2691: // q.canonicalize();
2692: return i;
2693: }
2694:
2695:
2696: /**************** mpf_class -- wrapper for mpf_t ****************/
2697:
2698: template <>
2699: class __gmp_expr<__gmpf_value, __gmpf_value>
2700: {
2701: private:
2702: mpf_t mp;
2703: public:
2704: // size information
2705: unsigned long int get_prec() const { return mpf_get_prec(mp); }
2706:
2707: void set_prec(unsigned long int prec) { mpf_set_prec(mp, prec); }
2708: void set_prec_raw(unsigned long int prec) { mpf_set_prec_raw(mp, prec); }
2709:
2710: // constructors and destructor
2711: __gmp_expr() { mpf_init(mp); }
2712:
2713: __gmp_expr(const __gmp_expr &f)
2714: { mpf_init2(mp, f.get_prec()); mpf_set(mp, f.mp); }
2715: __gmp_expr(const __gmp_expr &f, unsigned long int prec)
2716: { mpf_init2(mp, prec); mpf_set(mp, f.mp); }
2717: template <class T, class U>
2718: __gmp_expr(const __gmp_expr<T, U> &expr)
2719: { mpf_init2(mp, expr.get_prec()); __gmp_set_expr(mp, expr); }
2720: template <class T, class U>
2721: __gmp_expr(const __gmp_expr<T, U> &expr, unsigned long int prec)
2722: { mpf_init2(mp, prec); __gmp_set_expr(mp, expr); }
2723:
2724: __gmp_expr(signed char c) { mpf_init_set_si(mp, c); }
2725: __gmp_expr(signed char c, unsigned long int prec)
2726: { mpf_init2(mp, prec); mpf_set_si(mp, c); }
2727: __gmp_expr(unsigned char c) { mpf_init_set_ui(mp, c); }
2728: __gmp_expr(unsigned char c, unsigned long int prec)
2729: { mpf_init2(mp, prec); mpf_set_ui(mp, c); }
2730:
2731: __gmp_expr(signed int i) { mpf_init_set_si(mp, i); }
2732: __gmp_expr(signed int i, unsigned long int prec)
2733: { mpf_init2(mp, prec); mpf_set_si(mp, i); }
2734: __gmp_expr(unsigned int i) { mpf_init_set_ui(mp, i); }
2735: __gmp_expr(unsigned int i, unsigned long int prec)
2736: { mpf_init2(mp, prec); mpf_set_ui(mp, i); }
2737:
2738: __gmp_expr(signed short int s) { mpf_init_set_si(mp, s); }
2739: __gmp_expr(signed short int s, unsigned long int prec)
2740: { mpf_init2(mp, prec); mpf_set_si(mp, s); }
2741: __gmp_expr(unsigned short int s) { mpf_init_set_ui(mp, s); }
2742: __gmp_expr(unsigned short int s, unsigned long int prec)
2743: { mpf_init2(mp, prec); mpf_set_ui(mp, s); }
2744:
2745: __gmp_expr(signed long int l) { mpf_init_set_si(mp, l); }
2746: __gmp_expr(signed long int l, unsigned long int prec)
2747: { mpf_init2(mp, prec); mpf_set_si(mp, l); }
2748: __gmp_expr(unsigned long int l) { mpf_init_set_ui(mp, l); }
2749: __gmp_expr(unsigned long int l, unsigned long int prec)
2750: { mpf_init2(mp, prec); mpf_set_ui(mp, l); }
2751:
2752: __gmp_expr(float f) { mpf_init_set_d(mp, f); }
2753: __gmp_expr(float f, unsigned long int prec)
2754: { mpf_init2(mp, prec); mpf_set_d(mp, f); }
2755: __gmp_expr(double d) { mpf_init_set_d(mp, d); }
2756: __gmp_expr(double d, unsigned long int prec)
2757: { mpf_init2(mp, prec); mpf_set_d(mp, d); }
2758: /*
2759: __gmp_expr(long double ld) { mpf_init_set_d(mp, ld); }
2760: __gmp_expr(long double ld, unsigned long int prec)
2761: { mpf_init2(mp, prec); mpf_set_d(mp, ld); }
2762: */
2763:
2764: explicit __gmp_expr(const char *s) { mpf_init_set_str(mp, s, 0); }
2765: __gmp_expr(const char *s, unsigned long int prec)
2766: { mpf_init2(mp, prec); mpf_set_str(mp, s, 0); }
2767: explicit __gmp_expr(const std::string &s)
2768: { mpf_init_set_str(mp, s.c_str(), 0); }
2769: __gmp_expr(const std::string &s, unsigned long int prec)
2770: { mpf_init2(mp, prec); mpf_set_str(mp, s.c_str(), 0); }
2771:
2772: explicit __gmp_expr(mpf_srcptr f)
2773: { mpf_init2(mp, mpf_get_prec(f)); mpf_set(mp, f); }
2774: __gmp_expr(mpf_srcptr f, unsigned long int prec)
2775: { mpf_init2(mp, prec); mpf_set(mp, f); }
2776:
2777: ~__gmp_expr() { mpf_clear(mp); }
2778:
2779: // assignment operators
2780: __gmp_expr & operator=(const __gmp_expr &f)
2781: { mpf_set(mp, f.mp); return *this; }
2782: template <class T, class U>
2783: __gmp_expr<__gmpf_value, __gmpf_value> & operator=
2784: (const __gmp_expr<T, U> &expr)
2785: { __gmp_set_expr(mp, expr); return *this; }
2786:
2787: __gmp_expr & operator=(signed char c) { mpf_set_si(mp, c); return *this; }
2788: __gmp_expr & operator=(unsigned char c) { mpf_set_ui(mp, c); return *this; }
2789:
2790: __gmp_expr & operator=(signed int i) { mpf_set_si(mp, i); return *this; }
2791: __gmp_expr & operator=(unsigned int i) { mpf_set_ui(mp, i); return *this; }
2792:
2793: __gmp_expr & operator=(signed short int s)
2794: { mpf_set_si(mp, s); return *this; }
2795: __gmp_expr & operator=(unsigned short int s)
2796: { mpf_set_ui(mp, s); return *this; }
2797:
2798: __gmp_expr & operator=(signed long int l)
2799: { mpf_set_si(mp, l); return *this; }
2800: __gmp_expr & operator=(unsigned long int l)
2801: { mpf_set_ui(mp, l); return *this; }
2802:
2803: __gmp_expr & operator=(float f) { mpf_set_d(mp, f); return *this; }
2804: __gmp_expr & operator=(double d) { mpf_set_d(mp, d); return *this; }
2805: /*
2806: __gmp_expr & operator=(long double ld) { mpf_set_ld(mp, ld); return *this; }
2807: */
2808:
2809: __gmp_expr & operator=(const char *s)
2810: { mpf_set_str(mp, s, 0); return *this; }
2811: __gmp_expr & operator=(const std::string &s)
2812: { mpf_set_str(mp, s.c_str(), 0); return *this; }
2813:
2814: // string input/output functions
2815: int set_str(const std::string &s, int base)
2816: { return mpf_set_str(mp, s.c_str(), base); }
2817: std::string get_str(mp_exp_t *expo, int base, size_t size) const
2818: {
2819: __gmp_alloc_cstring temp(mpf_get_str(0, expo, base, size, mp));
2820: return std::string(temp.str);
2821: }
2822:
2823: // conversion functions
2824: mpf_srcptr get_mpf_t() const { return mp; }
2825: mpf_ptr get_mpf_t() { return mp; }
2826:
2827: signed long int get_si() const { return mpf_get_si(mp); }
2828: unsigned long int get_ui() const { return mpf_get_ui(mp); }
2829: double get_d() const { return mpf_get_d(mp); } // should be long double
2830:
2831: // bool fits_schar_p() const { return mpf_fits_schar_p(mp); }
2832: // bool fits_uchar_p() const { return mpf_fits_uchar_p(mp); }
2833: bool fits_sint_p() const { return mpf_fits_sint_p(mp); }
2834: bool fits_uint_p() const { return mpf_fits_uint_p(mp); }
2835: bool fits_sshort_p() const { return mpf_fits_sshort_p(mp); }
2836: bool fits_ushort_p() const { return mpf_fits_ushort_p(mp); }
2837: bool fits_slong_p() const { return mpf_fits_slong_p(mp); }
2838: bool fits_ulong_p() const { return mpf_fits_ulong_p(mp); }
2839: // bool fits_float_p() const { return mpf_fits_float_p(mp); }
2840: // bool fits_double_p() const { return mpf_fits_double_p(mp); }
2841: // bool fits_ldouble_p() const { return mpf_fits_ldouble_p(mp); }
2842:
2843: // compound assignments
2844: __GMPF_DECLARE_COMPOUND_OPERATOR(operator+=)
2845: __GMPF_DECLARE_COMPOUND_OPERATOR(operator-=)
2846: __GMPF_DECLARE_COMPOUND_OPERATOR(operator*=)
2847: __GMPF_DECLARE_COMPOUND_OPERATOR(operator/=)
2848:
2849: __GMPF_DECLARE_COMPOUND_OPERATOR_UI(operator<<=)
2850: __GMPF_DECLARE_COMPOUND_OPERATOR_UI(operator>>=)
2851:
2852: __GMPF_DECLARE_INCREMENT_OPERATOR(operator++)
2853: __GMPF_DECLARE_INCREMENT_OPERATOR(operator--)
2854: };
2855:
2856: typedef __gmp_expr<__gmpf_value, __gmpf_value> mpf_class;
2857:
2858:
2859: inline std::ostream & operator<<(std::ostream &o, const mpf_class &f)
2860: {
2861: return o << f.get_mpf_t();
2862: }
2863:
2864: template <class T>
2865: inline std::ostream & operator<<
2866: (std::ostream &o, const __gmp_expr<__gmpf_value, T> &expr)
2867: {
2868: mpf_class temp(expr);
2869: return o << temp.get_mpf_t();
2870: }
2871:
2872: inline std::istream & operator>>(std::istream &i, mpf_class &f)
2873: {
2874: return i >> f.get_mpf_t();
2875: }
2876:
2877:
2878: /**************** Classes for type conversion ****************/
2879: /* If the expression to be converted is a plain mp[zqf]_class, a direct
2880: reference to its mp[zqf]_t internal yields optimal efficiency.
2881: If it's a compound expression, a temporary must be used */
2882:
2883: class __gmpz_temp
2884: {
2885: private:
2886: mpz_srcptr mp;
2887: bool is_temp;
2888: mpz_t temp;
2889:
2890: __gmpz_temp();
2891: __gmpz_temp(const __gmpz_temp &);
2892: void operator=(const __gmpz_temp &);
2893: public:
2894: __gmpz_temp(const mpz_class &z) : mp(z.get_mpz_t()), is_temp(false) { }
2895: __gmpz_temp(const mpz_classref &z) : mp(z.get_mpz_t()), is_temp(false) { }
2896: template <class T, class U>
2897: __gmpz_temp(const __gmp_expr<T, U> &expr)
2898: {
2899: mpz_init(temp);
2900: __gmp_set_expr(temp, expr);
2901: mp = temp;
2902: is_temp = true;
2903: }
2904: ~__gmpz_temp() { if (is_temp) mpz_clear(temp); }
2905:
2906: mpz_srcptr get_mp() const { return mp; }
2907: };
2908:
2909: class __gmpq_temp
2910: {
2911: private:
2912: mpq_srcptr mp;
2913: bool is_temp;
2914: mpq_t temp;
2915:
2916: __gmpq_temp();
2917: __gmpq_temp(const __gmpq_temp &);
2918: void operator=(const __gmpq_temp &);
2919: public:
2920: __gmpq_temp(const mpq_class &q) : mp(q.get_mpq_t()), is_temp(false) { }
2921: template <class T, class U>
2922: __gmpq_temp(const __gmp_expr<T, U> &expr)
2923: {
2924: mpq_init(temp);
2925: __gmp_set_expr(temp, expr);
2926: mp = temp;
2927: is_temp = true;
2928: }
2929: ~__gmpq_temp() { if (is_temp) mpq_clear(temp); }
2930:
2931: mpq_srcptr get_mp() const { return mp; }
2932: };
2933:
2934: class __gmpf_temp
2935: {
2936: private:
2937: mpf_srcptr mp;
2938: bool is_temp;
2939: mpf_t temp;
2940:
2941: __gmpf_temp();
2942: __gmpf_temp(const __gmpf_temp &);
2943: void operator=(const __gmpf_temp &);
2944: public:
2945: __gmpf_temp(const mpf_class &f) : mp(f.get_mpf_t()), is_temp(false) { }
2946: __gmpf_temp(const mpf_class &f, unsigned long int)
2947: : mp(f.get_mpf_t()), is_temp(false) { }
2948: template <class T, class U>
2949: __gmpf_temp(const __gmp_expr<T, U> &expr)
2950: {
2951: mpf_init2(temp, expr.get_prec());
2952: __gmp_set_expr(temp, expr);
2953: mp = temp;
2954: is_temp = true;
2955: }
2956: template <class T, class U>
2957: __gmpf_temp(const __gmp_expr<T, U> &expr, unsigned long int prec)
2958: {
2959: mpf_init2(temp, prec);
2960: __gmp_set_expr(temp, expr);
2961: mp = temp;
2962: is_temp = true;
2963: }
2964: ~__gmpf_temp() { if (is_temp) mpf_clear(temp); }
2965:
2966: mpf_srcptr get_mp() const { return mp; }
2967: };
2968:
2969:
2970: // this function must be defined after __gmpz_temp
2971: template <class T, class U>
2972: inline mpq_class::__gmp_expr(const __gmp_expr<__gmpz_value, T> &num,
2973: const __gmp_expr<__gmpz_value, U> &den)
2974: {
2975: __gmpz_temp temp1(num), temp2(den);
2976: mpq_init(mp);
2977: mpz_set(mpq_numref(mp), temp1.get_mp());
2978: mpz_set(mpq_denref(mp), temp2.get_mp());
2979: }
2980:
2981:
2982: // type of mixed-type expressions
2983: template <class T, class U>
2984: struct __gmp_resolve_expr;
2985:
2986: template <>
2987: struct __gmp_resolve_expr<__gmpz_value, __gmpz_value>
2988: {
2989: typedef __gmpz_value value_type;
2990: typedef __gmpz_temp temp_type;
2991: };
2992:
2993: template <>
2994: struct __gmp_resolve_expr<__gmpq_value, __gmpq_value>
2995: {
2996: typedef __gmpq_value value_type;
2997: typedef __gmpq_temp temp_type;
2998: };
2999:
3000: template <>
3001: struct __gmp_resolve_expr<__gmpz_value, __gmpq_value>
3002: {
3003: typedef __gmpq_value value_type;
3004: typedef __gmpq_temp temp_type;
3005: };
3006:
3007: template <>
3008: struct __gmp_resolve_expr<__gmpq_value, __gmpz_value>
3009: {
3010: typedef __gmpq_value value_type;
3011: typedef __gmpq_temp temp_type;
3012: };
3013:
3014: template <>
3015: struct __gmp_resolve_expr<__gmpf_value, __gmpf_value>
3016: {
3017: typedef __gmpf_value value_type;
3018: typedef __gmpf_temp temp_type;
3019: };
3020:
3021: template <>
3022: struct __gmp_resolve_expr<__gmpz_value, __gmpf_value>
3023: {
3024: typedef __gmpf_value value_type;
3025: typedef __gmpf_temp temp_type;
3026: };
3027:
3028: template <>
3029: struct __gmp_resolve_expr<__gmpf_value, __gmpz_value>
3030: {
3031: typedef __gmpf_value value_type;
3032: typedef __gmpf_temp temp_type;
3033: };
3034:
3035: template <>
3036: struct __gmp_resolve_expr<__gmpq_value, __gmpf_value>
3037: {
3038: typedef __gmpf_value value_type;
3039: typedef __gmpf_temp temp_type;
3040: };
3041:
3042: template <>
3043: struct __gmp_resolve_expr<__gmpf_value, __gmpq_value>
3044: {
3045: typedef __gmpf_value value_type;
3046: typedef __gmpf_temp temp_type;
3047: };
3048:
3049:
3050: // perform type conversions
3051:
3052: template <>
3053: inline void __gmp_set_expr(mpz_ptr z, const mpz_class &w)
3054: {
3055: mpz_set(z, w.get_mpz_t());
3056: }
3057:
3058: template <class T>
3059: inline void __gmp_set_expr(mpz_ptr z, const __gmp_expr<__gmpz_value, T> &expr)
3060: {
3061: expr.eval(z);
3062: }
3063:
3064: template <>
3065: inline void __gmp_set_expr(mpz_ptr z, const mpz_classref &w)
3066: {
3067: mpz_set(z, w.get_mpz_t());
3068: }
3069:
3070: template <>
3071: inline void __gmp_set_expr(mpz_ptr z, const mpq_class &q)
3072: {
3073: mpz_set_q(z, q.get_mpq_t());
3074: }
3075:
3076: template <class T>
3077: inline void __gmp_set_expr(mpz_ptr z, const __gmp_expr<__gmpq_value, T> &expr)
3078: {
3079: mpq_class temp(expr);
3080: mpz_set_q(z, temp.get_mpq_t());
3081: }
3082:
3083: template <class T>
3084: inline void __gmp_set_expr(mpz_ptr z, const mpf_class &f)
3085: {
3086: mpz_set_f(z, f.get_mpf_t());
3087: }
3088:
3089: template <class T>
3090: inline void __gmp_set_expr(mpz_ptr z, const __gmp_expr<__gmpf_value, T> &expr)
3091: {
3092: mpf_class temp(expr);
3093: mpz_set_f(z, temp.get_mpf_t());
3094: }
3095:
3096: template <>
3097: inline void __gmp_set_expr(mpq_ptr q, const mpz_class &z)
3098: {
3099: mpq_set_z(q, z.get_mpz_t());
3100: }
3101:
3102: template <class T>
3103: inline void __gmp_set_expr(mpq_ptr q, const __gmp_expr<__gmpz_value, T> &expr)
3104: {
3105: mpz_class temp(expr);
3106: mpq_set_z(q, temp.get_mpz_t());
3107: }
3108:
3109: template <>
3110: inline void __gmp_set_expr(mpq_ptr q, const mpz_classref &z)
3111: {
3112: mpq_set_z(q, z.get_mpz_t());
3113: }
3114:
3115: template <>
3116: inline void __gmp_set_expr(mpq_ptr q, const mpq_class &r)
3117: {
3118: mpq_set(q, r.get_mpq_t());
3119: }
3120:
3121: template <class T>
3122: inline void __gmp_set_expr(mpq_ptr q, const __gmp_expr<__gmpq_value, T> &expr)
3123: {
3124: expr.eval(q);
3125: }
3126:
3127: template <class T>
3128: inline void __gmp_set_expr(mpq_ptr q, const mpf_class &f)
3129: {
3130: mpq_set_f(q, f.get_mpf_t());
3131: }
3132:
3133: template <class T>
3134: inline void __gmp_set_expr(mpq_ptr q, const __gmp_expr<__gmpf_value, T> &expr)
3135: {
3136: mpf_class temp(expr);
3137: mpq_set_f(q, temp.get_mpf_t());
3138: }
3139:
3140: template <class T>
3141: inline void __gmp_set_expr(mpf_ptr f, const mpz_class &z)
3142: {
3143: mpf_set_z(f, z.get_mpz_t());
3144: }
3145:
3146: template <class T>
3147: inline void __gmp_set_expr(mpf_ptr f, const __gmp_expr<__gmpz_value, T> &expr)
3148: {
3149: mpz_class temp(expr);
3150: mpf_set_z(f, temp.get_mpz_t());
3151: }
3152:
3153: template <class T>
3154: inline void __gmp_set_expr(mpf_ptr f, const mpz_classref &z)
3155: {
3156: mpf_set_z(f, z.get_mpz_t());
3157: }
3158:
3159: template <class T>
3160: inline void __gmp_set_expr(mpf_ptr f, const mpq_class &q)
3161: {
3162: mpf_set_q(f, q.get_mpq_t());
3163: }
3164:
3165: template <class T>
3166: inline void __gmp_set_expr(mpf_ptr f, const __gmp_expr<__gmpq_value, T> &expr)
3167: {
3168: mpq_class temp(expr);
3169: mpf_set_q(f, temp.get_mpq_t());
3170: }
3171:
3172: template <>
3173: inline void __gmp_set_expr(mpf_ptr f, const mpf_class &g)
3174: {
3175: mpf_set(f, g.get_mpf_t());
3176: }
3177:
3178: template <class T>
3179: inline void __gmp_set_expr(mpf_ptr f, const __gmp_expr<__gmpf_value, T> &expr)
3180: {
3181: expr.eval(f, mpf_get_prec(f));
3182: }
3183:
3184:
3185: /**************** Specializations of __gmp_expr ****************/
3186: /* The eval() method of __gmp_expr<T, U> evaluates the corresponding
3187: expression assigning the result to its argument, which is either an
3188: mpz_t, mpq_t, or mpf_t -- this depends on the T argument, which is
3189: either __gmpz_value, __gmpq_value, or __gmpf_value, respectively.
3190: Compound expressions are evaluated recursively (temporaries are created
3191: to hold intermediate values), while for simple expressions the eval()
3192: method of the appropriate function object (available as the Op argument
3193: of either __gmp_unary_expr<T, Op> or __gmp_binary_expr<T, U, Op>) is
3194: called. */
3195:
3196: /**************** Unary expressions ****************/
3197: /* cases:
3198: - simple: argument is mp[zqf]_class, or mpz_classref
3199: - compound: argument is __gmp_expr<...> */
3200:
3201:
3202: // simple expressions
3203:
3204: template <class Op>
3205: class __gmp_expr<__gmpz_value, __gmp_unary_expr<mpz_class, Op> >
3206: {
3207: private:
3208: __gmp_unary_expr<mpz_class, Op> expr;
3209: public:
3210: __gmp_expr(const mpz_class &val) : expr(val) { }
3211: void eval(mpz_ptr z) const { Op::eval(z, expr.val.get_mpz_t()); }
3212: unsigned long int get_prec() const { return mpf_get_default_prec(); }
3213: };
3214:
3215: template <class Op>
3216: class __gmp_expr<__gmpz_value, __gmp_unary_expr<mpz_classref, Op> >
3217: {
3218: private:
3219: __gmp_unary_expr<mpz_classref, Op> expr;
3220: public:
3221: __gmp_expr(const mpz_classref &val) : expr(val) { }
3222: void eval(mpz_ptr z) const { Op::eval(z, expr.val.get_mpz_t()); }
3223: unsigned long int get_prec() const { return mpf_get_default_prec(); }
3224: };
3225:
3226: template <class Op>
3227: class __gmp_expr<__gmpq_value, __gmp_unary_expr<mpq_class, Op> >
3228: {
3229: private:
3230: __gmp_unary_expr<mpq_class, Op> expr;
3231: public:
3232: __gmp_expr(const mpq_class &val) : expr(val) { }
3233: void eval(mpq_ptr q) const { Op::eval(q, expr.val.get_mpq_t()); }
3234: unsigned long int get_prec() const { return mpf_get_default_prec(); }
3235: };
3236:
3237: template <class Op>
3238: class __gmp_expr<__gmpf_value, __gmp_unary_expr<mpf_class, Op> >
3239: {
3240: private:
3241: __gmp_unary_expr<mpf_class, Op> expr;
3242: public:
3243: __gmp_expr(const mpf_class &val) : expr(val) { }
3244: void eval(mpf_ptr f, unsigned long int) const
3245: { Op::eval(f, expr.val.get_mpf_t()); }
3246: unsigned long int get_prec() const
3247: { return mpf_get_prec(expr.val.get_mpf_t()); }
3248: };
3249:
3250:
3251: // compound expressions
3252:
3253: template <class T, class U, class Op>
3254: class __gmp_expr<__gmpz_value, __gmp_unary_expr<__gmp_expr<T, U>, Op> >
3255: {
3256: private:
3257: __gmp_unary_expr<__gmp_expr<T, U>, Op> expr;
3258: public:
3259: __gmp_expr(const __gmp_expr<T, U> &val) : expr(val) { }
3260: void eval(mpz_ptr z) const
3261: {
3262: mpz_class temp(expr.val);
3263: Op::eval(z, temp.get_mpz_t());
3264: }
3265: unsigned long int get_prec() const { return mpf_get_default_prec(); }
3266: };
3267:
3268: template <class T, class U, class Op>
3269: class __gmp_expr<__gmpq_value, __gmp_unary_expr<__gmp_expr<T, U>, Op> >
3270: {
3271: private:
3272: __gmp_unary_expr<__gmp_expr<T, U>, Op> expr;
3273: public:
3274: __gmp_expr(const __gmp_expr<T, U> &val) : expr(val) { }
3275: void eval(mpq_ptr q) const
3276: {
3277: mpq_class temp(expr.val);
3278: Op::eval(q, temp.get_mpq_t());
3279: }
3280: unsigned long int get_prec() const { return mpf_get_default_prec(); }
3281: };
3282:
3283: template <class T, class U, class Op>
3284: class __gmp_expr<__gmpf_value, __gmp_unary_expr<__gmp_expr<T, U>, Op> >
3285: {
3286: private:
3287: __gmp_unary_expr<__gmp_expr<T, U>, Op> expr;
3288: public:
3289: __gmp_expr(const __gmp_expr<T, U> &val) : expr(val) { }
3290: void eval(mpf_ptr f, unsigned long int prec) const
3291: {
3292: mpf_class temp(expr.val, prec);
3293: Op::eval(f, temp.get_mpf_t());
3294: }
3295: unsigned long int get_prec() const { return expr.val.get_prec(); }
3296: };
3297:
3298:
3299: /**************** Binary expressions ****************/
3300: /* simple:
3301: - arguments are both mp[zqf]_class, or mpz_classref
3302: - one argument is mp[zqf]_class(ref), one is a built-in type
3303: compound:
3304: - one is mp[zqf]_class(ref), one is __gmp_expr<...>
3305: - one is __gmp_expr<...>, one is built-in
3306: - both arguments are __gmp_expr<...> */
3307:
3308:
3309: // simple expressions
3310:
3311: template <class Op>
3312: class __gmp_expr<__gmpz_value, __gmp_binary_expr<mpz_class, mpz_class, Op> >
3313: {
3314: private:
3315: __gmp_binary_expr<mpz_class, mpz_class, Op> expr;
3316: public:
3317: __gmp_expr(const mpz_class &val1, const mpz_class &val2)
3318: : expr(val1, val2) { }
3319: void eval(mpz_ptr z) const
3320: { Op::eval(z, expr.val1.get_mpz_t(), expr.val2.get_mpz_t()); }
3321: unsigned long int get_prec() const { return mpf_get_default_prec(); }
3322: };
3323:
3324: template <class Op>
3325: class __gmp_expr
3326: <__gmpz_value, __gmp_binary_expr<mpz_class, mpz_classref, Op> >
3327: {
3328: private:
3329: __gmp_binary_expr<mpz_class, mpz_classref, Op> expr;
3330: public:
3331: __gmp_expr(const mpz_class &val1, const mpz_classref &val2)
3332: : expr(val1, val2) { }
3333: void eval(mpz_ptr z) const
3334: { Op::eval(z, expr.val1.get_mpz_t(), expr.val2.get_mpz_t()); }
3335: unsigned long int get_prec() const { return mpf_get_default_prec(); }
3336: };
3337:
3338: template <class Op>
3339: class __gmp_expr
3340: <__gmpz_value, __gmp_binary_expr<mpz_classref, mpz_class, Op> >
3341: {
3342: private:
3343: __gmp_binary_expr<mpz_classref, mpz_class, Op> expr;
3344: public:
3345: __gmp_expr(const mpz_classref &val1, const mpz_class &val2)
3346: : expr(val1, val2) { }
3347: void eval(mpz_ptr z) const
3348: { Op::eval(z, expr.val1.get_mpz_t(), expr.val2.get_mpz_t()); }
3349: unsigned long int get_prec() const { return mpf_get_default_prec(); }
3350: };
3351:
3352: template <class Op>
3353: class __gmp_expr
3354: <__gmpz_value, __gmp_binary_expr<mpz_classref, mpz_classref, Op> >
3355: {
3356: private:
3357: __gmp_binary_expr<mpz_classref, mpz_classref, Op> expr;
3358: public:
3359: __gmp_expr(const mpz_classref &val1, const mpz_classref &val2)
3360: : expr(val1, val2) { }
3361: void eval(mpz_ptr z) const
3362: { Op::eval(z, expr.val1.get_mpz_t(), expr.val2.get_mpz_t()); }
3363: unsigned long int get_prec() const { return mpf_get_default_prec(); }
3364: };
3365:
3366: template <class Op>
3367: class __gmp_expr<__gmpq_value, __gmp_binary_expr<mpq_class, mpq_class, Op> >
3368: {
3369: private:
3370: __gmp_binary_expr<mpq_class, mpq_class, Op> expr;
3371: public:
3372: __gmp_expr(const mpq_class &val1, const mpq_class &val2)
3373: : expr(val1, val2) { }
3374: void eval(mpq_ptr q) const
3375: { Op::eval(q, expr.val1.get_mpq_t(), expr.val2.get_mpq_t()); }
3376: unsigned long int get_prec() const { return mpf_get_default_prec(); }
3377: };
3378:
3379: template <class Op>
3380: class __gmp_expr<__gmpf_value, __gmp_binary_expr<mpf_class, mpf_class, Op> >
3381: {
3382: private:
3383: __gmp_binary_expr<mpf_class, mpf_class, Op> expr;
3384: public:
3385: __gmp_expr(const mpf_class &val1, const mpf_class &val2)
3386: : expr(val1, val2) { }
3387: void eval(mpf_ptr f, unsigned long int) const
3388: { Op::eval(f, expr.val1.get_mpf_t(), expr.val2.get_mpf_t()); }
3389: unsigned long int get_prec() const
3390: {
3391: unsigned long int prec1 = expr.val1.get_prec(),
3392: prec2 = expr.val2.get_prec();
3393: return (prec1 > prec2) ? prec1 : prec2;
3394: }
3395: };
3396:
3397:
3398: // simple expressions, T is a built-in numerical type
3399:
3400: template <class T, class Op>
3401: class __gmp_expr<__gmpz_value, __gmp_binary_expr<mpz_class, T, Op> >
3402: {
3403: private:
3404: __gmp_binary_expr<mpz_class, T, Op> expr;
3405: public:
3406: __gmp_expr(const mpz_class &val1, T val2) : expr(val1, val2) { }
3407: void eval(mpz_ptr z) const
3408: { Op::eval(z, expr.val1.get_mpz_t(), expr.val2); }
3409: unsigned long int get_prec() const { return mpf_get_default_prec(); }
3410: };
3411:
3412: template <class T, class Op>
3413: class __gmp_expr<__gmpz_value, __gmp_binary_expr<T, mpz_class, Op> >
3414: {
3415: private:
3416: __gmp_binary_expr<T, mpz_class, Op> expr;
3417: public:
3418: __gmp_expr(T val1, const mpz_class &val2) : expr(val1, val2) { }
3419: void eval(mpz_ptr z) const
3420: { Op::eval(z, expr.val1, expr.val2.get_mpz_t()); }
3421: unsigned long int get_prec() const { return mpf_get_default_prec(); }
3422: };
3423:
3424: template <class T, class Op>
3425: class __gmp_expr<__gmpz_value, __gmp_binary_expr<mpz_classref, T, Op> >
3426: {
3427: private:
3428: __gmp_binary_expr<mpz_classref, T, Op> expr;
3429: public:
3430: __gmp_expr(const mpz_classref &val1, T val2) : expr(val1, val2) { }
3431: void eval(mpz_ptr z) const
3432: { Op::eval(z, expr.val1.get_mpz_t(), expr.val2); }
3433: unsigned long int get_prec() const { return mpf_get_default_prec(); }
3434: };
3435:
3436: template <class T, class Op>
3437: class __gmp_expr<__gmpz_value, __gmp_binary_expr<T, mpz_classref, Op> >
3438: {
3439: private:
3440: __gmp_binary_expr<T, mpz_classref, Op> expr;
3441: public:
3442: __gmp_expr(T val1, const mpz_classref &val2) : expr(val1, val2) { }
3443: void eval(mpz_ptr z) const
3444: { Op::eval(z, expr.val1, expr.val2.get_mpz_t()); }
3445: unsigned long int get_prec() const { return mpf_get_default_prec(); }
3446: };
3447:
3448: template <class T, class Op>
3449: class __gmp_expr<__gmpq_value, __gmp_binary_expr<mpq_class, T, Op> >
3450: {
3451: private:
3452: __gmp_binary_expr<mpq_class, T, Op> expr;
3453: public:
3454: __gmp_expr(const mpq_class &val1, T val2) : expr(val1, val2) { }
3455: void eval(mpq_ptr q) const
3456: { Op::eval(q, expr.val1.get_mpq_t(), expr.val2); }
3457: unsigned long int get_prec() const { return mpf_get_default_prec(); }
3458: };
3459:
3460: template <class T, class Op>
3461: class __gmp_expr<__gmpq_value, __gmp_binary_expr<T, mpq_class, Op> >
3462: {
3463: private:
3464: __gmp_binary_expr<T, mpq_class, Op> expr;
3465: public:
3466: __gmp_expr(T val1, const mpq_class &val2) : expr(val1, val2) { }
3467: void eval(mpq_ptr q) const
3468: { Op::eval(q, expr.val1, expr.val2.get_mpq_t()); }
3469: unsigned long int get_prec() const { return mpf_get_default_prec(); }
3470: };
3471:
3472: template <class T, class Op>
3473: class __gmp_expr<__gmpf_value, __gmp_binary_expr<mpf_class, T, Op> >
3474: {
3475: private:
3476: __gmp_binary_expr<mpf_class, T, Op> expr;
3477: public:
3478: __gmp_expr(const mpf_class &val1, T val2) : expr(val1, val2) { }
3479: void eval(mpf_ptr f, unsigned long int) const
3480: { Op::eval(f, expr.val1.get_mpf_t(), expr.val2); }
3481: unsigned long int get_prec() const
3482: {
3483: unsigned long int prec1 = expr.val1.get_prec(),
3484: prec2 = mpf_get_default_prec();
3485: return (prec1 > prec2) ? prec1 : prec2;
3486: }
3487: };
3488:
3489: template <class T, class Op>
3490: class __gmp_expr<__gmpf_value, __gmp_binary_expr<T, mpf_class, Op> >
3491: {
3492: private:
3493: __gmp_binary_expr<T, mpf_class, Op> expr;
3494: public:
3495: __gmp_expr(T val1, const mpf_class &val2) : expr(val1, val2) { }
3496: void eval(mpf_ptr f, unsigned long int) const
3497: { Op::eval(f, expr.val1, expr.val2.get_mpf_t()); }
3498: unsigned long int get_prec() const
3499: {
3500: unsigned long int prec1 = mpf_get_default_prec(),
3501: prec2 = expr.val2.get_prec();
3502: return (prec1 > prec2) ? prec1 : prec2;
3503: }
3504: };
3505:
3506:
3507: // compound expressions, one argument is a subexpression
3508:
3509: template <class T, class U, class Op>
3510: class __gmp_expr
3511: <__gmpz_value, __gmp_binary_expr<mpz_class, __gmp_expr<T, U>, Op> >
3512: {
3513: private:
3514: __gmp_binary_expr<mpz_class, __gmp_expr<T, U>, Op> expr;
3515: public:
3516: __gmp_expr(const mpz_class &val1, const __gmp_expr<T, U> &val2)
3517: : expr(val1, val2) { }
3518: void eval(mpz_ptr z) const
3519: {
3520: mpz_class temp(expr.val2);
3521: Op::eval(z, expr.val1.get_mpz_t(), temp.get_mpz_t());
3522: }
3523: unsigned long int get_prec() const { return mpf_get_default_prec(); }
3524: };
3525:
3526: template <class T, class U, class Op>
3527: class __gmp_expr
3528: <__gmpz_value, __gmp_binary_expr<__gmp_expr<T, U>, mpz_class, Op> >
3529: {
3530: private:
3531: __gmp_binary_expr<__gmp_expr<T, U>, mpz_class, Op> expr;
3532: public:
3533: __gmp_expr(const __gmp_expr<T, U> &val1, const mpz_class &val2)
3534: : expr(val1, val2) { }
3535: void eval(mpz_ptr z) const
3536: {
3537: mpz_class temp(expr.val1);
3538: Op::eval(z, temp.get_mpz_t(), expr.val2.get_mpz_t());
3539: }
3540: unsigned long int get_prec() const { return mpf_get_default_prec(); }
3541: };
3542:
3543: template <class T, class U, class Op>
3544: class __gmp_expr
3545: <__gmpz_value, __gmp_binary_expr<mpz_classref, __gmp_expr<T, U>, Op> >
3546: {
3547: private:
3548: __gmp_binary_expr<mpz_classref, __gmp_expr<T, U>, Op> expr;
3549: public:
3550: __gmp_expr(const mpz_classref &val1, const __gmp_expr<T, U> &val2)
3551: : expr(val1, val2) { }
3552: void eval(mpz_ptr z) const
3553: {
3554: mpz_class temp(expr.val2);
3555: Op::eval(z, expr.val1.get_mpz_t(), temp.get_mpz_t());
3556: }
3557: unsigned long int get_prec() const { return mpf_get_default_prec(); }
3558: };
3559:
3560: template <class T, class U, class Op>
3561: class __gmp_expr
3562: <__gmpz_value, __gmp_binary_expr<__gmp_expr<T, U>, mpz_classref, Op> >
3563: {
3564: private:
3565: __gmp_binary_expr<__gmp_expr<T, U>, mpz_classref, Op> expr;
3566: public:
3567: __gmp_expr(const __gmp_expr<T, U> &val1, const mpz_classref &val2)
3568: : expr(val1, val2) { }
3569: void eval(mpz_ptr z) const
3570: {
3571: mpz_class temp(expr.val1);
3572: Op::eval(z, temp.get_mpz_t(), expr.val2.get_mpz_t());
3573: }
3574: unsigned long int get_prec() const { return mpf_get_default_prec(); }
3575: };
3576:
3577: template <class T, class U, class Op>
3578: class __gmp_expr
3579: <__gmpq_value, __gmp_binary_expr<mpq_class, __gmp_expr<T, U>, Op> >
3580: {
3581: private:
3582: __gmp_binary_expr<mpq_class, __gmp_expr<T, U>, Op> expr;
3583: public:
3584: __gmp_expr(const mpq_class &val1, const __gmp_expr<T, U> &val2)
3585: : expr(val1, val2) { }
3586: void eval(mpq_ptr q) const
3587: {
3588: mpq_class temp(expr.val2);
3589: Op::eval(q, expr.val1.get_mpq_t(), temp.get_mpq_t());
3590: }
3591: unsigned long int get_prec() const { return mpf_get_default_prec(); }
3592: };
3593:
3594: template <class T, class U, class Op>
3595: class __gmp_expr
3596: <__gmpq_value, __gmp_binary_expr<__gmp_expr<T, U>, mpq_class, Op> >
3597: {
3598: private:
3599: __gmp_binary_expr<__gmp_expr<T, U>, mpq_class, Op> expr;
3600: public:
3601: __gmp_expr(const __gmp_expr<T, U> &val1, const mpq_class &val2)
3602: : expr(val1, val2) { }
3603: void eval(mpq_ptr q) const
3604: {
3605: mpq_class temp(expr.val1);
3606: Op::eval(q, temp.get_mpq_t(), expr.val2.get_mpq_t());
3607: }
3608: unsigned long int get_prec() const { return mpf_get_default_prec(); }
3609: };
3610:
3611: template <class T, class U, class Op>
3612: class __gmp_expr
3613: <__gmpf_value, __gmp_binary_expr<mpf_class, __gmp_expr<T, U>, Op> >
3614: {
3615: private:
3616: __gmp_binary_expr<mpf_class, __gmp_expr<T, U>, Op> expr;
3617: public:
3618: __gmp_expr(const mpf_class &val1, const __gmp_expr<T, U> &val2)
3619: : expr(val1, val2) { }
3620: void eval(mpf_ptr f, unsigned long int prec) const
3621: {
3622: mpf_class temp(expr.val2, prec);
3623: Op::eval(f, expr.val1.get_mpf_t(), temp.get_mpf_t());
3624: }
3625: unsigned long int get_prec() const
3626: {
3627: unsigned long int prec1 = expr.val1.get_prec(),
3628: prec2 = expr.val2.get_prec();
3629: return (prec1 > prec2) ? prec1 : prec2;
3630: }
3631: };
3632:
3633: template <class T, class U, class Op>
3634: class __gmp_expr
3635: <__gmpf_value, __gmp_binary_expr<__gmp_expr<T, U>, mpf_class, Op> >
3636: {
3637: private:
3638: __gmp_binary_expr<__gmp_expr<T, U>, mpf_class, Op> expr;
3639: public:
3640: __gmp_expr(const __gmp_expr<T, U> &val1, const mpf_class &val2)
3641: : expr(val1, val2) { }
3642: void eval(mpf_ptr f, unsigned long int prec) const
3643: {
3644: mpf_class temp(expr.val1, prec);
3645: Op::eval(f, temp.get_mpf_t(), expr.val2.get_mpf_t());
3646: }
3647: unsigned long int get_prec() const
3648: {
3649: unsigned long int prec1 = expr.val1.get_prec(),
3650: prec2 = expr.val2.get_prec();
3651: return (prec1 > prec2) ? prec1 : prec2;
3652: }
3653: };
3654:
3655:
3656: // one argument is a subexpression, one is a built-in
3657:
3658: template <class T, class U, class V, class Op>
3659: class __gmp_expr<__gmpz_value, __gmp_binary_expr<__gmp_expr<T, U>, V, Op> >
3660: {
3661: private:
3662: __gmp_binary_expr<__gmp_expr<T, U>, V, Op> expr;
3663: public:
3664: __gmp_expr(const __gmp_expr<T, U> &val1, V val2) : expr(val1, val2) { }
3665: void eval(mpz_ptr z) const
3666: {
3667: mpz_class temp(expr.val1);
3668: Op::eval(z, temp.get_mpz_t(), expr.val2);
3669: }
3670: unsigned long int get_prec() const { return mpf_get_default_prec(); }
3671: };
3672:
3673: template <class T, class U, class V, class Op>
3674: class __gmp_expr<__gmpz_value, __gmp_binary_expr<T, __gmp_expr<U, V>, Op> >
3675: {
3676: private:
3677: __gmp_binary_expr<T, __gmp_expr<U, V>, Op> expr;
3678: public:
3679: __gmp_expr(T val1, const __gmp_expr<U, V> &val2) : expr(val1, val2) { }
3680: void eval(mpz_ptr z) const
3681: {
3682: mpz_class temp(expr.val2);
3683: Op::eval(z, expr.val1, temp.get_mpz_t());
3684: }
3685: unsigned long int get_prec() const { return mpf_get_default_prec(); }
3686: };
3687:
3688: template <class T, class U, class V, class Op>
3689: class __gmp_expr<__gmpq_value, __gmp_binary_expr<__gmp_expr<T, U>, V, Op> >
3690: {
3691: private:
3692: __gmp_binary_expr<__gmp_expr<T, U>, V, Op> expr;
3693: public:
3694: __gmp_expr(const __gmp_expr<T, U> &val1, V val2) : expr(val1, val2) { }
3695: void eval(mpq_ptr q) const
3696: {
3697: mpq_class temp(expr.val1);
3698: Op::eval(q, temp.get_mpq_t(), expr.val2);
3699: }
3700: unsigned long int get_prec() const { return mpf_get_default_prec(); }
3701: };
3702:
3703: template <class T, class U, class V, class Op>
3704: class __gmp_expr<__gmpq_value, __gmp_binary_expr<T, __gmp_expr<U, V>, Op> >
3705: {
3706: private:
3707: __gmp_binary_expr<T, __gmp_expr<U, V>, Op> expr;
3708: public:
3709: __gmp_expr(T val1, const __gmp_expr<U, V> &val2) : expr(val1, val2) { }
3710: void eval(mpq_ptr q) const
3711: {
3712: mpq_class temp(expr.val2);
3713: Op::eval(q, expr.val1, temp.get_mpq_t());
3714: }
3715: unsigned long int get_prec() const { return mpf_get_default_prec(); }
3716: };
3717:
3718: template <class T, class U, class V, class Op>
3719: class __gmp_expr<__gmpf_value, __gmp_binary_expr<__gmp_expr<T, U>, V, Op> >
3720: {
3721: private:
3722: __gmp_binary_expr<__gmp_expr<T, U>, V, Op> expr;
3723: public:
3724: __gmp_expr(const __gmp_expr<T, U> &val1, V val2) : expr(val1, val2) { }
3725: void eval(mpf_ptr f, unsigned long int prec) const
3726: {
3727: mpf_class temp(expr.val1, prec);
3728: Op::eval(f, temp.get_mpf_t(), expr.val2);
3729: }
3730: unsigned long int get_prec() const
3731: {
3732: unsigned long int prec1 = expr.val1.get_prec(),
3733: prec2 = mpf_get_default_prec();
3734: return (prec1 > prec2) ? prec1 : prec2;
3735: }
3736: };
3737:
3738: template <class T, class U, class V, class Op>
3739: class __gmp_expr<__gmpf_value, __gmp_binary_expr<T, __gmp_expr<U, V>, Op> >
3740: {
3741: private:
3742: __gmp_binary_expr<T, __gmp_expr<U, V>, Op> expr;
3743: public:
3744: __gmp_expr(T val1, const __gmp_expr<U, V> &val2) : expr(val1, val2) { }
3745: void eval(mpf_ptr f, unsigned long int prec) const
3746: {
3747: mpf_class temp(expr.val2, prec);
3748: Op::eval(f, expr.val1, temp.get_mpf_t());
3749: }
3750: unsigned long int get_prec() const
3751: {
3752: unsigned long int prec1 = mpf_get_default_prec(),
3753: prec2 = expr.val2.get_prec();
3754: return (prec1 > prec2) ? prec1 : prec2;
3755: }
3756: };
3757:
3758:
3759: // both arguments are subexpressions
3760:
3761: template <class T, class U, class V, class W, class Op>
3762: class __gmp_expr
3763: <__gmpz_value, __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<V, W>, Op> >
3764: {
3765: private:
3766: __gmp_binary_expr
3767: <__gmp_expr<T, U>, __gmp_expr<V, W>, Op> expr;
3768: public:
3769: __gmp_expr(const __gmp_expr<T, U> &val1, const __gmp_expr<V, W> &val2)
3770: : expr(val1, val2) { }
3771: void eval(mpz_ptr z) const
3772: {
3773: mpz_class temp1(expr.val1), temp2(expr.val2);
3774: Op::eval(z, temp1.get_mpz_t(), temp2.get_mpz_t());
3775: }
3776: unsigned long int get_prec() const { return mpf_get_default_prec(); }
3777: };
3778:
3779: template <class T, class U, class V, class W, class Op>
3780: class __gmp_expr
3781: <__gmpq_value, __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<V, W>, Op> >
3782: {
3783: private:
3784: __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<V, W>, Op> expr;
3785: public:
3786: __gmp_expr(const __gmp_expr<T, U> &val1, const __gmp_expr<V, W> &val2)
3787: : expr(val1, val2) { }
3788: void eval(mpq_ptr q) const
3789: {
3790: mpq_class temp1(expr.val1), temp2(expr.val2);
3791: Op::eval(q, temp1.get_mpq_t(), temp2.get_mpq_t());
3792: }
3793: unsigned long int get_prec() const { return mpf_get_default_prec(); }
3794: };
3795:
3796: template <class T, class U, class V, class W, class Op>
3797: class __gmp_expr
3798: <__gmpf_value, __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<V, W>, Op> >
3799: {
3800: private:
3801: __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<V, W>, Op> expr;
3802: public:
3803: __gmp_expr(const __gmp_expr<T, U> &val1, const __gmp_expr<V, W> &val2)
3804: : expr(val1, val2) { }
3805: void eval(mpf_ptr f, unsigned long int prec) const
3806: {
3807: mpf_class temp1(expr.val1, prec), temp2(expr.val2, prec);
3808: Op::eval(f, temp1.get_mpf_t(), temp2.get_mpf_t());
3809: }
3810: unsigned long int get_prec() const
3811: {
3812: unsigned long int prec1 = expr.val1.get_prec(),
3813: prec2 = expr.val2.get_prec();
3814: return (prec1 > prec2) ? prec1 : prec2;
3815: }
3816: };
3817:
3818:
3819: /**************** Special cases ****************/
3820: /* Some operations (i.e., add and subtract) with mixed mpz/mpq arguments
3821: can be done directly without first converting the mpz to mpq.
3822: Appropriate specializations are required. */
3823:
3824:
3825: #define __GMPZQ_DEFINE_EXPR(eval_fun) \
3826: \
3827: template <> \
3828: class __gmp_expr \
3829: <__gmpq_value, __gmp_binary_expr<mpz_class, mpq_class, eval_fun> > \
3830: { \
3831: private: \
3832: __gmp_binary_expr<mpz_class, mpq_class, eval_fun> expr; \
3833: public: \
3834: __gmp_expr(const mpz_class &val1, const mpq_class &val2) \
3835: : expr(val1, val2) { } \
3836: void eval(mpq_ptr q) const \
3837: { eval_fun::eval(q, expr.val1.get_mpz_t(), expr.val2.get_mpq_t()); } \
3838: unsigned long int get_prec() const { return mpf_get_default_prec(); } \
3839: }; \
3840: \
3841: template <> \
3842: class __gmp_expr \
3843: <__gmpq_value, __gmp_binary_expr<mpq_class, mpz_class, eval_fun> > \
3844: { \
3845: private: \
3846: __gmp_binary_expr<mpq_class, mpz_class, eval_fun> expr; \
3847: public: \
3848: __gmp_expr(const mpq_class &val1, const mpz_class &val2) \
3849: : expr(val1, val2) { } \
3850: void eval(mpq_ptr q) const \
3851: { eval_fun::eval(q, expr.val1.get_mpq_t(), expr.val2.get_mpz_t()); } \
3852: unsigned long int get_prec() const { return mpf_get_default_prec(); } \
3853: }; \
3854: \
3855: template <class T> \
3856: class __gmp_expr<__gmpq_value, \
3857: __gmp_binary_expr<mpz_class, __gmp_expr<__gmpq_value, T>, eval_fun> > \
3858: { \
3859: private: \
3860: __gmp_binary_expr<mpz_class, __gmp_expr<__gmpq_value, T>, eval_fun> expr; \
3861: public: \
3862: __gmp_expr(const mpz_class &val1, const __gmp_expr<__gmpq_value, T> &val2) \
3863: : expr(val1, val2) { } \
3864: void eval(mpq_ptr q) const \
3865: { \
3866: mpq_class temp(expr.val2); \
3867: eval_fun::eval(q, expr.val1.get_mpz_t(), temp.get_mpq_t()); \
3868: } \
3869: unsigned long int get_prec() const { return mpf_get_default_prec(); } \
3870: }; \
3871: \
3872: template <class T> \
3873: class __gmp_expr<__gmpq_value, \
3874: __gmp_binary_expr<mpq_class, __gmp_expr<__gmpz_value, T>, eval_fun> > \
3875: { \
3876: private: \
3877: __gmp_binary_expr<mpq_class, __gmp_expr<__gmpz_value, T>, eval_fun> expr; \
3878: public: \
3879: __gmp_expr(const mpq_class &val1, const __gmp_expr<__gmpz_value, T> &val2) \
3880: : expr(val1, val2) { } \
3881: void eval(mpq_ptr q) const \
3882: { \
3883: mpz_class temp(expr.val2); \
3884: eval_fun::eval(q, expr.val1.get_mpq_t(), temp.get_mpz_t()); \
3885: } \
3886: unsigned long int get_prec() const { return mpf_get_default_prec(); } \
3887: }; \
3888: \
3889: template <class T> \
3890: class __gmp_expr<__gmpq_value, \
3891: __gmp_binary_expr<__gmp_expr<__gmpz_value, T>, mpq_class, eval_fun> > \
3892: { \
3893: private: \
3894: __gmp_binary_expr<__gmp_expr<__gmpz_value, T>, mpq_class, eval_fun> expr; \
3895: public: \
3896: __gmp_expr(const __gmp_expr<__gmpz_value, T> &val1, const mpq_class &val2) \
3897: : expr(val1, val2) { } \
3898: void eval(mpq_ptr q) const \
3899: { \
3900: mpz_class temp(expr.val1); \
3901: eval_fun::eval(q, temp.get_mpz_t(), expr.val2.get_mpq_t()); \
3902: } \
3903: unsigned long int get_prec() const { return mpf_get_default_prec(); } \
3904: }; \
3905: \
3906: template <class T> \
3907: class __gmp_expr<__gmpq_value, \
3908: __gmp_binary_expr<__gmp_expr<__gmpq_value, T>, mpz_class, eval_fun> > \
3909: { \
3910: private: \
3911: __gmp_binary_expr<__gmp_expr<__gmpq_value, T>, mpz_class, eval_fun> expr; \
3912: public: \
3913: __gmp_expr(const __gmp_expr<__gmpq_value, T> &val1, const mpz_class &val2) \
3914: : expr(val1, val2) { } \
3915: void eval(mpq_ptr q) const \
3916: { \
3917: mpq_class temp(expr.val1); \
3918: eval_fun::eval(q, temp.get_mpq_t(), expr.val2.get_mpz_t()); \
3919: } \
3920: unsigned long int get_prec() const { return mpf_get_default_prec(); } \
3921: }; \
3922: \
3923: template <class T, class U> \
3924: class __gmp_expr<__gmpq_value, __gmp_binary_expr \
3925: <__gmp_expr<__gmpz_value, T>, __gmp_expr<__gmpq_value, U>, eval_fun> > \
3926: { \
3927: private: \
3928: __gmp_binary_expr \
3929: <__gmp_expr<__gmpz_value, T>, __gmp_expr<__gmpq_value, U>, eval_fun> expr; \
3930: public: \
3931: __gmp_expr(const __gmp_expr<__gmpz_value, T> &val1, \
3932: const __gmp_expr<__gmpq_value, U> &val2) \
3933: : expr(val1, val2) { } \
3934: void eval(mpq_ptr q) const \
3935: { \
3936: mpz_class temp1(expr.val1); \
3937: mpq_class temp2(expr.val2); \
3938: eval_fun::eval(q, temp1.get_mpz_t(), temp2.get_mpq_t()); \
3939: } \
3940: unsigned long int get_prec() const { return mpf_get_default_prec(); } \
3941: }; \
3942: \
3943: template <class T, class U> \
3944: class __gmp_expr<__gmpq_value, __gmp_binary_expr \
3945: <__gmp_expr<__gmpq_value, T>, __gmp_expr<__gmpz_value, U>, eval_fun> > \
3946: { \
3947: private: \
3948: __gmp_binary_expr \
3949: <__gmp_expr<__gmpq_value, T>, __gmp_expr<__gmpz_value, U>, eval_fun> expr; \
3950: public: \
3951: __gmp_expr(const __gmp_expr<__gmpq_value, T> &val1, \
3952: const __gmp_expr<__gmpz_value, U> &val2) \
3953: : expr(val1, val2) { } \
3954: void eval(mpq_ptr q) const \
3955: { \
3956: mpq_class temp1(expr.val1); \
3957: mpz_class temp2(expr.val2); \
3958: eval_fun::eval(q, temp1.get_mpq_t(), temp2.get_mpz_t()); \
3959: } \
3960: unsigned long int get_prec() const { return mpf_get_default_prec(); } \
3961: };
3962:
3963:
3964: __GMPZQ_DEFINE_EXPR(__gmp_binary_plus)
3965: __GMPZQ_DEFINE_EXPR(__gmp_binary_minus)
3966:
3967:
3968: /**************** Macros for defining functions ****************/
3969: /* Results of operators and functions are __gmp_expr<T, U> objects.
3970: T determines the numerical type of the expression: it can be either
3971: __gmpz_value, __gmpq_value, or __gmpf_value.
3972: U is either __gmp_unary_expr<V, Op> or __gmp_binary_expr<V, W, Op>,
3973: where V and W are the arguments' types -- they can in turn be
3974: expressions, thus allowing to build compound expressions to any
3975: degree of complexity. Op is a function object that must have an
3976: eval() method accepting appropriate arguments.
3977: When the arguments of a binary expression have different numerical
3978: types, __gmp_resolve_expr is used to determine the "larger" type.
3979: Actual evaluation of a __gmp_expr<T, U> object is done when it gets
3980: assigned to an mp[zqf]_class: this is done by calling its eval()
3981: method. */
3982:
3983: // non-member operators and functions
3984:
3985: #define __GMP_DEFINE_UNARY_FUNCTION(fun, eval_fun) \
3986: \
3987: template <class T, class U> \
3988: inline __gmp_expr<T, __gmp_unary_expr<__gmp_expr<T, U>, eval_fun> > \
3989: fun(const __gmp_expr<T, U> &expr) \
3990: { \
3991: return __gmp_expr<T, __gmp_unary_expr<__gmp_expr<T, U>, eval_fun> >(expr); \
3992: }
3993:
3994: #define __GMP_DEFINE_BINARY_FUNCTION(fun, eval_fun) \
3995: \
3996: template <class T, class U, class V, class W> \
3997: inline __gmp_expr<typename __gmp_resolve_expr<T, V>::value_type, \
3998: __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<V, W>, eval_fun> > \
3999: fun(const __gmp_expr<T, U> &expr1, const __gmp_expr<V, W> &expr2) \
4000: { \
4001: return __gmp_expr<typename __gmp_resolve_expr<T, V>::value_type, \
4002: __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<V, W>, eval_fun> > \
4003: (expr1, expr2); \
4004: } \
4005: \
4006: template <class T, class U> \
4007: inline __gmp_expr \
4008: <T, __gmp_binary_expr<__gmp_expr<T, U>, signed long int, eval_fun> > \
4009: fun(const __gmp_expr<T, U> &expr, signed char c) \
4010: { \
4011: return __gmp_expr<T, __gmp_binary_expr \
4012: <__gmp_expr<T, U>, signed long int, eval_fun> >(expr, c); \
4013: } \
4014: \
4015: template <class T, class U> \
4016: inline __gmp_expr \
4017: <T, __gmp_binary_expr<signed long int, __gmp_expr<T, U>, eval_fun> > \
4018: fun(signed char c, const __gmp_expr<T, U> &expr) \
4019: { \
4020: return __gmp_expr<T, __gmp_binary_expr \
4021: <signed long int, __gmp_expr<T, U>, eval_fun> >(c, expr); \
4022: } \
4023: \
4024: template <class T, class U> \
4025: inline __gmp_expr \
4026: <T, __gmp_binary_expr<__gmp_expr<T, U>, unsigned long int, eval_fun> > \
4027: fun(const __gmp_expr<T, U> &expr, unsigned char c) \
4028: { \
4029: return __gmp_expr<T, __gmp_binary_expr \
4030: <__gmp_expr<T, U>, unsigned long int, eval_fun> >(expr, c); \
4031: } \
4032: \
4033: template <class T, class U> \
4034: inline __gmp_expr \
4035: <T, __gmp_binary_expr<unsigned long int, __gmp_expr<T, U>, eval_fun> > \
4036: fun(unsigned char c, const __gmp_expr<T, U> &expr) \
4037: { \
4038: return __gmp_expr<T, __gmp_binary_expr \
4039: <unsigned long int, __gmp_expr<T, U>, eval_fun> >(c, expr); \
4040: } \
4041: \
4042: template <class T, class U> \
4043: inline __gmp_expr \
4044: <T, __gmp_binary_expr<__gmp_expr<T, U>, signed long int, eval_fun> > \
4045: fun(const __gmp_expr<T, U> &expr, signed int i) \
4046: { \
4047: return __gmp_expr<T, __gmp_binary_expr \
4048: <__gmp_expr<T, U>, signed long int, eval_fun> >(expr, i); \
4049: } \
4050: \
4051: template <class T, class U> \
4052: inline __gmp_expr \
4053: <T, __gmp_binary_expr<signed long int, __gmp_expr<T, U>, eval_fun> > \
4054: fun(signed int i, const __gmp_expr<T, U> &expr) \
4055: { \
4056: return __gmp_expr<T, __gmp_binary_expr \
4057: <signed long int, __gmp_expr<T, U>, eval_fun> >(i, expr); \
4058: } \
4059: \
4060: template <class T, class U> \
4061: inline __gmp_expr \
4062: <T, __gmp_binary_expr<__gmp_expr<T, U>, unsigned long int, eval_fun> > \
4063: fun(const __gmp_expr<T, U> &expr, unsigned int i) \
4064: { \
4065: return __gmp_expr<T, __gmp_binary_expr \
4066: <__gmp_expr<T, U>, unsigned long int, eval_fun> >(expr, i); \
4067: } \
4068: \
4069: template <class T, class U> \
4070: inline __gmp_expr \
4071: <T, __gmp_binary_expr<unsigned long int, __gmp_expr<T, U>, eval_fun> > \
4072: fun(unsigned int i, const __gmp_expr<T, U> &expr) \
4073: { \
4074: return __gmp_expr<T, __gmp_binary_expr \
4075: <unsigned long int, __gmp_expr<T, U>, eval_fun> >(i, expr); \
4076: } \
4077: \
4078: template <class T, class U> \
4079: inline __gmp_expr \
4080: <T, __gmp_binary_expr<__gmp_expr<T, U>, signed long int, eval_fun> > \
4081: fun(const __gmp_expr<T, U> &expr, signed short int s) \
4082: { \
4083: return __gmp_expr<T, __gmp_binary_expr \
4084: <__gmp_expr<T, U>, signed long int, eval_fun> >(expr, s); \
4085: } \
4086: \
4087: template <class T, class U> \
4088: inline __gmp_expr \
4089: <T, __gmp_binary_expr<signed long int, __gmp_expr<T, U>, eval_fun> > \
4090: fun(signed short int s, const __gmp_expr<T, U> &expr) \
4091: { \
4092: return __gmp_expr<T, __gmp_binary_expr \
4093: <signed long int, __gmp_expr<T, U>, eval_fun> >(s, expr); \
4094: } \
4095: \
4096: template <class T, class U> \
4097: inline __gmp_expr \
4098: <T, __gmp_binary_expr<__gmp_expr<T, U>, unsigned long int, eval_fun> > \
4099: fun(const __gmp_expr<T, U> &expr, unsigned short int s) \
4100: { \
4101: return __gmp_expr<T, __gmp_binary_expr \
4102: <__gmp_expr<T, U>, unsigned long int, eval_fun> >(expr, s); \
4103: } \
4104: \
4105: template <class T, class U> \
4106: inline __gmp_expr \
4107: <T, __gmp_binary_expr<unsigned long int, __gmp_expr<T, U>, eval_fun> > \
4108: fun(unsigned short int s, const __gmp_expr<T, U> &expr) \
4109: { \
4110: return __gmp_expr<T, __gmp_binary_expr \
4111: <unsigned long int, __gmp_expr<T, U>, eval_fun> >(s, expr); \
4112: } \
4113: \
4114: template <class T, class U> \
4115: inline __gmp_expr \
4116: <T, __gmp_binary_expr<__gmp_expr<T, U>, signed long int, eval_fun> > \
4117: fun(const __gmp_expr<T, U> &expr, signed long int l) \
4118: { \
4119: return __gmp_expr<T, __gmp_binary_expr \
4120: <__gmp_expr<T, U>, signed long int, eval_fun> >(expr, l); \
4121: } \
4122: \
4123: template <class T, class U> \
4124: inline __gmp_expr \
4125: <T, __gmp_binary_expr<signed long int, __gmp_expr<T, U>, eval_fun> > \
4126: fun(signed long int l, const __gmp_expr<T, U> &expr) \
4127: { \
4128: return __gmp_expr<T, __gmp_binary_expr \
4129: <signed long int, __gmp_expr<T, U>, eval_fun> >(l, expr); \
4130: } \
4131: \
4132: template <class T, class U> \
4133: inline __gmp_expr \
4134: <T, __gmp_binary_expr<__gmp_expr<T, U>, unsigned long int, eval_fun> > \
4135: fun(const __gmp_expr<T, U> &expr, unsigned long int l) \
4136: { \
4137: return __gmp_expr<T, __gmp_binary_expr \
4138: <__gmp_expr<T, U>, unsigned long int, eval_fun> >(expr, l); \
4139: } \
4140: \
4141: template <class T, class U> \
4142: inline __gmp_expr \
4143: <T, __gmp_binary_expr<unsigned long int, __gmp_expr<T, U>, eval_fun> > \
4144: fun(unsigned long int l, const __gmp_expr<T, U> &expr) \
4145: { \
4146: return __gmp_expr<T, __gmp_binary_expr \
4147: <unsigned long int, __gmp_expr<T, U>, eval_fun> >(l, expr); \
4148: } \
4149: \
4150: template <class T, class U> \
4151: inline __gmp_expr<T, __gmp_binary_expr<__gmp_expr<T, U>, double, eval_fun> > \
4152: fun(const __gmp_expr<T, U> &expr, float f) \
4153: { \
4154: return __gmp_expr \
4155: <T, __gmp_binary_expr<__gmp_expr<T, U>, double, eval_fun> >(expr, f); \
4156: } \
4157: \
4158: template <class T, class U> \
4159: inline __gmp_expr<T, __gmp_binary_expr<double, __gmp_expr<T, U>, eval_fun> > \
4160: fun(float f, const __gmp_expr<T, U> &expr) \
4161: { \
4162: return __gmp_expr \
4163: <T, __gmp_binary_expr<double, __gmp_expr<T, U>, eval_fun> >(f, expr); \
4164: } \
4165: \
4166: template <class T, class U> \
4167: inline __gmp_expr<T, __gmp_binary_expr<__gmp_expr<T, U>, double, eval_fun> > \
4168: fun(const __gmp_expr<T, U> &expr, double d) \
4169: { \
4170: return __gmp_expr \
4171: <T, __gmp_binary_expr<__gmp_expr<T, U>, double, eval_fun> >(expr, d); \
4172: } \
4173: \
4174: template <class T, class U> \
4175: inline __gmp_expr<T, __gmp_binary_expr<double, __gmp_expr<T, U>, eval_fun> > \
4176: fun(double d, const __gmp_expr<T, U> &expr) \
4177: { \
4178: return __gmp_expr \
4179: <T, __gmp_binary_expr<double, __gmp_expr<T, U>, eval_fun> >(d, expr); \
4180: } \
4181: \
4182: template <class T, class U> \
4183: inline __gmp_expr \
4184: <T, __gmp_binary_expr<__gmp_expr<T, U>, long double, eval_fun> > \
4185: fun(const __gmp_expr<T, U> &expr, long double ld) \
4186: { \
4187: return __gmp_expr<T, __gmp_binary_expr \
4188: <__gmp_expr<T, U>, long double, eval_fun> >(expr, ld); \
4189: } \
4190: \
4191: template <class T, class U> \
4192: inline __gmp_expr \
4193: <T, __gmp_binary_expr<long double, __gmp_expr<T, U>, eval_fun> > \
4194: fun(long double ld, const __gmp_expr<T, U> &expr) \
4195: { \
4196: return __gmp_expr<T, __gmp_binary_expr \
4197: <long double, __gmp_expr<T, U>, eval_fun> >(ld, expr); \
4198: }
4199:
4200: #define __GMP_DEFINE_BINARY_FUNCTION_UI(fun, eval_fun) \
4201: \
4202: template <class T, class U> \
4203: inline __gmp_expr \
4204: <T, __gmp_binary_expr<__gmp_expr<T, U>, unsigned long int, eval_fun> > \
4205: fun(const __gmp_expr<T, U> &expr, unsigned long int l) \
4206: { \
4207: return __gmp_expr<T, __gmp_binary_expr \
4208: <__gmp_expr<T, U>, unsigned long int, eval_fun> >(expr, l); \
4209: }
4210:
4211: #define __GMP_DEFINE_UNARY_TYPE_FUNCTION(type, fun, eval_fun) \
4212: \
4213: template <class T, class U> \
4214: inline type fun(const __gmp_expr<T, U> &expr) \
4215: { \
4216: typename __gmp_resolve_expr<T, T>::temp_type temp(expr); \
4217: return eval_fun::eval(temp.get_mp()); \
4218: }
4219:
4220: #define __GMP_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun) \
4221: \
4222: template <class T, class U, class V, class W> \
4223: inline type fun(const __gmp_expr<T, U> &expr1, \
4224: const __gmp_expr<V, W> &expr2) \
4225: { \
4226: typename __gmp_resolve_expr<T, V>::temp_type temp1(expr1), temp2(expr2); \
4227: return eval_fun::eval(temp1.get_mp(), temp2.get_mp()); \
4228: } \
4229: \
4230: template <class T, class U> \
4231: inline type fun(const __gmp_expr<T, U> &expr1, \
4232: const __gmp_expr<T, U> &expr2) \
4233: { \
4234: typename __gmp_resolve_expr<T, T>::temp_type temp1(expr1), temp2(expr2); \
4235: return eval_fun::eval(temp1.get_mp(), temp2.get_mp()); \
4236: } \
4237: \
4238: template <class T, class U> \
4239: inline type fun(const __gmp_expr<T, U> &expr, signed char c) \
4240: { \
4241: typename __gmp_resolve_expr<T, T>::temp_type temp(expr); \
4242: return eval_fun::eval(temp.get_mp(), (signed long int) c); \
4243: } \
4244: \
4245: template <class T, class U> \
4246: inline type fun(signed char c, const __gmp_expr<T, U> &expr) \
4247: { \
4248: typename __gmp_resolve_expr<T, T>::temp_type temp(expr); \
4249: return eval_fun::eval((signed long int) c, temp.get_mp()); \
4250: } \
4251: \
4252: template <class T, class U> \
4253: inline type fun(const __gmp_expr<T, U> &expr, unsigned char c) \
4254: { \
4255: typename __gmp_resolve_expr<T, T>::temp_type temp(expr); \
4256: return eval_fun::eval(temp.get_mp(), (unsigned long int) c); \
4257: } \
4258: \
4259: template <class T, class U> \
4260: inline type fun(unsigned char c, const __gmp_expr<T, U> &expr) \
4261: { \
4262: typename __gmp_resolve_expr<T, T>::temp_type temp(expr); \
4263: return eval_fun::eval((unsigned long int) c, temp.get_mp()); \
4264: } \
4265: \
4266: template <class T, class U> \
4267: inline type fun(const __gmp_expr<T, U> &expr, signed int i) \
4268: { \
4269: typename __gmp_resolve_expr<T, T>::temp_type temp(expr); \
4270: return eval_fun::eval(temp.get_mp(), (signed long int) i); \
4271: } \
4272: \
4273: template <class T, class U> \
4274: inline type fun(signed int i, const __gmp_expr<T, U> &expr) \
4275: { \
4276: typename __gmp_resolve_expr<T, T>::temp_type temp(expr); \
4277: return eval_fun::eval((signed long int) i, temp.get_mp()); \
4278: } \
4279: \
4280: template <class T, class U> \
4281: inline type fun(const __gmp_expr<T, U> &expr, unsigned int i) \
4282: { \
4283: typename __gmp_resolve_expr<T, T>::temp_type temp(expr); \
4284: return eval_fun::eval(temp.get_mp(), (unsigned long int) i); \
4285: } \
4286: \
4287: template <class T, class U> \
4288: inline type fun(unsigned int i, const __gmp_expr<T, U> &expr) \
4289: { \
4290: typename __gmp_resolve_expr<T, T>::temp_type temp(expr); \
4291: return eval_fun::eval((unsigned long int) i, temp.get_mp()); \
4292: } \
4293: \
4294: template <class T, class U> \
4295: inline type fun(const __gmp_expr<T, U> &expr, signed short int s) \
4296: { \
4297: typename __gmp_resolve_expr<T, T>::temp_type temp(expr); \
4298: return eval_fun::eval(temp.get_mp(), (signed long int) s); \
4299: } \
4300: \
4301: template <class T, class U> \
4302: inline type fun(signed short int s, const __gmp_expr<T, U> &expr) \
4303: { \
4304: typename __gmp_resolve_expr<T, T>::temp_type temp(expr); \
4305: return eval_fun::eval((signed long int) s, temp.get_mp()); \
4306: } \
4307: \
4308: template <class T, class U> \
4309: inline type fun(const __gmp_expr<T, U> &expr, unsigned short int s) \
4310: { \
4311: typename __gmp_resolve_expr<T, T>::temp_type temp(expr); \
4312: return eval_fun::eval(temp.get_mp(), (unsigned long int) s); \
4313: } \
4314: \
4315: template <class T, class U> \
4316: inline type fun(unsigned short int s, const __gmp_expr<T, U> &expr) \
4317: { \
4318: typename __gmp_resolve_expr<T, T>::temp_type temp(expr); \
4319: return eval_fun::eval((unsigned long int) s, temp.get_mp()); \
4320: } \
4321: \
4322: template <class T, class U> \
4323: inline type fun(const __gmp_expr<T, U> &expr, signed long int l) \
4324: { \
4325: typename __gmp_resolve_expr<T, T>::temp_type temp(expr); \
4326: return eval_fun::eval(temp.get_mp(), l); \
4327: } \
4328: \
4329: template <class T, class U> \
4330: inline type fun(signed long int l, const __gmp_expr<T, U> &expr) \
4331: { \
4332: typename __gmp_resolve_expr<T, T>::temp_type temp(expr); \
4333: return eval_fun::eval(l, temp.get_mp()); \
4334: } \
4335: \
4336: template <class T, class U> \
4337: inline type fun(const __gmp_expr<T, U> &expr, unsigned long int l) \
4338: { \
4339: typename __gmp_resolve_expr<T, T>::temp_type temp(expr); \
4340: return eval_fun::eval(temp.get_mp(), l); \
4341: } \
4342: \
4343: template <class T, class U> \
4344: inline type fun(unsigned long int l, const __gmp_expr<T, U> &expr) \
4345: { \
4346: typename __gmp_resolve_expr<T, T>::temp_type temp(expr); \
4347: return eval_fun::eval(l, temp.get_mp()); \
4348: } \
4349: \
4350: template <class T, class U> \
4351: inline type fun(const __gmp_expr<T, U> &expr, float f) \
4352: { \
4353: typename __gmp_resolve_expr<T, T>::temp_type temp(expr); \
4354: return eval_fun::eval(temp.get_mp(), (double) f); \
4355: } \
4356: \
4357: template <class T, class U> \
4358: inline type fun(float f, const __gmp_expr<T, U> &expr) \
4359: { \
4360: typename __gmp_resolve_expr<T, T>::temp_type temp(expr); \
4361: return eval_fun::eval((double) f, temp.get_mp()); \
4362: } \
4363: \
4364: template <class T, class U> \
4365: inline type fun(const __gmp_expr<T, U> &expr, double d) \
4366: { \
4367: typename __gmp_resolve_expr<T, T>::temp_type temp(expr); \
4368: return eval_fun::eval(temp.get_mp(), d); \
4369: } \
4370: \
4371: template <class T, class U> \
4372: inline type fun(double d, const __gmp_expr<T, U> &expr) \
4373: { \
4374: typename __gmp_resolve_expr<T, T>::temp_type temp(expr); \
4375: return eval_fun::eval(d, temp.get_mp()); \
4376: } \
4377: \
4378: template <class T, class U> \
4379: inline type fun(const __gmp_expr<T, U> &expr, long double ld) \
4380: { \
4381: typename __gmp_resolve_expr<T, T>::temp_type temp(expr); \
4382: return eval_fun::eval(temp.get_mp(), ld); \
4383: } \
4384: \
4385: template <class T, class U> \
4386: inline type fun(long double ld, const __gmp_expr<T, U> &expr) \
4387: { \
4388: typename __gmp_resolve_expr<T, T>::temp_type temp(expr); \
4389: return eval_fun::eval(ld, temp.get_mp()); \
4390: }
4391:
4392:
4393: // member operators for mpz_class
4394:
4395: #define __GMPZZ_DEFINE_COMPOUND_OPERATOR(fun, eval_fun) \
4396: \
4397: template <class T, class U> \
4398: inline mpz_class & mpz_class::fun(const __gmp_expr<T, U> &expr) \
4399: { \
4400: __gmpz_temp temp(expr); \
4401: eval_fun::eval(mp, mp, temp.get_mp()); \
4402: return *this; \
4403: }
4404:
4405: #define __GMPZN_DEFINE_COMPOUND_OPERATOR(fun, eval_fun) \
4406: \
4407: inline mpz_class & mpz_class::fun(signed char c) \
4408: { \
4409: eval_fun::eval(mp, mp, (signed long int) c); \
4410: return *this; \
4411: } \
4412: \
4413: inline mpz_class & mpz_class::fun(unsigned char c) \
4414: { \
4415: eval_fun::eval(mp, mp, (unsigned long int) c); \
4416: return *this; \
4417: } \
4418: \
4419: inline mpz_class & mpz_class::fun(signed int i) \
4420: { \
4421: eval_fun::eval(mp, mp, (signed long int) i); \
4422: return *this; \
4423: } \
4424: \
4425: inline mpz_class & mpz_class::fun(unsigned int i) \
4426: { \
4427: eval_fun::eval(mp, mp, (unsigned long int) i); \
4428: return *this; \
4429: } \
4430: \
4431: inline mpz_class & mpz_class::fun(signed short int s) \
4432: { \
4433: eval_fun::eval(mp, mp, (signed long int) s); \
4434: return *this; \
4435: } \
4436: \
4437: inline mpz_class & mpz_class::fun(unsigned short int s) \
4438: { \
4439: eval_fun::eval(mp, mp, (unsigned long int) s); \
4440: return *this; \
4441: } \
4442: \
4443: inline mpz_class & mpz_class::fun(signed long int l) \
4444: { \
4445: eval_fun::eval(mp, mp, l); \
4446: return *this; \
4447: } \
4448: \
4449: inline mpz_class & mpz_class::fun(unsigned long int l) \
4450: { \
4451: eval_fun::eval(mp, mp, l); \
4452: return *this; \
4453: } \
4454: \
4455: inline mpz_class & mpz_class::fun(float f) \
4456: { \
4457: eval_fun::eval(mp, mp, (double) f); \
4458: return *this; \
4459: } \
4460: \
4461: inline mpz_class & mpz_class::fun(double d) \
4462: { \
4463: eval_fun::eval(mp, mp, d); \
4464: return *this; \
4465: } \
4466: \
4467: /* \
4468: inline mpz_class & mpz_class::fun(long double ld) \
4469: { \
4470: eval_fun::eval(mp, mp, ld); \
4471: return *this; \
4472: } */
4473:
4474: #define __GMPZ_DEFINE_COMPOUND_OPERATOR(fun, eval_fun) \
4475: __GMPZZ_DEFINE_COMPOUND_OPERATOR(fun, eval_fun) \
4476: __GMPZN_DEFINE_COMPOUND_OPERATOR(fun, eval_fun)
4477:
4478: #define __GMPZ_DEFINE_COMPOUND_OPERATOR_UI(fun, eval_fun) \
4479: \
4480: inline mpz_class & mpz_class::fun(unsigned long int l) \
4481: { \
4482: eval_fun::eval(mp, mp, l); \
4483: return *this; \
4484: }
4485:
4486: #define __GMPZ_DEFINE_INCREMENT_OPERATOR(fun, eval_fun) \
4487: \
4488: inline mpz_class & mpz_class::fun() \
4489: { \
4490: eval_fun::eval(mp, mp); \
4491: return *this; \
4492: } \
4493: \
4494: inline mpz_class mpz_class::fun(int) \
4495: { \
4496: mpz_class temp(*this); \
4497: eval_fun::eval(mp, mp); \
4498: return temp; \
4499: }
4500:
4501:
4502: // member operators for mpz_classref
4503:
4504: #define __GMPZRR_DEFINE_COMPOUND_OPERATOR(fun, eval_fun) \
4505: \
4506: template <class T, class U> \
4507: inline mpz_classref & mpz_classref::fun(const __gmp_expr<T, U> &expr) \
4508: { \
4509: __gmpz_temp temp(expr); \
4510: eval_fun::eval(ref, ref, temp.get_mp()); \
4511: return *this; \
4512: }
4513:
4514: #define __GMPZRN_DEFINE_COMPOUND_OPERATOR(fun, eval_fun) \
4515: \
4516: inline mpz_classref & mpz_classref::fun(signed char c) \
4517: { \
4518: eval_fun::eval(ref, ref, (signed long int) c); \
4519: return *this; \
4520: } \
4521: \
4522: inline mpz_classref & mpz_classref::fun(unsigned char c) \
4523: { \
4524: eval_fun::eval(ref, ref, (unsigned long int) c); \
4525: return *this; \
4526: } \
4527: \
4528: inline mpz_classref & mpz_classref::fun(signed int i) \
4529: { \
4530: eval_fun::eval(ref, ref, (signed long int) i); \
4531: return *this; \
4532: } \
4533: \
4534: inline mpz_classref & mpz_classref::fun(unsigned int i) \
4535: { \
4536: eval_fun::eval(ref, ref, (unsigned long int) i); \
4537: return *this; \
4538: } \
4539: \
4540: inline mpz_classref & mpz_classref::fun(signed short int s) \
4541: { \
4542: eval_fun::eval(ref, ref, (signed long int) s); \
4543: return *this; \
4544: } \
4545: \
4546: inline mpz_classref & mpz_classref::fun(unsigned short int s) \
4547: { \
4548: eval_fun::eval(ref, ref, (unsigned long int) s); \
4549: return *this; \
4550: } \
4551: \
4552: inline mpz_classref & mpz_classref::fun(signed long int l) \
4553: { \
4554: eval_fun::eval(ref, ref, l); \
4555: return *this; \
4556: } \
4557: \
4558: inline mpz_classref & mpz_classref::fun(unsigned long int l) \
4559: { \
4560: eval_fun::eval(ref, ref, l); \
4561: return *this; \
4562: } \
4563: \
4564: inline mpz_classref & mpz_classref::fun(float f) \
4565: { \
4566: eval_fun::eval(ref, ref, (double) f); \
4567: return *this; \
4568: } \
4569: \
4570: inline mpz_classref & mpz_classref::fun(double d) \
4571: { \
4572: eval_fun::eval(ref, ref, d); \
4573: return *this; \
4574: } \
4575: \
4576: /* \
4577: inline mpz_classref & mpz_classref::fun(long double ld) \
4578: { \
4579: eval_fun::eval(ref, ref, ld); \
4580: return *this; \
4581: } */
4582:
4583: #define __GMPZR_DEFINE_COMPOUND_OPERATOR(fun, eval_fun) \
4584: __GMPZRR_DEFINE_COMPOUND_OPERATOR(fun, eval_fun) \
4585: __GMPZRN_DEFINE_COMPOUND_OPERATOR(fun, eval_fun)
4586:
4587: #define __GMPZR_DEFINE_COMPOUND_OPERATOR_UI(fun, eval_fun) \
4588: \
4589: inline mpz_classref & mpz_classref::fun(unsigned long int l) \
4590: { \
4591: eval_fun::eval(ref, ref, l); \
4592: return *this; \
4593: }
4594:
4595: #define __GMPZR_DEFINE_INCREMENT_OPERATOR(fun, eval_fun) \
4596: \
4597: inline mpz_classref & mpz_classref::fun() \
4598: { \
4599: eval_fun::eval(ref, ref); \
4600: return *this; \
4601: } \
4602: \
4603: inline mpz_class mpz_classref::fun(int) \
4604: { \
4605: mpz_class temp(*this); \
4606: eval_fun::eval(ref, ref); \
4607: return temp; \
4608: }
4609:
4610:
4611: // member operators for mpq_class
4612:
4613: #define __GMPQQ_DEFINE_COMPOUND_OPERATOR(fun, eval_fun) \
4614: \
4615: template <class T, class U> \
4616: inline mpq_class & mpq_class::fun(const __gmp_expr<T, U> &expr) \
4617: { \
4618: __gmpq_temp temp(expr); \
4619: eval_fun::eval(mp, mp, temp.get_mp()); \
4620: return *this; \
4621: }
4622:
4623: #define __GMPQN_DEFINE_COMPOUND_OPERATOR(fun, eval_fun) \
4624: \
4625: inline mpq_class & mpq_class::fun(signed char c) \
4626: { \
4627: eval_fun::eval(mp, mp, (signed long int) c); \
4628: return *this; \
4629: } \
4630: \
4631: inline mpq_class & mpq_class::fun(unsigned char c) \
4632: { \
4633: eval_fun::eval(mp, mp, (unsigned long int) c); \
4634: return *this; \
4635: } \
4636: \
4637: inline mpq_class & mpq_class::fun(signed int i) \
4638: { \
4639: eval_fun::eval(mp, mp, (signed long int) i); \
4640: return *this; \
4641: } \
4642: \
4643: inline mpq_class & mpq_class::fun(unsigned int i) \
4644: { \
4645: eval_fun::eval(mp, mp, (unsigned long int) i); \
4646: return *this; \
4647: } \
4648: \
4649: inline mpq_class & mpq_class::fun(signed short int s) \
4650: { \
4651: eval_fun::eval(mp, mp, (signed long int) s); \
4652: return *this; \
4653: } \
4654: \
4655: inline mpq_class & mpq_class::fun(unsigned short int s) \
4656: { \
4657: eval_fun::eval(mp, mp, (unsigned long int) s); \
4658: return *this; \
4659: } \
4660: \
4661: inline mpq_class & mpq_class::fun(signed long int l) \
4662: { \
4663: eval_fun::eval(mp, mp, l); \
4664: return *this; \
4665: } \
4666: \
4667: inline mpq_class & mpq_class::fun(unsigned long int l) \
4668: { \
4669: eval_fun::eval(mp, mp, l); \
4670: return *this; \
4671: } \
4672: \
4673: inline mpq_class & mpq_class::fun(float f) \
4674: { \
4675: eval_fun::eval(mp, mp, (double) f); \
4676: return *this; \
4677: } \
4678: \
4679: inline mpq_class & mpq_class::fun(double d) \
4680: { \
4681: eval_fun::eval(mp, mp, d); \
4682: return *this; \
4683: } \
4684: \
4685: /* \
4686: inline mpq_class & mpq_class::fun(long double ld) \
4687: { \
4688: eval_fun::eval(mp, mp, ld); \
4689: return *this; \
4690: } */
4691:
4692: #define __GMPQ_DEFINE_COMPOUND_OPERATOR(fun, eval_fun) \
4693: __GMPQQ_DEFINE_COMPOUND_OPERATOR(fun, eval_fun) \
4694: __GMPQN_DEFINE_COMPOUND_OPERATOR(fun, eval_fun)
4695:
4696: #define __GMPQ_DEFINE_COMPOUND_OPERATOR_UI(fun, eval_fun) \
4697: \
4698: inline mpq_class & mpq_class::fun(unsigned long int l) \
4699: { \
4700: eval_fun::eval(mp, mp, l); \
4701: return *this; \
4702: }
4703:
4704: #define __GMPQ_DEFINE_INCREMENT_OPERATOR(fun, eval_fun) \
4705: \
4706: inline mpq_class & mpq_class::fun() \
4707: { \
4708: eval_fun::eval(mp, mp); \
4709: return *this; \
4710: } \
4711: \
4712: inline mpq_class mpq_class::fun(int) \
4713: { \
4714: mpq_class temp(*this); \
4715: eval_fun::eval(mp, mp); \
4716: return temp; \
4717: }
4718:
4719:
4720: // member operators for mpf_class
4721:
4722: #define __GMPFF_DEFINE_COMPOUND_OPERATOR(fun, eval_fun) \
4723: \
4724: template <class T, class U> \
4725: inline mpf_class & mpf_class::fun(const __gmp_expr<T, U> &expr) \
4726: { \
4727: __gmpf_temp temp(expr, get_prec()); \
4728: eval_fun::eval(mp, mp, temp.get_mp()); \
4729: return *this; \
4730: }
4731:
4732: #define __GMPFN_DEFINE_COMPOUND_OPERATOR(fun, eval_fun) \
4733: \
4734: inline mpf_class & mpf_class::fun(signed char c) \
4735: { \
4736: eval_fun::eval(mp, mp, (signed long int) c); \
4737: return *this; \
4738: } \
4739: \
4740: inline mpf_class & mpf_class::fun(unsigned char c) \
4741: { \
4742: eval_fun::eval(mp, mp, (unsigned long int) c); \
4743: return *this; \
4744: } \
4745: \
4746: inline mpf_class & mpf_class::fun(signed int i) \
4747: { \
4748: eval_fun::eval(mp, mp, (signed long int) i); \
4749: return *this; \
4750: } \
4751: \
4752: inline mpf_class & mpf_class::fun(unsigned int i) \
4753: { \
4754: eval_fun::eval(mp, mp, (unsigned long int) i); \
4755: return *this; \
4756: } \
4757: \
4758: inline mpf_class & mpf_class::fun(signed short int s) \
4759: { \
4760: eval_fun::eval(mp, mp, (signed long int) s); \
4761: return *this; \
4762: } \
4763: \
4764: inline mpf_class & mpf_class::fun(unsigned short int s) \
4765: { \
4766: eval_fun::eval(mp, mp, (unsigned long int) s); \
4767: return *this; \
4768: } \
4769: \
4770: inline mpf_class & mpf_class::fun(signed long int l) \
4771: { \
4772: eval_fun::eval(mp, mp, l); \
4773: return *this; \
4774: } \
4775: \
4776: inline mpf_class & mpf_class::fun(unsigned long int l) \
4777: { \
4778: eval_fun::eval(mp, mp, l); \
4779: return *this; \
4780: } \
4781: \
4782: inline mpf_class & mpf_class::fun(float f) \
4783: { \
4784: eval_fun::eval(mp, mp, (double) f); \
4785: return *this; \
4786: } \
4787: \
4788: inline mpf_class & mpf_class::fun(double d) \
4789: { \
4790: eval_fun::eval(mp, mp, d); \
4791: return *this; \
4792: } \
4793: \
4794: /* \
4795: inline mpf_class & mpf_class::fun(long double ld) \
4796: { \
4797: eval_fun::eval(mp, mp, ld); \
4798: return *this; \
4799: } */
4800:
4801: #define __GMPF_DEFINE_COMPOUND_OPERATOR(fun, eval_fun) \
4802: __GMPFF_DEFINE_COMPOUND_OPERATOR(fun, eval_fun) \
4803: __GMPFN_DEFINE_COMPOUND_OPERATOR(fun, eval_fun)
4804:
4805: #define __GMPF_DEFINE_COMPOUND_OPERATOR_UI(fun, eval_fun) \
4806: \
4807: inline mpf_class & mpf_class::fun(unsigned long int l) \
4808: { \
4809: eval_fun::eval(mp, mp, l); \
4810: return *this; \
4811: }
4812:
4813: #define __GMPF_DEFINE_INCREMENT_OPERATOR(fun, eval_fun) \
4814: \
4815: inline mpf_class & mpf_class::fun() \
4816: { \
4817: eval_fun::eval(mp, mp); \
4818: return *this; \
4819: } \
4820: \
4821: inline mpf_class mpf_class::fun(int) \
4822: { \
4823: mpf_class temp(*this); \
4824: eval_fun::eval(mp, mp); \
4825: return temp; \
4826: }
4827:
4828:
4829: /**************** Arithmetic operators and functions ****************/
4830:
4831: // non-member operators and functions
4832:
4833: __GMP_DEFINE_UNARY_FUNCTION(operator+, __gmp_unary_plus)
4834: __GMP_DEFINE_UNARY_FUNCTION(operator-, __gmp_unary_minus)
4835: __GMP_DEFINE_UNARY_FUNCTION(operator~, __gmp_unary_com)
4836:
4837: __GMP_DEFINE_BINARY_FUNCTION(operator+, __gmp_binary_plus)
4838: __GMP_DEFINE_BINARY_FUNCTION(operator-, __gmp_binary_minus)
4839: __GMP_DEFINE_BINARY_FUNCTION(operator*, __gmp_binary_multiplies)
4840: __GMP_DEFINE_BINARY_FUNCTION(operator/, __gmp_binary_divides)
4841: __GMP_DEFINE_BINARY_FUNCTION(operator%, __gmp_binary_modulus)
4842: __GMP_DEFINE_BINARY_FUNCTION(operator&, __gmp_binary_and)
4843: __GMP_DEFINE_BINARY_FUNCTION(operator|, __gmp_binary_ior)
4844: __GMP_DEFINE_BINARY_FUNCTION(operator^, __gmp_binary_xor)
4845:
4846: __GMP_DEFINE_BINARY_FUNCTION_UI(operator<<, __gmp_binary_lshift)
4847: __GMP_DEFINE_BINARY_FUNCTION_UI(operator>>, __gmp_binary_rshift)
4848:
4849: __GMP_DEFINE_BINARY_TYPE_FUNCTION(bool, operator==, __gmp_binary_equal)
4850: __GMP_DEFINE_BINARY_TYPE_FUNCTION(bool, operator!=, __gmp_binary_not_equal)
4851: __GMP_DEFINE_BINARY_TYPE_FUNCTION(bool, operator<, __gmp_binary_less)
4852: __GMP_DEFINE_BINARY_TYPE_FUNCTION(bool, operator<=, __gmp_binary_less_equal)
4853: __GMP_DEFINE_BINARY_TYPE_FUNCTION(bool, operator>, __gmp_binary_greater)
4854: __GMP_DEFINE_BINARY_TYPE_FUNCTION(bool, operator>=, \
4855: __gmp_binary_greater_equal)
4856:
4857: __GMP_DEFINE_UNARY_FUNCTION(abs, __gmp_abs_function)
4858: __GMP_DEFINE_UNARY_FUNCTION(trunc, __gmp_trunc_function)
4859: __GMP_DEFINE_UNARY_FUNCTION(floor, __gmp_floor_function)
4860: __GMP_DEFINE_UNARY_FUNCTION(ceil, __gmp_ceil_function)
4861: __GMP_DEFINE_UNARY_FUNCTION(sqrt, __gmp_sqrt_function)
4862: __GMP_DEFINE_BINARY_FUNCTION(hypot, __gmp_hypot_function)
4863:
4864: __GMP_DEFINE_UNARY_TYPE_FUNCTION(int, sgn, __gmp_sgn_function)
4865: __GMP_DEFINE_BINARY_TYPE_FUNCTION(int, cmp, __gmp_cmp_function)
4866:
4867: // member operators for mpz_class
4868:
4869: __GMPZ_DEFINE_COMPOUND_OPERATOR(operator+=, __gmp_binary_plus)
4870: __GMPZ_DEFINE_COMPOUND_OPERATOR(operator-=, __gmp_binary_minus)
4871: __GMPZ_DEFINE_COMPOUND_OPERATOR(operator*=, __gmp_binary_multiplies)
4872: __GMPZ_DEFINE_COMPOUND_OPERATOR(operator/=, __gmp_binary_divides)
4873: __GMPZ_DEFINE_COMPOUND_OPERATOR(operator%=, __gmp_binary_modulus)
4874:
4875: __GMPZZ_DEFINE_COMPOUND_OPERATOR(operator&=, __gmp_binary_and)
4876: __GMPZZ_DEFINE_COMPOUND_OPERATOR(operator|=, __gmp_binary_ior)
4877: __GMPZZ_DEFINE_COMPOUND_OPERATOR(operator^=, __gmp_binary_xor)
4878:
4879: __GMPZ_DEFINE_COMPOUND_OPERATOR_UI(operator<<=, __gmp_binary_lshift)
4880: __GMPZ_DEFINE_COMPOUND_OPERATOR_UI(operator>>=, __gmp_binary_rshift)
4881:
4882: __GMPZ_DEFINE_INCREMENT_OPERATOR(operator++, __gmp_unary_increment)
4883: __GMPZ_DEFINE_INCREMENT_OPERATOR(operator--, __gmp_unary_decrement)
4884:
4885: // member operators for mpz_classref
4886:
4887: __GMPZR_DEFINE_COMPOUND_OPERATOR(operator+=, __gmp_binary_plus)
4888: __GMPZR_DEFINE_COMPOUND_OPERATOR(operator-=, __gmp_binary_minus)
4889: __GMPZR_DEFINE_COMPOUND_OPERATOR(operator*=, __gmp_binary_multiplies)
4890: __GMPZR_DEFINE_COMPOUND_OPERATOR(operator/=, __gmp_binary_divides)
4891: __GMPZR_DEFINE_COMPOUND_OPERATOR(operator%=, __gmp_binary_modulus)
4892:
4893: __GMPZRR_DEFINE_COMPOUND_OPERATOR(operator&=, __gmp_binary_and)
4894: __GMPZRR_DEFINE_COMPOUND_OPERATOR(operator|=, __gmp_binary_ior)
4895: __GMPZRR_DEFINE_COMPOUND_OPERATOR(operator^=, __gmp_binary_xor)
4896:
4897: __GMPZR_DEFINE_COMPOUND_OPERATOR_UI(operator<<=, __gmp_binary_lshift)
4898: __GMPZR_DEFINE_COMPOUND_OPERATOR_UI(operator>>=, __gmp_binary_rshift)
4899:
4900: __GMPZR_DEFINE_INCREMENT_OPERATOR(operator++, __gmp_unary_increment)
4901: __GMPZR_DEFINE_INCREMENT_OPERATOR(operator--, __gmp_unary_decrement)
4902:
4903: // member operators for mpq_class
4904:
4905: __GMPQ_DEFINE_COMPOUND_OPERATOR(operator+=, __gmp_binary_plus)
4906: __GMPQ_DEFINE_COMPOUND_OPERATOR(operator-=, __gmp_binary_minus)
4907: __GMPQ_DEFINE_COMPOUND_OPERATOR(operator*=, __gmp_binary_multiplies)
4908: __GMPQ_DEFINE_COMPOUND_OPERATOR(operator/=, __gmp_binary_divides)
4909:
4910: __GMPQ_DEFINE_COMPOUND_OPERATOR_UI(operator<<=, __gmp_binary_lshift)
4911: __GMPQ_DEFINE_COMPOUND_OPERATOR_UI(operator>>=, __gmp_binary_rshift)
4912:
4913: __GMPQ_DEFINE_INCREMENT_OPERATOR(operator++, __gmp_unary_increment)
4914: __GMPQ_DEFINE_INCREMENT_OPERATOR(operator--, __gmp_unary_decrement)
4915:
4916: // member operators for mpf_class
4917:
4918: __GMPF_DEFINE_COMPOUND_OPERATOR(operator+=, __gmp_binary_plus)
4919: __GMPF_DEFINE_COMPOUND_OPERATOR(operator-=, __gmp_binary_minus)
4920: __GMPF_DEFINE_COMPOUND_OPERATOR(operator*=, __gmp_binary_multiplies)
4921: __GMPF_DEFINE_COMPOUND_OPERATOR(operator/=, __gmp_binary_divides)
4922:
4923: __GMPF_DEFINE_COMPOUND_OPERATOR_UI(operator<<=, __gmp_binary_lshift)
4924: __GMPF_DEFINE_COMPOUND_OPERATOR_UI(operator>>=, __gmp_binary_rshift)
4925:
4926: __GMPF_DEFINE_INCREMENT_OPERATOR(operator++, __gmp_unary_increment)
4927: __GMPF_DEFINE_INCREMENT_OPERATOR(operator--, __gmp_unary_decrement)
4928:
4929:
4930: /**************** Class wrapper for gmp_randstate_t ****************/
4931:
4932: class __gmp_urandomb_value { };
4933: class __gmp_urandomm_value { };
4934:
4935: template <>
4936: class __gmp_expr<__gmpz_value, __gmp_urandomb_value>
4937: {
4938: private:
4939: __gmp_randstate_struct *state;
4940: unsigned long int bits;
4941: public:
4942: __gmp_expr(gmp_randstate_t s, unsigned long int l) : state(s), bits(l) { }
4943: void eval(mpz_ptr z) const { __gmp_rand_function::eval(z, state, bits); }
4944: unsigned long int get_prec() const { return mpf_get_default_prec(); }
4945: };
4946:
4947: template <>
4948: class __gmp_expr<__gmpz_value, __gmp_urandomm_value>
4949: {
4950: private:
4951: __gmp_randstate_struct *state;
4952: mpz_class range;
4953: public:
4954: __gmp_expr(gmp_randstate_t s, const mpz_class &z) : state(s), range(z) { }
4955: void eval(mpz_ptr z) const
4956: { __gmp_rand_function::eval(z, state, range.get_mpz_t()); }
4957: unsigned long int get_prec() const { return mpf_get_default_prec(); }
4958: };
4959:
4960: template <>
4961: class __gmp_expr<__gmpf_value, __gmp_urandomb_value>
4962: {
4963: private:
4964: __gmp_randstate_struct *state;
4965: unsigned long int bits;
4966: public:
4967: __gmp_expr(gmp_randstate_t s, unsigned long int l) : state(s), bits(l) { }
4968: void eval(mpf_ptr f, unsigned long int prec) const
4969: { __gmp_rand_function::eval(f, state, (bits>0) ? get_prec() : prec); }
4970: unsigned long int get_prec() const
4971: {
4972: if (bits == 0)
4973: return mpf_get_default_prec();
4974: else
4975: return bits;
4976: }
4977: };
4978:
4979: extern "C" {
4980: typedef void __gmp_randinit_default_t (gmp_randstate_t);
4981: typedef void __gmp_randinit_lc_2exp_t (gmp_randstate_t, mpz_srcptr, unsigned long int, unsigned long int);
4982: typedef int __gmp_randinit_lc_2exp_size_t (gmp_randstate_t, unsigned long int);
4983: }
4984:
4985: class gmp_randclass
4986: {
4987: private:
4988: gmp_randstate_t state;
4989: gmp_randclass(const gmp_randclass &); // copy constructor not allowed
4990: void operator=(const gmp_randclass &); // copying with assignment not allowed
4991: public:
4992: // constructors and destructor
4993: gmp_randclass(gmp_randalg_t alg, unsigned long int size)
4994: {
4995: switch (alg)
4996: {
4997: case GMP_RAND_ALG_LC: // no other cases for now
4998: default:
4999: gmp_randinit(state, alg, size);
5000: break;
5001: }
5002: }
5003:
5004: // gmp_randinit_default
5005: gmp_randclass(__gmp_randinit_default_t* f)
5006: { f(state); }
5007:
5008: // gmp_randinit_lc_2exp
5009: gmp_randclass(__gmp_randinit_lc_2exp_t* f,
5010: mpz_class z, unsigned long int l1, unsigned long int l2)
5011: { f(state, z.get_mpz_t(), l1, l2); }
5012:
5013: // gmp_randinit_lc_2exp_size
5014: gmp_randclass(__gmp_randinit_lc_2exp_size_t* f,
5015: unsigned long int size)
5016: { f(state, size); }
5017:
5018: ~gmp_randclass() { gmp_randclear(state); }
5019:
5020: // initialize
5021: void seed(); // choose a random seed some way (?)
5022: void seed(unsigned long int s) { gmp_randseed_ui(state, s); }
5023: void seed(const mpz_class &z) { gmp_randseed(state, z.get_mpz_t()); }
5024:
5025: // get random number
5026: __gmp_expr<__gmpz_value, __gmp_urandomb_value>
5027: get_z_bits(unsigned long int l)
5028: { return __gmp_expr<__gmpz_value, __gmp_urandomb_value>(state, l); }
5029: __gmp_expr<__gmpz_value, __gmp_urandomb_value>
5030: get_z_bits(const mpz_class &z)
5031: { return get_z_bits(z.get_ui()); }
5032:
5033: __gmp_expr<__gmpz_value, __gmp_urandomm_value>
5034: get_z_range(const mpz_class &z)
5035: { return __gmp_expr<__gmpz_value, __gmp_urandomm_value>(state, z); }
5036: __gmp_expr<__gmpf_value, __gmp_urandomb_value>
5037: get_f(unsigned long int prec = 0)
5038: { return __gmp_expr<__gmpf_value, __gmp_urandomb_value>(state, prec); }
5039: };
5040:
5041:
5042: /**************** #undef all private macros ****************/
5043:
5044: #undef __GMPZQ_DEFINE_EXPR
5045:
5046: #undef __GMP_DEFINE_UNARY_FUNCTION
5047: #undef __GMP_DEFINE_BINARY_FUNCTION
5048: #undef __GMP_DEFINE_BINARY_FUNCTION_UI
5049: #undef __GMP_DEFINE_UNARY_TYPE_FUNCTION
5050: #undef __GMP_DEFINE_BINARY_TYPE_FUNCTION
5051:
5052: #undef __GMPZZ_DECLARE_COMPOUND_OPERATOR
5053: #undef __GMPZN_DECLARE_COMPOUND_OPERATOR
5054: #undef __GMPZ_DECLARE_COMPOUND_OPERATOR
5055: #undef __GMPZ_DECLARE_COMPOUND_OPERATOR_UI
5056: #undef __GMPZ_DECLARE_INCREMENT_OPERATOR
5057:
5058: #undef __GMPZZ_DEFINE_COMPOUND_OPERATOR
5059: #undef __GMPZN_DEFINE_COMPOUND_OPERATOR
5060: #undef __GMPZ_DEFINE_COMPOUND_OPERATOR
5061: #undef __GMPZ_DEFINE_COMPOUND_OPERATOR_UI
5062: #undef __GMPZ_DEFINE_INCREMENT_OPERATOR
5063:
5064: #undef __GMPZRR_DECLARE_COMPOUND_OPERATOR
5065: #undef __GMPZRN_DECLARE_COMPOUND_OPERATOR
5066: #undef __GMPZR_DECLARE_COMPOUND_OPERATOR
5067: #undef __GMPZR_DECLARE_COMPOUND_OPERATOR_UI
5068: #undef __GMPZR_DECLARE_INCREMENT_OPERATOR
5069:
5070: #undef __GMPZRR_DEFINE_COMPOUND_OPERATOR
5071: #undef __GMPZRN_DEFINE_COMPOUND_OPERATOR
5072: #undef __GMPZR_DEFINE_COMPOUND_OPERATOR
5073: #undef __GMPZR_DEFINE_COMPOUND_OPERATOR_UI
5074: #undef __GMPZR_DEFINE_INCREMENT_OPERATOR
5075:
5076: #undef __GMPQQ_DECLARE_COMPOUND_OPERATOR
5077: #undef __GMPQN_DECLARE_COMPOUND_OPERATOR
5078: #undef __GMPQ_DECLARE_COMPOUND_OPERATOR
5079: #undef __GMPQ_DECLARE_COMPOUND_OPERATOR_UI
5080: #undef __GMPQ_DECLARE_INCREMENT_OPERATOR
5081:
5082: #undef __GMPQQ_DEFINE_COMPOUND_OPERATOR
5083: #undef __GMPQN_DEFINE_COMPOUND_OPERATOR
5084: #undef __GMPQ_DEFINE_COMPOUND_OPERATOR
5085: #undef __GMPQ_DEFINE_COMPOUND_OPERATOR_UI
5086: #undef __GMPQ_DEFINE_INCREMENT_OPERATOR
5087:
5088: #undef __GMPFF_DECLARE_COMPOUND_OPERATOR
5089: #undef __GMPFN_DECLARE_COMPOUND_OPERATOR
5090: #undef __GMPF_DECLARE_COMPOUND_OPERATOR
5091: #undef __GMPF_DECLARE_COMPOUND_OPERATOR_UI
5092: #undef __GMPF_DECLARE_INCREMENT_OPERATOR
5093:
5094: #undef __GMPFF_DEFINE_COMPOUND_OPERATOR
5095: #undef __GMPFN_DEFINE_COMPOUND_OPERATOR
5096: #undef __GMPF_DEFINE_COMPOUND_OPERATOR
5097: #undef __GMPF_DEFINE_COMPOUND_OPERATOR_UI
5098: #undef __GMPF_DEFINE_INCREMENT_OPERATOR
5099:
5100:
5101: #endif /* __GMP_PLUSPLUS__ */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>