source: trunk/third/gmp/gmpxx.h @ 22254

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