~ubuntu-branches/ubuntu/quantal/gclcvs/quantal

« back to all changes in this revision

Viewing changes to gmp3/gmpxx.h

  • Committer: Bazaar Package Importer
  • Author(s): Camm Maguire
  • Date: 2004-06-24 15:13:46 UTC
  • Revision ID: james.westby@ubuntu.com-20040624151346-xh0xaaktyyp7aorc
Tags: 2.7.0-26
C_GC_OFFSET is 2 on m68k-linux

Show diffs side-by-side

added added

removed removed

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