[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     ! 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>