[BACK]Return to gmpxx.h CVS log [TXT][DIR] Up to [local] / OpenXM_contrib / gmp

Annotation of OpenXM_contrib/gmp/gmpxx.h, Revision 1.1.1.1

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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>