Annotation of OpenXM_contrib2/windows/mpir/gmpxx.h, Revision 1.1
1.1 ! ohara 1: /* mpirxx.h -- C++ class wrapper for GMP types. -*- C++ -*-
! 2:
! 3: Copyright 2001, 2002, 2003, 2006, 2008 Free Software Foundation, Inc.
! 4:
! 5: Copyright 2009 William Hart
! 6:
! 7: This file is part of the GNU MP Library.
! 8:
! 9: The GNU MP Library is free software; you can redistribute it and/or modify
! 10: it under the terms of the GNU Lesser General Public License as published by
! 11: the Free Software Foundation; either version 3 of the License, or (at your
! 12: option) any later version.
! 13:
! 14: The GNU MP Library is distributed in the hope that it will be useful, but
! 15: WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
! 16: or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
! 17: License for more details.
! 18:
! 19: You should have received a copy of the GNU Lesser General Public License
! 20: along with the GNU MP Library. If not, see http://www.gnu.org/licenses/. */
! 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 mpirxx.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:
! 39: #include <cstring> /* for strlen */
! 40: #include <string>
! 41: #include <stdexcept>
! 42: #include <cfloat>
! 43:
! 44: #include <gmp.h>
! 45:
! 46: #include <climits>
! 47:
! 48: #ifdef LLONG_MAX
! 49: #if LLONG_MAX != LONG_MAX
! 50: #define MPIRXX_HAVE_LLONG 1
! 51: #endif
! 52: #endif
! 53:
! 54: /**************** Function objects ****************/
! 55: /* Any evaluation of a __gmp_expr ends up calling one of these functions
! 56: all intermediate functions being inline, the evaluation should optimize
! 57: to a direct call to the relevant function, thus yielding no overhead
! 58: over the C interface. */
! 59:
! 60: struct __gmp_unary_plus
! 61: {
! 62: static void eval(mpz_ptr z, mpz_srcptr w) { mpz_set(z, w); }
! 63: static void eval(mpq_ptr q, mpq_srcptr r) { mpq_set(q, r); }
! 64: static void eval(mpf_ptr f, mpf_srcptr g) { mpf_set(f, g); }
! 65: };
! 66:
! 67: struct __gmp_unary_minus
! 68: {
! 69: static void eval(mpz_ptr z, mpz_srcptr w) { mpz_neg(z, w); }
! 70: static void eval(mpq_ptr q, mpq_srcptr r) { mpq_neg(q, r); }
! 71: static void eval(mpf_ptr f, mpf_srcptr g) { mpf_neg(f, g); }
! 72: };
! 73:
! 74: struct __gmp_unary_com
! 75: {
! 76: static void eval(mpz_ptr z, mpz_srcptr w) { mpz_com(z, w); }
! 77: };
! 78:
! 79: struct __gmp_binary_plus
! 80: {
! 81: static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v)
! 82: { mpz_add(z, w, v); }
! 83:
! 84: static void eval(mpz_ptr z, mpz_srcptr w, mpir_ui l)
! 85: { mpz_add_ui(z, w, l); }
! 86: static void eval(mpz_ptr z, mpir_ui l, mpz_srcptr w)
! 87: { mpz_add_ui(z, w, l); }
! 88: static void eval(mpz_ptr z, mpz_srcptr w, mpir_si l)
! 89: {
! 90: if (l >= 0)
! 91: mpz_add_ui(z, w, l);
! 92: else
! 93: mpz_sub_ui(z, w, -l);
! 94: }
! 95: static void eval(mpz_ptr z, mpir_si l, mpz_srcptr w)
! 96: {
! 97: if (l >= 0)
! 98: mpz_add_ui(z, w, l);
! 99: else
! 100: mpz_sub_ui(z, w, -l);
! 101: }
! 102: static void eval(mpz_ptr z, mpz_srcptr w, double d)
! 103: {
! 104: mpz_t temp;
! 105: mpz_init_set_d(temp, d);
! 106: mpz_add(z, w, temp);
! 107: mpz_clear(temp);
! 108: }
! 109: static void eval(mpz_ptr z, double d, mpz_srcptr w)
! 110: {
! 111: mpz_t temp;
! 112: mpz_init_set_d(temp, d);
! 113: mpz_add(z, temp, w);
! 114: mpz_clear(temp);
! 115: }
! 116:
! 117: static void eval(mpq_ptr q, mpq_srcptr r, mpq_srcptr s)
! 118: { mpq_add(q, r, s); }
! 119:
! 120: static void eval(mpq_ptr q, mpq_srcptr r, mpir_ui l)
! 121: { mpq_set(q, r); mpz_addmul_ui(mpq_numref(q), mpq_denref(q), l); }
! 122: static void eval(mpq_ptr q, mpir_ui l, mpq_srcptr r)
! 123: { mpq_set(q, r); mpz_addmul_ui(mpq_numref(q), mpq_denref(q), l); }
! 124: static void eval(mpq_ptr q, mpq_srcptr r, mpir_si l)
! 125: {
! 126: mpq_set(q, r);
! 127: if (l >= 0)
! 128: mpz_addmul_ui(mpq_numref(q), mpq_denref(q), l);
! 129: else
! 130: mpz_submul_ui(mpq_numref(q), mpq_denref(q), -l);
! 131: }
! 132: static void eval(mpq_ptr q, mpir_si l, mpq_srcptr r)
! 133: {
! 134: mpq_set(q, r);
! 135: if (l >= 0)
! 136: mpz_addmul_ui(mpq_numref(q), mpq_denref(q), l);
! 137: else
! 138: mpz_submul_ui(mpq_numref(q), mpq_denref(q), -l);
! 139: }
! 140: static void eval(mpq_ptr q, mpq_srcptr r, double d)
! 141: {
! 142: mpq_t temp;
! 143: mpq_init(temp);
! 144: mpq_set_d(temp, d);
! 145: mpq_add(q, r, temp);
! 146: mpq_clear(temp);
! 147: }
! 148: static void eval(mpq_ptr q, double d, mpq_srcptr r)
! 149: {
! 150: mpq_t temp;
! 151: mpq_init(temp);
! 152: mpq_set_d(temp, d);
! 153: mpq_add(q, temp, r);
! 154: mpq_clear(temp);
! 155: }
! 156:
! 157: static void eval(mpq_ptr q, mpq_srcptr r, mpz_srcptr z)
! 158: { mpq_set(q, r); mpz_addmul(mpq_numref(q), mpq_denref(q), z); }
! 159: static void eval(mpq_ptr q, mpz_srcptr z, mpq_srcptr r)
! 160: { mpq_set(q, r); mpz_addmul(mpq_numref(q), mpq_denref(q), z); }
! 161:
! 162: static void eval(mpf_ptr f, mpf_srcptr g, mpf_srcptr h)
! 163: { mpf_add(f, g, h); }
! 164:
! 165: static void eval(mpf_ptr f, mpf_srcptr g, mpir_ui l)
! 166: { mpf_add_ui(f, g, l); }
! 167: static void eval(mpf_ptr f, mpir_ui l, mpf_srcptr g)
! 168: { mpf_add_ui(f, g, l); }
! 169: static void eval(mpf_ptr f, mpf_srcptr g, mpir_si l)
! 170: {
! 171: if (l >= 0)
! 172: mpf_add_ui(f, g, l);
! 173: else
! 174: mpf_sub_ui(f, g, -l);
! 175: }
! 176: static void eval(mpf_ptr f, mpir_si l, mpf_srcptr g)
! 177: {
! 178: if (l >= 0)
! 179: mpf_add_ui(f, g, l);
! 180: else
! 181: mpf_sub_ui(f, g, -l);
! 182: }
! 183: static void eval(mpf_ptr f, mpf_srcptr g, double d)
! 184: {
! 185: mpf_t temp;
! 186: mpf_init2(temp, 8*sizeof(double));
! 187: mpf_set_d(temp, d);
! 188: mpf_add(f, g, temp);
! 189: mpf_clear(temp);
! 190: }
! 191: static void eval(mpf_ptr f, double d, mpf_srcptr g)
! 192: {
! 193: mpf_t temp;
! 194: mpf_init2(temp, 8*sizeof(double));
! 195: mpf_set_d(temp, d);
! 196: mpf_add(f, temp, g);
! 197: mpf_clear(temp);
! 198: }
! 199: };
! 200:
! 201: struct __gmp_binary_minus
! 202: {
! 203: static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v)
! 204: { mpz_sub(z, w, v); }
! 205:
! 206: static void eval(mpz_ptr z, mpz_srcptr w, mpir_ui l)
! 207: { mpz_sub_ui(z, w, l); }
! 208: static void eval(mpz_ptr z, mpir_ui l, mpz_srcptr w)
! 209: { mpz_ui_sub(z, l, w); }
! 210: static void eval(mpz_ptr z, mpz_srcptr w, mpir_si l)
! 211: {
! 212: if (l >= 0)
! 213: mpz_sub_ui(z, w, l);
! 214: else
! 215: mpz_add_ui(z, w, -l);
! 216: }
! 217: static void eval(mpz_ptr z, mpir_si l, mpz_srcptr w)
! 218: {
! 219: if (l >= 0)
! 220: mpz_ui_sub(z, l, w);
! 221: else
! 222: {
! 223: mpz_add_ui(z, w, -l);
! 224: mpz_neg(z, z);
! 225: }
! 226: }
! 227: static void eval(mpz_ptr z, mpz_srcptr w, double d)
! 228: {
! 229: mpz_t temp;
! 230: mpz_init_set_d(temp, d);
! 231: mpz_sub(z, w, temp);
! 232: mpz_clear(temp);
! 233: }
! 234: static void eval(mpz_ptr z, double d, mpz_srcptr w)
! 235: {
! 236: mpz_t temp;
! 237: mpz_init_set_d(temp, d);
! 238: mpz_sub(z, temp, w);
! 239: mpz_clear(temp);
! 240: }
! 241:
! 242: static void eval(mpq_ptr q, mpq_srcptr r, mpq_srcptr s)
! 243: { mpq_sub(q, r, s); }
! 244:
! 245: static void eval(mpq_ptr q, mpq_srcptr r, mpir_ui l)
! 246: { mpq_set(q, r); mpz_submul_ui(mpq_numref(q), mpq_denref(q), l); }
! 247: static void eval(mpq_ptr q, mpir_ui l, mpq_srcptr r)
! 248: { mpq_neg(q, r); mpz_addmul_ui(mpq_numref(q), mpq_denref(q), l); }
! 249: static void eval(mpq_ptr q, mpq_srcptr r, mpir_si l)
! 250: {
! 251: mpq_set(q, r);
! 252: if (l >= 0)
! 253: mpz_submul_ui(mpq_numref(q), mpq_denref(q), l);
! 254: else
! 255: mpz_addmul_ui(mpq_numref(q), mpq_denref(q), -l);
! 256: }
! 257: static void eval(mpq_ptr q, mpir_si l, mpq_srcptr r)
! 258: {
! 259: mpq_neg(q, r);
! 260: if (l >= 0)
! 261: mpz_addmul_ui(mpq_numref(q), mpq_denref(q), l);
! 262: else
! 263: mpz_submul_ui(mpq_numref(q), mpq_denref(q), -l);
! 264: }
! 265: static void eval(mpq_ptr q, mpq_srcptr r, double d)
! 266: {
! 267: mpq_t temp;
! 268: mpq_init(temp);
! 269: mpq_set_d(temp, d);
! 270: mpq_sub(q, r, temp);
! 271: mpq_clear(temp);
! 272: }
! 273: static void eval(mpq_ptr q, double d, mpq_srcptr r)
! 274: {
! 275: mpq_t temp;
! 276: mpq_init(temp);
! 277: mpq_set_d(temp, d);
! 278: mpq_sub(q, temp, r);
! 279: mpq_clear(temp);
! 280: }
! 281:
! 282: static void eval(mpq_ptr q, mpq_srcptr r, mpz_srcptr z)
! 283: { mpq_set(q, r); mpz_submul(mpq_numref(q), mpq_denref(q), z); }
! 284: static void eval(mpq_ptr q, mpz_srcptr z, mpq_srcptr r)
! 285: { mpq_neg(q, r); mpz_addmul(mpq_numref(q), mpq_denref(q), z); }
! 286:
! 287: static void eval(mpf_ptr f, mpf_srcptr g, mpf_srcptr h)
! 288: { mpf_sub(f, g, h); }
! 289:
! 290: static void eval(mpf_ptr f, mpf_srcptr g, mpir_ui l)
! 291: { mpf_sub_ui(f, g, l); }
! 292: static void eval(mpf_ptr f, mpir_ui l, mpf_srcptr g)
! 293: { mpf_ui_sub(f, l, g); }
! 294: static void eval(mpf_ptr f, mpf_srcptr g, mpir_si l)
! 295: {
! 296: if (l >= 0)
! 297: mpf_sub_ui(f, g, l);
! 298: else
! 299: mpf_add_ui(f, g, -l);
! 300: }
! 301: static void eval(mpf_ptr f, mpir_si l, mpf_srcptr g)
! 302: {
! 303: if (l >= 0)
! 304: mpf_sub_ui(f, g, l);
! 305: else
! 306: mpf_add_ui(f, g, -l);
! 307: mpf_neg(f, f);
! 308: }
! 309: static void eval(mpf_ptr f, mpf_srcptr g, double d)
! 310: {
! 311: mpf_t temp;
! 312: mpf_init2(temp, 8*sizeof(double));
! 313: mpf_set_d(temp, d);
! 314: mpf_sub(f, g, temp);
! 315: mpf_clear(temp);
! 316: }
! 317: static void eval(mpf_ptr f, double d, mpf_srcptr g)
! 318: {
! 319: mpf_t temp;
! 320: mpf_init2(temp, 8*sizeof(double));
! 321: mpf_set_d(temp, d);
! 322: mpf_sub(f, temp, g);
! 323: mpf_clear(temp);
! 324: }
! 325: };
! 326:
! 327: struct __gmp_binary_multiplies
! 328: {
! 329: static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v)
! 330: { mpz_mul(z, w, v); }
! 331:
! 332: static void eval(mpz_ptr z, mpz_srcptr w, mpir_ui l)
! 333: { mpz_mul_ui(z, w, l); }
! 334: static void eval(mpz_ptr z, mpir_ui l, mpz_srcptr w)
! 335: { mpz_mul_ui(z, w, l); }
! 336: static void eval(mpz_ptr z, mpz_srcptr w, mpir_si l)
! 337: { mpz_mul_si (z, w, l); }
! 338: static void eval(mpz_ptr z, mpir_si l, mpz_srcptr w)
! 339: { mpz_mul_si (z, w, l); }
! 340: static void eval(mpz_ptr z, mpz_srcptr w, double d)
! 341: {
! 342: mpz_t temp;
! 343: mpz_init_set_d(temp, d);
! 344: mpz_mul(z, w, temp);
! 345: mpz_clear(temp);
! 346: }
! 347: static void eval(mpz_ptr z, double d, mpz_srcptr w)
! 348: {
! 349: mpz_t temp;
! 350: mpz_init_set_d(temp, d);
! 351: mpz_mul(z, temp, w);
! 352: mpz_clear(temp);
! 353: }
! 354:
! 355: static void eval(mpq_ptr q, mpq_srcptr r, mpq_srcptr s)
! 356: { mpq_mul(q, r, s); }
! 357:
! 358: static void eval(mpq_ptr q, mpq_srcptr r, mpir_ui l)
! 359: {
! 360: mpq_t temp;
! 361: mpq_init(temp);
! 362: mpq_set_ui(temp, l, 1);
! 363: mpq_mul(q, r, temp);
! 364: mpq_clear(temp);
! 365: }
! 366: static void eval(mpq_ptr q, mpir_ui l, mpq_srcptr r)
! 367: {
! 368: mpq_t temp;
! 369: mpq_init(temp);
! 370: mpq_set_ui(temp, l, 1);
! 371: mpq_mul(q, temp, r);
! 372: mpq_clear(temp);
! 373: }
! 374: static void eval(mpq_ptr q, mpq_srcptr r, mpir_si l)
! 375: {
! 376: mpq_t temp;
! 377: mpq_init(temp);
! 378: mpq_set_si(temp, l, 1);
! 379: mpq_mul(q, r, temp);
! 380: mpq_clear(temp);
! 381: }
! 382: static void eval(mpq_ptr q, mpir_si l, mpq_srcptr r)
! 383: {
! 384: mpq_t temp;
! 385: mpq_init(temp);
! 386: mpq_set_si(temp, l, 1);
! 387: mpq_mul(q, temp, r);
! 388: mpq_clear(temp);
! 389: }
! 390: static void eval(mpq_ptr q, mpq_srcptr r, double d)
! 391: {
! 392: mpq_t temp;
! 393: mpq_init(temp);
! 394: mpq_set_d(temp, d);
! 395: mpq_mul(q, r, temp);
! 396: mpq_clear(temp);
! 397: }
! 398: static void eval(mpq_ptr q, double d, mpq_srcptr r)
! 399: {
! 400: mpq_t temp;
! 401: mpq_init(temp);
! 402: mpq_set_d(temp, d);
! 403: mpq_mul(q, temp, r);
! 404: mpq_clear(temp);
! 405: }
! 406:
! 407: static void eval(mpf_ptr f, mpf_srcptr g, mpf_srcptr h)
! 408: { mpf_mul(f, g, h); }
! 409:
! 410: static void eval(mpf_ptr f, mpf_srcptr g, mpir_ui l)
! 411: { mpf_mul_ui(f, g, l); }
! 412: static void eval(mpf_ptr f, mpir_ui l, mpf_srcptr g)
! 413: { mpf_mul_ui(f, g, l); }
! 414: static void eval(mpf_ptr f, mpf_srcptr g, mpir_si l)
! 415: {
! 416: if (l >= 0)
! 417: mpf_mul_ui(f, g, l);
! 418: else
! 419: {
! 420: mpf_mul_ui(f, g, -l);
! 421: mpf_neg(f, f);
! 422: }
! 423: }
! 424: static void eval(mpf_ptr f, mpir_si l, mpf_srcptr g)
! 425: {
! 426: if (l >= 0)
! 427: mpf_mul_ui(f, g, l);
! 428: else
! 429: {
! 430: mpf_mul_ui(f, g, -l);
! 431: mpf_neg(f, f);
! 432: }
! 433: }
! 434: static void eval(mpf_ptr f, mpf_srcptr g, double d)
! 435: {
! 436: mpf_t temp;
! 437: mpf_init2(temp, 8*sizeof(double));
! 438: mpf_set_d(temp, d);
! 439: mpf_mul(f, g, temp);
! 440: mpf_clear(temp);
! 441: }
! 442: static void eval(mpf_ptr f, double d, mpf_srcptr g)
! 443: {
! 444: mpf_t temp;
! 445: mpf_init2(temp, 8*sizeof(double));
! 446: mpf_set_d(temp, d);
! 447: mpf_mul(f, temp, g);
! 448: mpf_clear(temp);
! 449: }
! 450: };
! 451:
! 452: struct __gmp_binary_divides
! 453: {
! 454: static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v)
! 455: { mpz_tdiv_q(z, w, v); }
! 456:
! 457: static void eval(mpz_ptr z, mpz_srcptr w, mpir_ui l)
! 458: { mpz_tdiv_q_ui(z, w, l); }
! 459: static void eval(mpz_ptr z, mpir_ui l, mpz_srcptr w)
! 460: {
! 461: if (mpz_sgn(w) >= 0)
! 462: {
! 463: if (mpz_fits_ui_p(w))
! 464: mpz_set_ui(z, l / mpz_get_ui(w));
! 465: else
! 466: mpz_set_ui(z, 0);
! 467: }
! 468: else
! 469: {
! 470: mpz_neg(z, w);
! 471: if (mpz_fits_ui_p(z))
! 472: {
! 473: mpz_set_ui(z, l / mpz_get_ui(z));
! 474: mpz_neg(z, z);
! 475: }
! 476: else
! 477: mpz_set_ui(z, 0);
! 478: }
! 479: }
! 480: static void eval(mpz_ptr z, mpz_srcptr w, mpir_si l)
! 481: {
! 482: if (l >= 0)
! 483: mpz_tdiv_q_ui(z, w, l);
! 484: else
! 485: {
! 486: mpz_tdiv_q_ui(z, w, -l);
! 487: mpz_neg(z, z);
! 488: }
! 489: }
! 490: static void eval(mpz_ptr z, mpir_si l, mpz_srcptr w)
! 491: {
! 492: if (mpz_fits_si_p(w))
! 493: mpz_set_si(z, l / mpz_get_si(w));
! 494: else
! 495: {
! 496: /* if w is bigger than a long then the quotient must be zero, unless
! 497: l==LONG_MIN and w==-LONG_MIN in which case the quotient is -1 */
! 498: mpz_set_si (z, (mpz_cmpabs_ui (w, (l >= 0 ? l : -l)) == 0 ? -1 : 0));
! 499: }
! 500: }
! 501: static void eval(mpz_ptr z, mpz_srcptr w, double d)
! 502: {
! 503: mpz_t temp;
! 504: mpz_init_set_d(temp, d);
! 505: mpz_tdiv_q(z, w, temp);
! 506: mpz_clear(temp);
! 507: }
! 508: static void eval(mpz_ptr z, double d, mpz_srcptr w)
! 509: {
! 510: mpz_t temp;
! 511: mpz_init_set_d(temp, d);
! 512: mpz_tdiv_q(z, temp, w);
! 513: mpz_clear(temp);
! 514: }
! 515:
! 516: static void eval(mpq_ptr q, mpq_srcptr r, mpq_srcptr s)
! 517: { mpq_div(q, r, s); }
! 518:
! 519: static void eval(mpq_ptr q, mpq_srcptr r, mpir_ui l)
! 520: {
! 521: mpq_t temp;
! 522: mpq_init(temp);
! 523: mpq_set_ui(temp, l, 1);
! 524: mpq_div(q, r, temp);
! 525: mpq_clear(temp);
! 526: }
! 527: static void eval(mpq_ptr q, mpir_ui l, mpq_srcptr r)
! 528: {
! 529: mpq_t temp;
! 530: mpq_init(temp);
! 531: mpq_set_ui(temp, l, 1);
! 532: mpq_div(q, temp, r);
! 533: mpq_clear(temp);
! 534: }
! 535: static void eval(mpq_ptr q, mpq_srcptr r, mpir_si l)
! 536: {
! 537: mpq_t temp;
! 538: mpq_init(temp);
! 539: mpq_set_si(temp, l, 1);
! 540: mpq_div(q, r, temp);
! 541: mpq_clear(temp);
! 542: }
! 543: static void eval(mpq_ptr q, mpir_si l, mpq_srcptr r)
! 544: {
! 545: mpq_t temp;
! 546: mpq_init(temp);
! 547: mpq_set_si(temp, l, 1);
! 548: mpq_div(q, temp, r);
! 549: mpq_clear(temp);
! 550: }
! 551: static void eval(mpq_ptr q, mpq_srcptr r, double d)
! 552: {
! 553: mpq_t temp;
! 554: mpq_init(temp);
! 555: mpq_set_d(temp, d);
! 556: mpq_div(q, r, temp);
! 557: mpq_clear(temp);
! 558: }
! 559: static void eval(mpq_ptr q, double d, mpq_srcptr r)
! 560: {
! 561: mpq_t temp;
! 562: mpq_init(temp);
! 563: mpq_set_d(temp, d);
! 564: mpq_div(q, temp, r);
! 565: mpq_clear(temp);
! 566: }
! 567:
! 568: static void eval(mpf_ptr f, mpf_srcptr g, mpf_srcptr h)
! 569: { mpf_div(f, g, h); }
! 570:
! 571: static void eval(mpf_ptr f, mpf_srcptr g, mpir_ui l)
! 572: { mpf_div_ui(f, g, l); }
! 573: static void eval(mpf_ptr f, mpir_ui l, mpf_srcptr g)
! 574: { mpf_ui_div(f, l, g); }
! 575: static void eval(mpf_ptr f, mpf_srcptr g, mpir_si l)
! 576: {
! 577: if (l >= 0)
! 578: mpf_div_ui(f, g, l);
! 579: else
! 580: {
! 581: mpf_div_ui(f, g, -l);
! 582: mpf_neg(f, f);
! 583: }
! 584: }
! 585: static void eval(mpf_ptr f, mpir_si l, mpf_srcptr g)
! 586: {
! 587: if (l >= 0)
! 588: mpf_ui_div(f, l, g);
! 589: else
! 590: {
! 591: mpf_ui_div(f, -l, g);
! 592: mpf_neg(f, f);
! 593: }
! 594: }
! 595: static void eval(mpf_ptr f, mpf_srcptr g, double d)
! 596: {
! 597: mpf_t temp;
! 598: mpf_init2(temp, 8*sizeof(double));
! 599: mpf_set_d(temp, d);
! 600: mpf_div(f, g, temp);
! 601: mpf_clear(temp);
! 602: }
! 603: static void eval(mpf_ptr f, double d, mpf_srcptr g)
! 604: {
! 605: mpf_t temp;
! 606: mpf_init2(temp, 8*sizeof(double));
! 607: mpf_set_d(temp, d);
! 608: mpf_div(f, temp, g);
! 609: mpf_clear(temp);
! 610: }
! 611: };
! 612:
! 613: struct __gmp_binary_modulus
! 614: {
! 615: static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v)
! 616: { mpz_tdiv_r(z, w, v); }
! 617:
! 618: static void eval(mpz_ptr z, mpz_srcptr w, mpir_ui l)
! 619: { mpz_tdiv_r_ui(z, w, l); }
! 620: static void eval(mpz_ptr z, mpir_ui l, mpz_srcptr w)
! 621: {
! 622: if (mpz_sgn(w) >= 0)
! 623: {
! 624: if (mpz_fits_ui_p(w))
! 625: mpz_set_ui(z, l % mpz_get_ui(w));
! 626: else
! 627: mpz_set_ui(z, l);
! 628: }
! 629: else
! 630: {
! 631: mpz_neg(z, w);
! 632: if (mpz_fits_ui_p(z))
! 633: mpz_set_ui(z, l % mpz_get_ui(z));
! 634: else
! 635: mpz_set_ui(z, l);
! 636: }
! 637: }
! 638: static void eval(mpz_ptr z, mpz_srcptr w, mpir_si l)
! 639: {
! 640: mpz_tdiv_r_ui (z, w, (l >= 0 ? l : -l));
! 641: }
! 642: static void eval(mpz_ptr z, mpir_si l, mpz_srcptr w)
! 643: {
! 644: if (mpz_fits_si_p(w))
! 645: mpz_set_si(z, l % mpz_get_si(w));
! 646: else
! 647: {
! 648: /* if w is bigger than a long then the remainder is l unchanged,
! 649: unless l==LONG_MIN and w==-LONG_MIN in which case it's 0 */
! 650: mpz_set_si (z, mpz_cmpabs_ui (w, (l >= 0 ? l : -l)) == 0 ? 0 : l);
! 651: }
! 652: }
! 653: static void eval(mpz_ptr z, mpz_srcptr w, double d)
! 654: {
! 655: mpz_t temp;
! 656: mpz_init_set_d(temp, d);
! 657: mpz_tdiv_r(z, w, temp);
! 658: mpz_clear(temp);
! 659: }
! 660: static void eval(mpz_ptr z, double d, mpz_srcptr w)
! 661: {
! 662: mpz_t temp;
! 663: mpz_init_set_d(temp, d);
! 664: mpz_tdiv_r(z, temp, w);
! 665: mpz_clear(temp);
! 666: }
! 667: };
! 668:
! 669: // Max allocations for plain types when converted to mpz_t
! 670: #define __GMP_DBL_LIMBS (2 + DBL_MAX_EXP / GMP_NUMB_BITS)
! 671: #define __GMP_ULI_LIMBS (1 + (8 * sizeof (mpir_ui) - 1) / GMP_NUMB_BITS)
! 672:
! 673: #define __GMPXX_TMP_UI \
! 674: mpz_t temp; \
! 675: mp_limb_t limbs[__GMP_ULI_LIMBS]; \
! 676: temp->_mp_d = limbs; \
! 677: temp->_mp_alloc = __GMP_ULI_LIMBS; \
! 678: mpz_set_ui (temp, l)
! 679: #define __GMPXX_TMP_SI \
! 680: mpz_t temp; \
! 681: mp_limb_t limbs[__GMP_ULI_LIMBS]; \
! 682: temp->_mp_d = limbs; \
! 683: temp->_mp_alloc = __GMP_ULI_LIMBS; \
! 684: mpz_set_si (temp, l)
! 685: #define __GMPXX_TMP_D \
! 686: mpz_t temp; \
! 687: mp_limb_t limbs[__GMP_DBL_LIMBS]; \
! 688: temp->_mp_d = limbs; \
! 689: temp->_mp_alloc = __GMP_DBL_LIMBS; \
! 690: mpz_set_d (temp, d)
! 691:
! 692: struct __gmp_binary_and
! 693: {
! 694: static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v)
! 695: { mpz_and(z, w, v); }
! 696:
! 697: static void eval(mpz_ptr z, mpz_srcptr w, mpir_ui l)
! 698: { __GMPXX_TMP_UI; mpz_and (z, w, temp); }
! 699: static void eval(mpz_ptr z, mpir_ui l, mpz_srcptr w)
! 700: { __GMPXX_TMP_UI; mpz_and (z, w, temp); }
! 701: static void eval(mpz_ptr z, mpz_srcptr w, mpir_si l)
! 702: { __GMPXX_TMP_SI; mpz_and (z, w, temp); }
! 703: static void eval(mpz_ptr z, mpir_si l, mpz_srcptr w)
! 704: { __GMPXX_TMP_SI; mpz_and (z, w, temp); }
! 705: static void eval(mpz_ptr z, mpz_srcptr w, double d)
! 706: { __GMPXX_TMP_D; mpz_and (z, w, temp); }
! 707: static void eval(mpz_ptr z, double d, mpz_srcptr w)
! 708: { __GMPXX_TMP_D; mpz_and (z, w, temp); }
! 709: };
! 710:
! 711: struct __gmp_binary_ior
! 712: {
! 713: static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v)
! 714: { mpz_ior(z, w, v); }
! 715: static void eval(mpz_ptr z, mpz_srcptr w, mpir_ui l)
! 716: { __GMPXX_TMP_UI; mpz_ior (z, w, temp); }
! 717: static void eval(mpz_ptr z, mpir_ui l, mpz_srcptr w)
! 718: { __GMPXX_TMP_UI; mpz_ior (z, w, temp); }
! 719: static void eval(mpz_ptr z, mpz_srcptr w, mpir_si l)
! 720: { __GMPXX_TMP_SI; mpz_ior (z, w, temp); }
! 721: static void eval(mpz_ptr z, mpir_si l, mpz_srcptr w)
! 722: { __GMPXX_TMP_SI; mpz_ior (z, w, temp); }
! 723: static void eval(mpz_ptr z, mpz_srcptr w, double d)
! 724: { __GMPXX_TMP_D; mpz_ior (z, w, temp); }
! 725: static void eval(mpz_ptr z, double d, mpz_srcptr w)
! 726: { __GMPXX_TMP_D; mpz_ior (z, w, temp); }
! 727: };
! 728:
! 729: struct __gmp_binary_xor
! 730: {
! 731: static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v)
! 732: { mpz_xor(z, w, v); }
! 733: static void eval(mpz_ptr z, mpz_srcptr w, mpir_ui l)
! 734: { __GMPXX_TMP_UI; mpz_xor (z, w, temp); }
! 735: static void eval(mpz_ptr z, mpir_ui l, mpz_srcptr w)
! 736: { __GMPXX_TMP_UI; mpz_xor (z, w, temp); }
! 737: static void eval(mpz_ptr z, mpz_srcptr w, mpir_si l)
! 738: { __GMPXX_TMP_SI; mpz_xor (z, w, temp); }
! 739: static void eval(mpz_ptr z, mpir_si l, mpz_srcptr w)
! 740: { __GMPXX_TMP_SI; mpz_xor (z, w, temp); }
! 741: static void eval(mpz_ptr z, mpz_srcptr w, double d)
! 742: { __GMPXX_TMP_D; mpz_xor (z, w, temp); }
! 743: static void eval(mpz_ptr z, double d, mpz_srcptr w)
! 744: { __GMPXX_TMP_D; mpz_xor (z, w, temp); }
! 745: };
! 746:
! 747: struct __gmp_binary_lshift
! 748: {
! 749: static void eval(mpz_ptr z, mpz_srcptr w, mpir_ui l)
! 750: { mpz_mul_2exp(z, w, l); }
! 751: static void eval(mpq_ptr q, mpq_srcptr r, mpir_ui l)
! 752: { mpq_mul_2exp(q, r, l); }
! 753: static void eval(mpf_ptr f, mpf_srcptr g, mpir_ui l)
! 754: { mpf_mul_2exp(f, g, l); }
! 755: };
! 756:
! 757: struct __gmp_binary_rshift
! 758: {
! 759: static void eval(mpz_ptr z, mpz_srcptr w, mpir_ui l)
! 760: { mpz_fdiv_q_2exp(z, w, l); }
! 761: static void eval(mpq_ptr q, mpq_srcptr r, mpir_ui l)
! 762: { mpq_div_2exp(q, r, l); }
! 763: static void eval(mpf_ptr f, mpf_srcptr g, mpir_ui l)
! 764: { mpf_div_2exp(f, g, l); }
! 765: };
! 766:
! 767: struct __gmp_binary_equal
! 768: {
! 769: static bool eval(mpz_srcptr z, mpz_srcptr w) { return mpz_cmp(z, w) == 0; }
! 770:
! 771: static bool eval(mpz_srcptr z, mpir_ui l)
! 772: { return mpz_cmp_ui(z, l) == 0; }
! 773: static bool eval(mpir_ui l, mpz_srcptr z)
! 774: { return mpz_cmp_ui(z, l) == 0; }
! 775: static bool eval(mpz_srcptr z, mpir_si l)
! 776: { return mpz_cmp_si(z, l) == 0; }
! 777: static bool eval(mpir_si l, mpz_srcptr z)
! 778: { return mpz_cmp_si(z, l) == 0; }
! 779: static bool eval(mpz_srcptr z, double d)
! 780: { return mpz_cmp_d(z, d) == 0; }
! 781: static bool eval(double d, mpz_srcptr z)
! 782: { return mpz_cmp_d(z, d) == 0; }
! 783:
! 784: static bool eval(mpq_srcptr q, mpq_srcptr r)
! 785: { return mpq_equal(q, r) != 0; }
! 786:
! 787: static bool eval(mpq_srcptr q, mpir_ui l)
! 788: { return mpq_cmp_ui(q, l, 1) == 0; }
! 789: static bool eval(mpir_ui l, mpq_srcptr q)
! 790: { return mpq_cmp_ui(q, l, 1) == 0; }
! 791: static bool eval(mpq_srcptr q, mpir_si l)
! 792: { return mpq_cmp_si(q, l, 1) == 0; }
! 793: static bool eval(mpir_si l, mpq_srcptr q)
! 794: { return mpq_cmp_si(q, l, 1) == 0; }
! 795: static bool eval(mpq_srcptr q, double d)
! 796: {
! 797: bool b;
! 798: mpq_t temp;
! 799: mpq_init(temp);
! 800: mpq_set_d(temp, d);
! 801: b = (mpq_equal(q, temp) != 0);
! 802: mpq_clear(temp);
! 803: return b;
! 804: }
! 805: static bool eval(double d, mpq_srcptr q)
! 806: {
! 807: bool b;
! 808: mpq_t temp;
! 809: mpq_init(temp);
! 810: mpq_set_d(temp, d);
! 811: b = (mpq_equal(temp, q) != 0);
! 812: mpq_clear(temp);
! 813: return b;
! 814: }
! 815:
! 816: static bool eval(mpf_srcptr f, mpf_srcptr g) { return mpf_cmp(f, g) == 0; }
! 817:
! 818: static bool eval(mpf_srcptr f, mpir_ui l)
! 819: { return mpf_cmp_ui(f, l) == 0; }
! 820: static bool eval(mpir_ui l, mpf_srcptr f)
! 821: { return mpf_cmp_ui(f, l) == 0; }
! 822: static bool eval(mpf_srcptr f, mpir_si l)
! 823: { return mpf_cmp_si(f, l) == 0; }
! 824: static bool eval(mpir_si l, mpf_srcptr f)
! 825: { return mpf_cmp_si(f, l) == 0; }
! 826: static bool eval(mpf_srcptr f, double d)
! 827: { return mpf_cmp_d(f, d) == 0; }
! 828: static bool eval(double d, mpf_srcptr f)
! 829: { return mpf_cmp_d(f, d) == 0; }
! 830: };
! 831:
! 832: struct __gmp_binary_not_equal
! 833: {
! 834: static bool eval(mpz_srcptr z, mpz_srcptr w) { return mpz_cmp(z, w) != 0; }
! 835:
! 836: static bool eval(mpz_srcptr z, mpir_ui l)
! 837: { return mpz_cmp_ui(z, l) != 0; }
! 838: static bool eval(mpir_ui l, mpz_srcptr z)
! 839: { return mpz_cmp_ui(z, l) != 0; }
! 840: static bool eval(mpz_srcptr z, mpir_si l)
! 841: { return mpz_cmp_si(z, l) != 0; }
! 842: static bool eval(mpir_si l, mpz_srcptr z)
! 843: { return mpz_cmp_si(z, l) != 0; }
! 844: static bool eval(mpz_srcptr z, double d)
! 845: { return mpz_cmp_d(z, d) != 0; }
! 846: static bool eval(double d, mpz_srcptr z)
! 847: { return mpz_cmp_d(z, d) != 0; }
! 848:
! 849: static bool eval(mpq_srcptr q, mpq_srcptr r)
! 850: { return mpq_equal(q, r) == 0; }
! 851:
! 852: static bool eval(mpq_srcptr q, mpir_ui l)
! 853: { return mpq_cmp_ui(q, l, 1) != 0; }
! 854: static bool eval(mpir_ui l, mpq_srcptr q)
! 855: { return mpq_cmp_ui(q, l, 1) != 0; }
! 856: static bool eval(mpq_srcptr q, mpir_si l)
! 857: { return mpq_cmp_si(q, l, 1) != 0; }
! 858: static bool eval(mpir_si l, mpq_srcptr q)
! 859: { return mpq_cmp_si(q, l, 1) != 0; }
! 860: static bool eval(mpq_srcptr q, double d)
! 861: {
! 862: bool b;
! 863: mpq_t temp;
! 864: mpq_init(temp);
! 865: mpq_set_d(temp, d);
! 866: b = (mpq_equal(q, temp) == 0);
! 867: mpq_clear(temp);
! 868: return b;
! 869: }
! 870: static bool eval(double d, mpq_srcptr q)
! 871: {
! 872: bool b;
! 873: mpq_t temp;
! 874: mpq_init(temp);
! 875: mpq_set_d(temp, d);
! 876: b = (mpq_equal(temp, q) == 0);
! 877: mpq_clear(temp);
! 878: return b;
! 879: }
! 880:
! 881: static bool eval(mpf_srcptr f, mpf_srcptr g) { return mpf_cmp(f, g) != 0; }
! 882:
! 883: static bool eval(mpf_srcptr f, mpir_ui l)
! 884: { return mpf_cmp_ui(f, l) != 0; }
! 885: static bool eval(mpir_ui l, mpf_srcptr f)
! 886: { return mpf_cmp_ui(f, l) != 0; }
! 887: static bool eval(mpf_srcptr f, mpir_si l)
! 888: { return mpf_cmp_si(f, l) != 0; }
! 889: static bool eval(mpir_si l, mpf_srcptr f)
! 890: { return mpf_cmp_si(f, l) != 0; }
! 891: static bool eval(mpf_srcptr f, double d)
! 892: { return mpf_cmp_d(f, d) != 0; }
! 893: static bool eval(double d, mpf_srcptr f)
! 894: { return mpf_cmp_d(f, d) != 0; }
! 895: };
! 896:
! 897: struct __gmp_binary_less
! 898: {
! 899: static bool eval(mpz_srcptr z, mpz_srcptr w) { return mpz_cmp(z, w) < 0; }
! 900:
! 901: static bool eval(mpz_srcptr z, mpir_ui l)
! 902: { return mpz_cmp_ui(z, l) < 0; }
! 903: static bool eval(mpir_ui l, mpz_srcptr z)
! 904: { return mpz_cmp_ui(z, l) > 0; }
! 905: static bool eval(mpz_srcptr z, mpir_si l)
! 906: { return mpz_cmp_si(z, l) < 0; }
! 907: static bool eval(mpir_si l, mpz_srcptr z)
! 908: { return mpz_cmp_si(z, l) > 0; }
! 909: static bool eval(mpz_srcptr z, double d)
! 910: { return mpz_cmp_d(z, d) < 0; }
! 911: static bool eval(double d, mpz_srcptr z)
! 912: { return mpz_cmp_d(z, d) > 0; }
! 913:
! 914: static bool eval(mpq_srcptr q, mpq_srcptr r) { return mpq_cmp(q, r) < 0; }
! 915:
! 916: static bool eval(mpq_srcptr q, mpir_ui l)
! 917: { return mpq_cmp_ui(q, l, 1) < 0; }
! 918: static bool eval(mpir_ui l, mpq_srcptr q)
! 919: { return mpq_cmp_ui(q, l, 1) > 0; }
! 920: static bool eval(mpq_srcptr q, mpir_si l)
! 921: { return mpq_cmp_si(q, l, 1) < 0; }
! 922: static bool eval(mpir_si l, mpq_srcptr q)
! 923: { return mpq_cmp_si(q, l, 1) > 0; }
! 924: static bool eval(mpq_srcptr q, double d)
! 925: {
! 926: bool b;
! 927: mpq_t temp;
! 928: mpq_init(temp);
! 929: mpq_set_d(temp, d);
! 930: b = (mpq_cmp(q, temp) < 0);
! 931: mpq_clear(temp);
! 932: return b;
! 933: }
! 934: static bool eval(double d, mpq_srcptr q)
! 935: {
! 936: bool b;
! 937: mpq_t temp;
! 938: mpq_init(temp);
! 939: mpq_set_d(temp, d);
! 940: b = (mpq_cmp(temp, q) < 0);
! 941: mpq_clear(temp);
! 942: return b;
! 943: }
! 944:
! 945: static bool eval(mpf_srcptr f, mpf_srcptr g) { return mpf_cmp(f, g) < 0; }
! 946:
! 947: static bool eval(mpf_srcptr f, mpir_ui l)
! 948: { return mpf_cmp_ui(f, l) < 0; }
! 949: static bool eval(mpir_ui l, mpf_srcptr f)
! 950: { return mpf_cmp_ui(f, l) > 0; }
! 951: static bool eval(mpf_srcptr f, mpir_si l)
! 952: { return mpf_cmp_si(f, l) < 0; }
! 953: static bool eval(mpir_si l, mpf_srcptr f)
! 954: { return mpf_cmp_si(f, l) > 0; }
! 955: static bool eval(mpf_srcptr f, double d)
! 956: { return mpf_cmp_d(f, d) < 0; }
! 957: static bool eval(double d, mpf_srcptr f)
! 958: { return mpf_cmp_d(f, d) > 0; }
! 959: };
! 960:
! 961: struct __gmp_binary_less_equal
! 962: {
! 963: static bool eval(mpz_srcptr z, mpz_srcptr w) { return mpz_cmp(z, w) <= 0; }
! 964:
! 965: static bool eval(mpz_srcptr z, mpir_ui l)
! 966: { return mpz_cmp_ui(z, l) <= 0; }
! 967: static bool eval(mpir_ui l, mpz_srcptr z)
! 968: { return mpz_cmp_ui(z, l) >= 0; }
! 969: static bool eval(mpz_srcptr z, mpir_si l)
! 970: { return mpz_cmp_si(z, l) <= 0; }
! 971: static bool eval(mpir_si l, mpz_srcptr z)
! 972: { return mpz_cmp_si(z, l) >= 0; }
! 973: static bool eval(mpz_srcptr z, double d)
! 974: { return mpz_cmp_d(z, d) <= 0; }
! 975: static bool eval(double d, mpz_srcptr z)
! 976: { return mpz_cmp_d(z, d) >= 0; }
! 977:
! 978: static bool eval(mpq_srcptr q, mpq_srcptr r) { return mpq_cmp(q, r) <= 0; }
! 979:
! 980: static bool eval(mpq_srcptr q, mpir_ui l)
! 981: { return mpq_cmp_ui(q, l, 1) <= 0; }
! 982: static bool eval(mpir_ui l, mpq_srcptr q)
! 983: { return mpq_cmp_ui(q, l, 1) >= 0; }
! 984: static bool eval(mpq_srcptr q, mpir_si l)
! 985: { return mpq_cmp_si(q, l, 1) <= 0; }
! 986: static bool eval(mpir_si l, mpq_srcptr q)
! 987: { return mpq_cmp_si(q, l, 1) >= 0; }
! 988: static bool eval(mpq_srcptr q, double d)
! 989: {
! 990: bool b;
! 991: mpq_t temp;
! 992: mpq_init(temp);
! 993: mpq_set_d(temp, d);
! 994: b = (mpq_cmp(q, temp) <= 0);
! 995: mpq_clear(temp);
! 996: return b;
! 997: }
! 998: static bool eval(double d, mpq_srcptr q)
! 999: {
! 1000: bool b;
! 1001: mpq_t temp;
! 1002: mpq_init(temp);
! 1003: mpq_set_d(temp, d);
! 1004: b = (mpq_cmp(temp, q) <= 0);
! 1005: mpq_clear(temp);
! 1006: return b;
! 1007: }
! 1008:
! 1009: static bool eval(mpf_srcptr f, mpf_srcptr g) { return mpf_cmp(f, g) <= 0; }
! 1010:
! 1011: static bool eval(mpf_srcptr f, mpir_ui l)
! 1012: { return mpf_cmp_ui(f, l) <= 0; }
! 1013: static bool eval(mpir_ui l, mpf_srcptr f)
! 1014: { return mpf_cmp_ui(f, l) >= 0; }
! 1015: static bool eval(mpf_srcptr f, mpir_si l)
! 1016: { return mpf_cmp_si(f, l) <= 0; }
! 1017: static bool eval(mpir_si l, mpf_srcptr f)
! 1018: { return mpf_cmp_si(f, l) >= 0; }
! 1019: static bool eval(mpf_srcptr f, double d)
! 1020: { return mpf_cmp_d(f, d) <= 0; }
! 1021: static bool eval(double d, mpf_srcptr f)
! 1022: { return mpf_cmp_d(f, d) >= 0; }
! 1023: };
! 1024:
! 1025: struct __gmp_binary_greater
! 1026: {
! 1027: static bool eval(mpz_srcptr z, mpz_srcptr w) { return mpz_cmp(z, w) > 0; }
! 1028:
! 1029: static bool eval(mpz_srcptr z, mpir_ui l)
! 1030: { return mpz_cmp_ui(z, l) > 0; }
! 1031: static bool eval(mpir_ui l, mpz_srcptr z)
! 1032: { return mpz_cmp_ui(z, l) < 0; }
! 1033: static bool eval(mpz_srcptr z, mpir_si l)
! 1034: { return mpz_cmp_si(z, l) > 0; }
! 1035: static bool eval(mpir_si l, mpz_srcptr z)
! 1036: { return mpz_cmp_si(z, l) < 0; }
! 1037: static bool eval(mpz_srcptr z, double d)
! 1038: { return mpz_cmp_d(z, d) > 0; }
! 1039: static bool eval(double d, mpz_srcptr z)
! 1040: { return mpz_cmp_d(z, d) < 0; }
! 1041:
! 1042: static bool eval(mpq_srcptr q, mpq_srcptr r) { return mpq_cmp(q, r) > 0; }
! 1043:
! 1044: static bool eval(mpq_srcptr q, mpir_ui l)
! 1045: { return mpq_cmp_ui(q, l, 1) > 0; }
! 1046: static bool eval(mpir_ui l, mpq_srcptr q)
! 1047: { return mpq_cmp_ui(q, l, 1) < 0; }
! 1048: static bool eval(mpq_srcptr q, mpir_si l)
! 1049: { return mpq_cmp_si(q, l, 1) > 0; }
! 1050: static bool eval(mpir_si l, mpq_srcptr q)
! 1051: { return mpq_cmp_si(q, l, 1) < 0; }
! 1052: static bool eval(mpq_srcptr q, double d)
! 1053: {
! 1054: bool b;
! 1055: mpq_t temp;
! 1056: mpq_init(temp);
! 1057: mpq_set_d(temp, d);
! 1058: b = (mpq_cmp(q, temp) > 0);
! 1059: mpq_clear(temp);
! 1060: return b;
! 1061: }
! 1062: static bool eval(double d, mpq_srcptr q)
! 1063: {
! 1064: bool b;
! 1065: mpq_t temp;
! 1066: mpq_init(temp);
! 1067: mpq_set_d(temp, d);
! 1068: b = (mpq_cmp(temp, q) > 0);
! 1069: mpq_clear(temp);
! 1070: return b;
! 1071: }
! 1072:
! 1073: static bool eval(mpf_srcptr f, mpf_srcptr g) { return mpf_cmp(f, g) > 0; }
! 1074:
! 1075: static bool eval(mpf_srcptr f, mpir_ui l)
! 1076: { return mpf_cmp_ui(f, l) > 0; }
! 1077: static bool eval(mpir_ui l, mpf_srcptr f)
! 1078: { return mpf_cmp_ui(f, l) < 0; }
! 1079: static bool eval(mpf_srcptr f, mpir_si l)
! 1080: { return mpf_cmp_si(f, l) > 0; }
! 1081: static bool eval(mpir_si l, mpf_srcptr f)
! 1082: { return mpf_cmp_si(f, l) < 0; }
! 1083: static bool eval(mpf_srcptr f, double d)
! 1084: { return mpf_cmp_d(f, d) > 0; }
! 1085: static bool eval(double d, mpf_srcptr f)
! 1086: { return mpf_cmp_d(f, d) < 0; }
! 1087: };
! 1088:
! 1089: struct __gmp_binary_greater_equal
! 1090: {
! 1091: static bool eval(mpz_srcptr z, mpz_srcptr w) { return mpz_cmp(z, w) >= 0; }
! 1092:
! 1093: static bool eval(mpz_srcptr z, mpir_ui l)
! 1094: { return mpz_cmp_ui(z, l) >= 0; }
! 1095: static bool eval(mpir_ui l, mpz_srcptr z)
! 1096: { return mpz_cmp_ui(z, l) <= 0; }
! 1097: static bool eval(mpz_srcptr z, mpir_si l)
! 1098: { return mpz_cmp_si(z, l) >= 0; }
! 1099: static bool eval(mpir_si l, mpz_srcptr z)
! 1100: { return mpz_cmp_si(z, l) <= 0; }
! 1101: static bool eval(mpz_srcptr z, double d)
! 1102: { return mpz_cmp_d(z, d) >= 0; }
! 1103: static bool eval(double d, mpz_srcptr z)
! 1104: { return mpz_cmp_d(z, d) <= 0; }
! 1105:
! 1106: static bool eval(mpq_srcptr q, mpq_srcptr r) { return mpq_cmp(q, r) >= 0; }
! 1107:
! 1108: static bool eval(mpq_srcptr q, mpir_ui l)
! 1109: { return mpq_cmp_ui(q, l, 1) >= 0; }
! 1110: static bool eval(mpir_ui l, mpq_srcptr q)
! 1111: { return mpq_cmp_ui(q, l, 1) <= 0; }
! 1112: static bool eval(mpq_srcptr q, mpir_si l)
! 1113: { return mpq_cmp_si(q, l, 1) >= 0; }
! 1114: static bool eval(mpir_si l, mpq_srcptr q)
! 1115: { return mpq_cmp_si(q, l, 1) <= 0; }
! 1116: static bool eval(mpq_srcptr q, double d)
! 1117: {
! 1118: bool b;
! 1119: mpq_t temp;
! 1120: mpq_init(temp);
! 1121: mpq_set_d(temp, d);
! 1122: b = (mpq_cmp(q, temp) >= 0);
! 1123: mpq_clear(temp);
! 1124: return b;
! 1125: }
! 1126: static bool eval(double d, mpq_srcptr q)
! 1127: {
! 1128: bool b;
! 1129: mpq_t temp;
! 1130: mpq_init(temp);
! 1131: mpq_set_d(temp, d);
! 1132: b = (mpq_cmp(temp, q) >= 0);
! 1133: mpq_clear(temp);
! 1134: return b;
! 1135: }
! 1136:
! 1137: static bool eval(mpf_srcptr f, mpf_srcptr g) { return mpf_cmp(f, g) >= 0; }
! 1138:
! 1139: static bool eval(mpf_srcptr f, mpir_ui l)
! 1140: { return mpf_cmp_ui(f, l) >= 0; }
! 1141: static bool eval(mpir_ui l, mpf_srcptr f)
! 1142: { return mpf_cmp_ui(f, l) <= 0; }
! 1143: static bool eval(mpf_srcptr f, mpir_si l)
! 1144: { return mpf_cmp_si(f, l) >= 0; }
! 1145: static bool eval(mpir_si l, mpf_srcptr f)
! 1146: { return mpf_cmp_si(f, l) <= 0; }
! 1147: static bool eval(mpf_srcptr f, double d)
! 1148: { return mpf_cmp_d(f, d) >= 0; }
! 1149: static bool eval(double d, mpf_srcptr f)
! 1150: { return mpf_cmp_d(f, d) <= 0; }
! 1151: };
! 1152:
! 1153: struct __gmp_unary_increment
! 1154: {
! 1155: static void eval(mpz_ptr z) { mpz_add_ui(z, z, 1); }
! 1156: static void eval(mpq_ptr q)
! 1157: { mpz_add(mpq_numref(q), mpq_numref(q), mpq_denref(q)); }
! 1158: static void eval(mpf_ptr f) { mpf_add_ui(f, f, 1); }
! 1159: };
! 1160:
! 1161: struct __gmp_unary_decrement
! 1162: {
! 1163: static void eval(mpz_ptr z) { mpz_sub_ui(z, z, 1); }
! 1164: static void eval(mpq_ptr q)
! 1165: { mpz_sub(mpq_numref(q), mpq_numref(q), mpq_denref(q)); }
! 1166: static void eval(mpf_ptr f) { mpf_sub_ui(f, f, 1); }
! 1167: };
! 1168:
! 1169: struct __gmp_abs_function
! 1170: {
! 1171: static void eval(mpz_ptr z, mpz_srcptr w) { mpz_abs(z, w); }
! 1172: static void eval(mpq_ptr q, mpq_srcptr r) { mpq_abs(q, r); }
! 1173: static void eval(mpf_ptr f, mpf_srcptr g) { mpf_abs(f, g); }
! 1174: };
! 1175:
! 1176: struct __gmp_trunc_function
! 1177: {
! 1178: static void eval(mpf_ptr f, mpf_srcptr g) { mpf_trunc(f, g); }
! 1179: };
! 1180:
! 1181: struct __gmp_floor_function
! 1182: {
! 1183: static void eval(mpf_ptr f, mpf_srcptr g) { mpf_floor(f, g); }
! 1184: };
! 1185:
! 1186: struct __gmp_ceil_function
! 1187: {
! 1188: static void eval(mpf_ptr f, mpf_srcptr g) { mpf_ceil(f, g); }
! 1189: };
! 1190:
! 1191: struct __gmp_sqrt_function
! 1192: {
! 1193: static void eval(mpz_ptr z, mpz_srcptr w) { mpz_sqrt(z, w); }
! 1194: static void eval(mpf_ptr f, mpf_srcptr g) { mpf_sqrt(f, g); }
! 1195: };
! 1196:
! 1197: struct __gmp_hypot_function
! 1198: {
! 1199: static void eval(mpf_ptr f, mpf_srcptr g, mpf_srcptr h)
! 1200: {
! 1201: mpf_t temp;
! 1202: mpf_init2(temp, mpf_get_prec(f));
! 1203: mpf_mul(temp, g, g);
! 1204: mpf_mul(f, h, h);
! 1205: mpf_add(f, f, temp);
! 1206: mpf_sqrt(f, f);
! 1207: mpf_clear(temp);
! 1208: }
! 1209:
! 1210: static void eval(mpf_ptr f, mpf_srcptr g, mpir_ui l)
! 1211: {
! 1212: mpf_t temp;
! 1213: mpf_init2(temp, mpf_get_prec(f));
! 1214: mpf_mul(temp, g, g);
! 1215: mpf_set_ui(f, l);
! 1216: mpf_mul(f, f, f);
! 1217: mpf_add(f, f, temp);
! 1218: mpf_sqrt(f, f);
! 1219: mpf_clear(temp);
! 1220: }
! 1221: static void eval(mpf_ptr f, mpir_ui l, mpf_srcptr g)
! 1222: {
! 1223: mpf_t temp;
! 1224: mpf_init2(temp, mpf_get_prec(f));
! 1225: mpf_mul(temp, g, g);
! 1226: mpf_set_ui(f, l);
! 1227: mpf_mul(f, f, f);
! 1228: mpf_add(f, f, temp);
! 1229: mpf_sqrt(f, f);
! 1230: mpf_clear(temp);
! 1231: }
! 1232: static void eval(mpf_ptr f, mpf_srcptr g, mpir_si l)
! 1233: {
! 1234: mpf_t temp;
! 1235: mpf_init2(temp, mpf_get_prec(f));
! 1236: mpf_mul(temp, g, g);
! 1237: mpf_set_si(f, l);
! 1238: mpf_mul(f, f, f);
! 1239: mpf_add(f, f, temp);
! 1240: mpf_sqrt(f, f);
! 1241: mpf_clear(temp);
! 1242: }
! 1243: static void eval(mpf_ptr f, mpir_si l, mpf_srcptr g)
! 1244: {
! 1245: mpf_t temp;
! 1246: mpf_init2(temp, mpf_get_prec(f));
! 1247: mpf_mul(temp, g, g);
! 1248: mpf_set_si(f, l);
! 1249: mpf_mul(f, f, f);
! 1250: mpf_add(f, f, temp);
! 1251: mpf_sqrt(f, f);
! 1252: mpf_clear(temp);
! 1253: }
! 1254: static void eval(mpf_ptr f, mpf_srcptr g, double d)
! 1255: {
! 1256: mpf_t temp;
! 1257: mpf_init2(temp, mpf_get_prec(f));
! 1258: mpf_mul(temp, g, g);
! 1259: mpf_set_d(f, d);
! 1260: mpf_mul(f, f, f);
! 1261: mpf_add(f, f, temp);
! 1262: mpf_sqrt(f, f);
! 1263: mpf_clear(temp);
! 1264: }
! 1265: static void eval(mpf_ptr f, double d, mpf_srcptr g)
! 1266: {
! 1267: mpf_t temp;
! 1268: mpf_init2(temp, mpf_get_prec(f));
! 1269: mpf_mul(temp, g, g);
! 1270: mpf_set_d(f, d);
! 1271: mpf_mul(f, f, f);
! 1272: mpf_add(f, f, temp);
! 1273: mpf_sqrt(f, f);
! 1274: mpf_clear(temp);
! 1275: }
! 1276: };
! 1277:
! 1278: struct __gmp_sgn_function
! 1279: {
! 1280: static int eval(mpz_srcptr z) { return mpz_sgn(z); }
! 1281: static int eval(mpq_srcptr q) { return mpq_sgn(q); }
! 1282: static int eval(mpf_srcptr f) { return mpf_sgn(f); }
! 1283: };
! 1284:
! 1285: struct __gmp_cmp_function
! 1286: {
! 1287: static int eval(mpz_srcptr z, mpz_srcptr w) { return mpz_cmp(z, w); }
! 1288:
! 1289: static int eval(mpz_srcptr z, mpir_ui l)
! 1290: { return mpz_cmp_ui(z, l); }
! 1291: static int eval(mpir_ui l, mpz_srcptr z)
! 1292: { return -mpz_cmp_ui(z, l); }
! 1293: static int eval(mpz_srcptr z, mpir_si l)
! 1294: { return mpz_cmp_si(z, l); }
! 1295: static int eval(mpir_si l, mpz_srcptr z)
! 1296: { return -mpz_cmp_si(z, l); }
! 1297: static int eval(mpz_srcptr z, double d)
! 1298: { return mpz_cmp_d(z, d); }
! 1299: static int eval(double d, mpz_srcptr z)
! 1300: { return -mpz_cmp_d(z, d); }
! 1301:
! 1302: static int eval(mpq_srcptr q, mpq_srcptr r) { return mpq_cmp(q, r); }
! 1303:
! 1304: static int eval(mpq_srcptr q, mpir_ui l)
! 1305: { return mpq_cmp_ui(q, l, 1); }
! 1306: static int eval(mpir_ui l, mpq_srcptr q)
! 1307: { return -mpq_cmp_ui(q, l, 1); }
! 1308: static int eval(mpq_srcptr q, mpir_si l)
! 1309: { return mpq_cmp_si(q, l, 1); }
! 1310: static int eval(mpir_si l, mpq_srcptr q)
! 1311: { return -mpq_cmp_si(q, l, 1); }
! 1312: static int eval(mpq_srcptr q, double d)
! 1313: {
! 1314: int i;
! 1315: mpq_t temp;
! 1316: mpq_init(temp);
! 1317: mpq_set_d(temp, d);
! 1318: i = mpq_cmp(q, temp);
! 1319: mpq_clear(temp);
! 1320: return i;
! 1321: }
! 1322: static int eval(double d, mpq_srcptr q)
! 1323: {
! 1324: int i;
! 1325: mpq_t temp;
! 1326: mpq_init(temp);
! 1327: mpq_set_d(temp, d);
! 1328: i = mpq_cmp(temp, q);
! 1329: mpq_clear(temp);
! 1330: return i;
! 1331: }
! 1332:
! 1333: static int eval(mpf_srcptr f, mpf_srcptr g) { return mpf_cmp(f, g); }
! 1334:
! 1335: static int eval(mpf_srcptr f, mpir_ui l)
! 1336: { return mpf_cmp_ui(f, l); }
! 1337: static int eval(mpir_ui l, mpf_srcptr f)
! 1338: { return -mpf_cmp_ui(f, l); }
! 1339: static int eval(mpf_srcptr f, mpir_si l)
! 1340: { return mpf_cmp_si(f, l); }
! 1341: static int eval(mpir_si l, mpf_srcptr f)
! 1342: { return -mpf_cmp_si(f, l); }
! 1343: static int eval(mpf_srcptr f, double d)
! 1344: { return mpf_cmp_d(f, d); }
! 1345: static int eval(double d, mpf_srcptr f)
! 1346: { return -mpf_cmp_d(f, d); }
! 1347: };
! 1348:
! 1349: struct __gmp_rand_function
! 1350: {
! 1351: static void eval(mpz_ptr z, gmp_randstate_t s, mpir_ui l)
! 1352: { mpz_urandomb(z, s, l); }
! 1353: static void eval(mpz_ptr z, gmp_randstate_t s, mpz_srcptr w)
! 1354: { mpz_urandomm(z, s, w); }
! 1355: static void eval(mpf_ptr f, gmp_randstate_t s, mp_bitcnt_t prec)
! 1356: { mpf_urandomb(f, s, prec); }
! 1357: };
! 1358:
! 1359:
! 1360: /**************** Auxiliary classes ****************/
! 1361:
! 1362: /* this is much the same as gmp_allocated_string in gmp-impl.h
! 1363: since gmp-impl.h is not publicly available, I redefine it here
! 1364: I use a different name to avoid possible clashes */
! 1365: extern "C" {
! 1366: struct __gmp_alloc_cstring_c
! 1367: {
! 1368: void (*free_func) (void *, size_t);
! 1369: };
! 1370: }
! 1371:
! 1372: struct __gmp_alloc_cstring : __gmp_alloc_cstring_c
! 1373: {
! 1374: char *str;
! 1375: __gmp_alloc_cstring(char *s) { str = s; }
! 1376: ~__gmp_alloc_cstring()
! 1377: {
! 1378: mp_get_memory_functions (NULL, NULL, &free_func);
! 1379: (*free_func) (str, std::strlen(str)+1);
! 1380: }
! 1381: };
! 1382:
! 1383: // general expression template class
! 1384: template <class T, class U>
! 1385: class __gmp_expr;
! 1386:
! 1387:
! 1388: // templates for resolving expression types
! 1389: template <class T>
! 1390: struct __gmp_resolve_ref
! 1391: {
! 1392: typedef T ref_type;
! 1393: };
! 1394:
! 1395: template <class T, class U>
! 1396: struct __gmp_resolve_ref<__gmp_expr<T, U> >
! 1397: {
! 1398: typedef const __gmp_expr<T, U> & ref_type;
! 1399: };
! 1400:
! 1401:
! 1402: template <class T, class U = T>
! 1403: struct __gmp_resolve_expr;
! 1404:
! 1405: template <>
! 1406: struct __gmp_resolve_expr<mpz_t>
! 1407: {
! 1408: typedef mpz_t value_type;
! 1409: typedef mpz_ptr ptr_type;
! 1410: };
! 1411:
! 1412: template <>
! 1413: struct __gmp_resolve_expr<mpq_t>
! 1414: {
! 1415: typedef mpq_t value_type;
! 1416: typedef mpq_ptr ptr_type;
! 1417: };
! 1418:
! 1419: template <>
! 1420: struct __gmp_resolve_expr<mpf_t>
! 1421: {
! 1422: typedef mpf_t value_type;
! 1423: typedef mpf_ptr ptr_type;
! 1424: };
! 1425:
! 1426: template <>
! 1427: struct __gmp_resolve_expr<mpz_t, mpq_t>
! 1428: {
! 1429: typedef mpq_t value_type;
! 1430: };
! 1431:
! 1432: template <>
! 1433: struct __gmp_resolve_expr<mpq_t, mpz_t>
! 1434: {
! 1435: typedef mpq_t value_type;
! 1436: };
! 1437:
! 1438: template <>
! 1439: struct __gmp_resolve_expr<mpz_t, mpf_t>
! 1440: {
! 1441: typedef mpf_t value_type;
! 1442: };
! 1443:
! 1444: template <>
! 1445: struct __gmp_resolve_expr<mpf_t, mpz_t>
! 1446: {
! 1447: typedef mpf_t value_type;
! 1448: };
! 1449:
! 1450: template <>
! 1451: struct __gmp_resolve_expr<mpq_t, mpf_t>
! 1452: {
! 1453: typedef mpf_t value_type;
! 1454: };
! 1455:
! 1456: template <>
! 1457: struct __gmp_resolve_expr<mpf_t, mpq_t>
! 1458: {
! 1459: typedef mpf_t value_type;
! 1460: };
! 1461:
! 1462:
! 1463:
! 1464: template <class T, class U, class V>
! 1465: struct __gmp_resolve_temp
! 1466: {
! 1467: typedef __gmp_expr<T, T> temp_type;
! 1468: };
! 1469:
! 1470: template <class T>
! 1471: struct __gmp_resolve_temp<T, T, T>
! 1472: {
! 1473: typedef const __gmp_expr<T, T> & temp_type;
! 1474: };
! 1475:
! 1476:
! 1477: // classes for evaluating unary and binary expressions
! 1478: template <class T, class Op>
! 1479: struct __gmp_unary_expr
! 1480: {
! 1481: const T &val;
! 1482:
! 1483: __gmp_unary_expr(const T &v) : val(v) { }
! 1484: private:
! 1485: __gmp_unary_expr();
! 1486: };
! 1487:
! 1488: template <class T, class U, class Op>
! 1489: struct __gmp_binary_expr
! 1490: {
! 1491: typename __gmp_resolve_ref<T>::ref_type val1;
! 1492: typename __gmp_resolve_ref<U>::ref_type val2;
! 1493:
! 1494: __gmp_binary_expr(const T &v1, const U &v2) : val1(v1), val2(v2) { }
! 1495: private:
! 1496: __gmp_binary_expr();
! 1497: };
! 1498:
! 1499:
! 1500: // functions for evaluating expressions
! 1501: template <class T, class U>
! 1502: void __gmp_set_expr(mpz_ptr, const __gmp_expr<T, U> &);
! 1503: template <class T, class U>
! 1504: void __gmp_set_expr(mpq_ptr, const __gmp_expr<T, U> &);
! 1505: template <class T, class U>
! 1506: void __gmp_set_expr(mpf_ptr, const __gmp_expr<T, U> &);
! 1507:
! 1508:
! 1509: /**************** Macros for in-class declarations ****************/
! 1510: /* This is just repetitive code that is easier to maintain if it's written
! 1511: only once */
! 1512:
! 1513: #define __GMPP_DECLARE_COMPOUND_OPERATOR(fun) \
! 1514: template <class T, class U> \
! 1515: __gmp_expr<value_type, value_type> & fun(const __gmp_expr<T, U> &);
! 1516: #ifdef MPIRXX_HAVE_LLONG
! 1517: #define __GMPN_DECLARE_COMPOUND_OPERATOR(fun) \
! 1518: __gmp_expr & fun(signed char); \
! 1519: __gmp_expr & fun(unsigned char); \
! 1520: __gmp_expr & fun(signed int); \
! 1521: __gmp_expr & fun(unsigned int); \
! 1522: __gmp_expr & fun(signed short int); \
! 1523: __gmp_expr & fun(unsigned short int); \
! 1524: __gmp_expr & fun(signed long int); \
! 1525: __gmp_expr & fun(unsigned long int); \
! 1526: __gmp_expr & fun(signed long long int); \
! 1527: __gmp_expr & fun(unsigned long long int); \
! 1528: __gmp_expr & fun(float); \
! 1529: __gmp_expr & fun(double); \
! 1530: __gmp_expr & fun(long double);
! 1531: #else
! 1532: #define __GMPN_DECLARE_COMPOUND_OPERATOR(fun) \
! 1533: __gmp_expr & fun(signed char); \
! 1534: __gmp_expr & fun(unsigned char); \
! 1535: __gmp_expr & fun(signed int); \
! 1536: __gmp_expr & fun(unsigned int); \
! 1537: __gmp_expr & fun(signed short int); \
! 1538: __gmp_expr & fun(unsigned short int); \
! 1539: __gmp_expr & fun(signed long int); \
! 1540: __gmp_expr & fun(unsigned long int); \
! 1541: __gmp_expr & fun(float); \
! 1542: __gmp_expr & fun(double); \
! 1543: __gmp_expr & fun(long double);
! 1544: #endif
! 1545:
! 1546: #define __GMP_DECLARE_COMPOUND_OPERATOR(fun) \
! 1547: __GMPP_DECLARE_COMPOUND_OPERATOR(fun) \
! 1548: __GMPN_DECLARE_COMPOUND_OPERATOR(fun)
! 1549:
! 1550: #define __GMP_DECLARE_COMPOUND_OPERATOR_UI(fun) \
! 1551: __gmp_expr & fun(mpir_ui);
! 1552:
! 1553: #define __GMP_DECLARE_INCREMENT_OPERATOR(fun) \
! 1554: inline __gmp_expr & fun(); \
! 1555: inline __gmp_expr fun(int);
! 1556:
! 1557:
! 1558: /**************** mpz_class -- wrapper for mpz_t ****************/
! 1559:
! 1560: template <>
! 1561: class __gmp_expr<mpz_t, mpz_t>
! 1562: {
! 1563: private:
! 1564: typedef mpz_t value_type;
! 1565: value_type mp;
! 1566: public:
! 1567: mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); }
! 1568:
! 1569: // constructors and destructor
! 1570: __gmp_expr() { mpz_init(mp); }
! 1571:
! 1572: __gmp_expr(const __gmp_expr &z) { mpz_init_set(mp, z.mp); }
! 1573: template <class T, class U>
! 1574: __gmp_expr(const __gmp_expr<T, U> &expr)
! 1575: { mpz_init(mp); __gmp_set_expr(mp, expr); }
! 1576:
! 1577: __gmp_expr(signed char c) { mpz_init_set_si(mp, c); }
! 1578: __gmp_expr(unsigned char c) { mpz_init_set_ui(mp, c); }
! 1579:
! 1580: __gmp_expr(signed int i) { mpz_init_set_si(mp, i); }
! 1581: __gmp_expr(unsigned int i) { mpz_init_set_ui(mp, i); }
! 1582:
! 1583: __gmp_expr(signed short int s) { mpz_init_set_si(mp, s); }
! 1584: __gmp_expr(unsigned short int s) { mpz_init_set_ui(mp, s); }
! 1585:
! 1586: __gmp_expr(signed long int l) { mpz_init_set_si(mp, l); }
! 1587: __gmp_expr(unsigned long int l) { mpz_init_set_ui(mp, l); }
! 1588:
! 1589: #ifdef MPIRXX_HAVE_LLONG
! 1590: __gmp_expr(signed long long int l) { mpz_init_set_si(mp, l); }
! 1591: __gmp_expr(unsigned long long int l) { mpz_init_set_ui(mp, l); }
! 1592: #endif
! 1593:
! 1594: #if defined( _MSC_VER ) && _MSC_VER >= 1600
! 1595: #if defined( _STDINT_H ) || defined ( _STDINT_H_ ) || defined ( _STDINT )
! 1596: __gmp_expr(intmax_t l) { mpz_init_set_sx(mp, l); }
! 1597: __gmp_expr(uintmax_t l) { mpz_init_set_ux(mp, l); }
! 1598: #endif
! 1599: #endif
! 1600:
! 1601: __gmp_expr(float f) { mpz_init_set_d(mp, f); }
! 1602: __gmp_expr(double d) { mpz_init_set_d(mp, d); }
! 1603: // __gmp_expr(long double ld) { mpz_init_set_d(mp, ld); }
! 1604:
! 1605: explicit __gmp_expr(const char *s)
! 1606: {
! 1607: if (mpz_init_set_str (mp, s, 0) != 0)
! 1608: {
! 1609: mpz_clear (mp);
! 1610: throw std::invalid_argument ("mpz_set_str");
! 1611: }
! 1612: }
! 1613: __gmp_expr(const char *s, int base)
! 1614: {
! 1615: if (mpz_init_set_str (mp, s, base) != 0)
! 1616: {
! 1617: mpz_clear (mp);
! 1618: throw std::invalid_argument ("mpz_set_str");
! 1619: }
! 1620: }
! 1621: explicit __gmp_expr(const std::string &s)
! 1622: {
! 1623: if (mpz_init_set_str (mp, s.c_str(), 0) != 0)
! 1624: {
! 1625: mpz_clear (mp);
! 1626: throw std::invalid_argument ("mpz_set_str");
! 1627: }
! 1628: }
! 1629: __gmp_expr(const std::string &s, int base)
! 1630: {
! 1631: if (mpz_init_set_str(mp, s.c_str(), base) != 0)
! 1632: {
! 1633: mpz_clear (mp);
! 1634: throw std::invalid_argument ("mpz_set_str");
! 1635: }
! 1636: }
! 1637:
! 1638: explicit __gmp_expr(mpz_srcptr z) { mpz_init_set(mp, z); }
! 1639:
! 1640: ~__gmp_expr() { mpz_clear(mp); }
! 1641:
! 1642: // assignment operators
! 1643: __gmp_expr & operator=(const __gmp_expr &z) { mpz_set(mp, z.mp); return *this; }
! 1644: template <class T, class U>
! 1645: __gmp_expr<value_type, value_type> & operator=(const __gmp_expr<T, U> &expr)
! 1646: { __gmp_set_expr(mp, expr); return *this; }
! 1647:
! 1648: __gmp_expr & operator=(signed char c) { mpz_set_si(mp, c); return *this; }
! 1649: __gmp_expr & operator=(unsigned char c) { mpz_set_ui(mp, c); return *this; }
! 1650:
! 1651: __gmp_expr & operator=(signed short int s) { mpz_set_si(mp, s); return *this; }
! 1652: __gmp_expr & operator=(unsigned short int s) { mpz_set_ui(mp, s); return *this; }
! 1653:
! 1654: __gmp_expr & operator=(signed int i) { mpz_set_si(mp, i); return *this; }
! 1655: __gmp_expr & operator=(unsigned int i) { mpz_set_ui(mp, i); return *this; }
! 1656:
! 1657: __gmp_expr & operator=(signed long int i) { mpz_set_si(mp, i); return *this; }
! 1658: __gmp_expr & operator=(unsigned long int i) { mpz_set_ui(mp, i); return *this; }
! 1659:
! 1660: #ifdef MPIRXX_HAVE_LLONG
! 1661: __gmp_expr & operator=(signed long long int i) { mpz_set_si(mp, i); return *this; }
! 1662: __gmp_expr & operator=(unsigned long long int i) { mpz_set_ui(mp, i); return *this; }
! 1663: #endif
! 1664:
! 1665: #if defined( _MSC_VER ) && _MSC_VER >= 1600
! 1666: #if defined( _STDINT_H ) || defined ( _STDINT_H_ ) || defined ( _STDINT )
! 1667: __gmp_expr & operator=(intmax_t i) { mpz_set_sx(mp, i); return *this; }
! 1668: __gmp_expr & operator=(uintmax_t i) { mpz_set_ux(mp, i); return *this; }
! 1669: #endif
! 1670: #endif
! 1671:
! 1672: __gmp_expr & operator=(float f) { mpz_set_d(mp, f); return *this; }
! 1673: __gmp_expr & operator=(double d) { mpz_set_d(mp, d); return *this; }
! 1674: // __gmp_expr & operator=(long double ld)
! 1675: // { mpz_set_ld(mp, ld); return *this; }
! 1676:
! 1677: __gmp_expr & operator=(const char *s)
! 1678: {
! 1679: if (mpz_set_str (mp, s, 0) != 0)
! 1680: throw std::invalid_argument ("mpz_set_str");
! 1681: return *this;
! 1682: }
! 1683: __gmp_expr & operator=(const std::string &s)
! 1684: {
! 1685: if (mpz_set_str(mp, s.c_str(), 0) != 0)
! 1686: throw std::invalid_argument ("mpz_set_str");
! 1687: return *this;
! 1688: }
! 1689:
! 1690: // string input/output functions
! 1691: int set_str(const char *s, int base)
! 1692: { return mpz_set_str(mp, s, base); }
! 1693: int set_str(const std::string &s, int base)
! 1694: { return mpz_set_str(mp, s.c_str(), base); }
! 1695: std::string get_str(int base = 10) const
! 1696: {
! 1697: __gmp_alloc_cstring temp(mpz_get_str(0, base, mp));
! 1698: return std::string(temp.str);
! 1699: }
! 1700:
! 1701: // conversion functions
! 1702: mpz_srcptr __get_mp() const { return mp; }
! 1703: mpz_ptr __get_mp() { return mp; }
! 1704: mpz_srcptr get_mpz_t() const { return mp; }
! 1705: mpz_ptr get_mpz_t() { return mp; }
! 1706:
! 1707: mpir_si get_si() const { return mpz_get_si(mp); }
! 1708: mpir_ui get_ui() const { return mpz_get_ui(mp); }
! 1709: #if defined( _STDINT_H ) || defined ( _STDINT_H_ ) || defined ( _STDINT )
! 1710: intmax_t get_sx() const { return mpz_get_sx(mp); }
! 1711: uintmax_t get_ux() const { return mpz_get_ux(mp); }
! 1712: #endif
! 1713: double get_d() const { return mpz_get_d(mp); }
! 1714:
! 1715: // bool fits_schar_p() const { return mpz_fits_schar_p(mp); }
! 1716: // bool fits_uchar_p() const { return mpz_fits_uchar_p(mp); }
! 1717: bool fits_sint_p() const { return mpz_fits_sint_p(mp); }
! 1718: bool fits_uint_p() const { return mpz_fits_uint_p(mp); }
! 1719: bool fits_si_p() const { return mpz_fits_si_p(mp); }
! 1720: bool fits_ui_p() const { return mpz_fits_ui_p(mp); }
! 1721: bool fits_sshort_p() const { return mpz_fits_sshort_p(mp); }
! 1722: bool fits_ushort_p() const { return mpz_fits_ushort_p(mp); }
! 1723: bool fits_slong_p() const { return mpz_fits_slong_p(mp); }
! 1724: bool fits_ulong_p() const { return mpz_fits_ulong_p(mp); }
! 1725: // bool fits_float_p() const { return mpz_fits_float_p(mp); }
! 1726: // bool fits_double_p() const { return mpz_fits_double_p(mp); }
! 1727: // bool fits_ldouble_p() const { return mpz_fits_ldouble_p(mp); }
! 1728:
! 1729: // member operators
! 1730: __GMP_DECLARE_COMPOUND_OPERATOR(operator+=)
! 1731: __GMP_DECLARE_COMPOUND_OPERATOR(operator-=)
! 1732: __GMP_DECLARE_COMPOUND_OPERATOR(operator*=)
! 1733: __GMP_DECLARE_COMPOUND_OPERATOR(operator/=)
! 1734: __GMP_DECLARE_COMPOUND_OPERATOR(operator%=)
! 1735:
! 1736: __GMPP_DECLARE_COMPOUND_OPERATOR(operator&=)
! 1737: __GMPP_DECLARE_COMPOUND_OPERATOR(operator|=)
! 1738: __GMPP_DECLARE_COMPOUND_OPERATOR(operator^=)
! 1739:
! 1740: __GMP_DECLARE_COMPOUND_OPERATOR_UI(operator<<=)
! 1741: __GMP_DECLARE_COMPOUND_OPERATOR_UI(operator>>=)
! 1742:
! 1743: __GMP_DECLARE_INCREMENT_OPERATOR(operator++)
! 1744: __GMP_DECLARE_INCREMENT_OPERATOR(operator--)
! 1745: };
! 1746:
! 1747: typedef __gmp_expr<mpz_t, mpz_t> mpz_class;
! 1748:
! 1749:
! 1750: /**************** mpq_class -- wrapper for mpq_t ****************/
! 1751:
! 1752: template <>
! 1753: class __gmp_expr<mpq_t, mpq_t>
! 1754: {
! 1755: private:
! 1756: typedef mpq_t value_type;
! 1757: value_type mp;
! 1758: public:
! 1759: mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); }
! 1760: void canonicalize() { mpq_canonicalize(mp); }
! 1761:
! 1762: // constructors and destructor
! 1763: __gmp_expr() { mpq_init(mp); }
! 1764:
! 1765: __gmp_expr(const __gmp_expr &q) { mpq_init(mp); mpq_set(mp, q.mp); }
! 1766: template <class T, class U>
! 1767: __gmp_expr(const __gmp_expr<T, U> &expr)
! 1768: { mpq_init(mp); __gmp_set_expr(mp, expr); }
! 1769:
! 1770: __gmp_expr(signed char c) { mpq_init(mp); mpq_set_si(mp, c, 1); }
! 1771: __gmp_expr(unsigned char c) { mpq_init(mp); mpq_set_ui(mp, c, 1); }
! 1772:
! 1773: __gmp_expr(signed int i) { mpq_init(mp); mpq_set_si(mp, i, 1); }
! 1774: __gmp_expr(unsigned int i) { mpq_init(mp); mpq_set_ui(mp, i, 1); }
! 1775:
! 1776: __gmp_expr(signed short int s) { mpq_init(mp); mpq_set_si(mp, s, 1); }
! 1777: __gmp_expr(unsigned short int s) { mpq_init(mp); mpq_set_ui(mp, s, 1); }
! 1778:
! 1779: __gmp_expr(signed long int l) { mpq_init(mp); mpq_set_si(mp, l, 1); }
! 1780: __gmp_expr(unsigned long int l) { mpq_init(mp); mpq_set_ui(mp, l, 1); }
! 1781:
! 1782: #ifdef MPIRXX_HAVE_LLONG
! 1783: __gmp_expr(signed long long int l) { mpq_init(mp); mpq_set_si(mp, l, 1); }
! 1784: __gmp_expr(unsigned long long int l) { mpq_init(mp); mpq_set_ui(mp, l, 1); }
! 1785: #endif
! 1786:
! 1787: __gmp_expr(float f) { mpq_init(mp); mpq_set_d(mp, f); }
! 1788: __gmp_expr(double d) { mpq_init(mp); mpq_set_d(mp, d); }
! 1789: // __gmp_expr(long double ld) { mpq_init(mp); mpq_set_ld(mp, ld); }
! 1790:
! 1791: explicit __gmp_expr(const char *s)
! 1792: {
! 1793: mpq_init (mp);
! 1794: if (mpq_set_str (mp, s, 0) != 0)
! 1795: {
! 1796: mpq_clear (mp);
! 1797: throw std::invalid_argument ("mpq_set_str");
! 1798: }
! 1799: }
! 1800: __gmp_expr(const char *s, int base)
! 1801: {
! 1802: mpq_init (mp);
! 1803: if (mpq_set_str(mp, s, base) != 0)
! 1804: {
! 1805: mpq_clear (mp);
! 1806: throw std::invalid_argument ("mpq_set_str");
! 1807: }
! 1808: }
! 1809: explicit __gmp_expr(const std::string &s)
! 1810: {
! 1811: mpq_init (mp);
! 1812: if (mpq_set_str (mp, s.c_str(), 0) != 0)
! 1813: {
! 1814: mpq_clear (mp);
! 1815: throw std::invalid_argument ("mpq_set_str");
! 1816: }
! 1817: }
! 1818: __gmp_expr(const std::string &s, int base)
! 1819: {
! 1820: mpq_init(mp);
! 1821: if (mpq_set_str (mp, s.c_str(), base) != 0)
! 1822: {
! 1823: mpq_clear (mp);
! 1824: throw std::invalid_argument ("mpq_set_str");
! 1825: }
! 1826: }
! 1827: explicit __gmp_expr(mpq_srcptr q) { mpq_init(mp); mpq_set(mp, q); }
! 1828:
! 1829: __gmp_expr(const mpz_class &num, const mpz_class &den)
! 1830: {
! 1831: mpq_init(mp);
! 1832: mpz_set(mpq_numref(mp), num.get_mpz_t());
! 1833: mpz_set(mpq_denref(mp), den.get_mpz_t());
! 1834: }
! 1835:
! 1836: ~__gmp_expr() { mpq_clear(mp); }
! 1837:
! 1838: // assignment operators
! 1839: __gmp_expr & operator=(const __gmp_expr &q)
! 1840: { mpq_set(mp, q.mp); return *this; }
! 1841: template <class T, class U>
! 1842: __gmp_expr<value_type, value_type> & operator=(const __gmp_expr<T, U> &expr)
! 1843: { __gmp_set_expr(mp, expr); return *this; }
! 1844:
! 1845: __gmp_expr & operator=(signed char c)
! 1846: { mpq_set_si(mp, c, 1); return *this; }
! 1847: __gmp_expr & operator=(unsigned char c)
! 1848: { mpq_set_ui(mp, c, 1); return *this; }
! 1849:
! 1850: __gmp_expr & operator=(signed int i) { mpq_set_si(mp, i, 1); return *this; }
! 1851: __gmp_expr & operator=(unsigned int i)
! 1852: { mpq_set_ui(mp, i, 1); return *this; }
! 1853:
! 1854: __gmp_expr & operator=(signed short int s)
! 1855: { mpq_set_si(mp, s, 1); return *this; }
! 1856: __gmp_expr & operator=(unsigned short int s)
! 1857: { mpq_set_ui(mp, s, 1); return *this; }
! 1858:
! 1859: __gmp_expr & operator=(signed long int l)
! 1860: { mpq_set_si(mp, l, 1); return *this; }
! 1861: __gmp_expr & operator=(unsigned long int l)
! 1862: { mpq_set_ui(mp, l, 1); return *this; }
! 1863:
! 1864: #ifdef MPIRXX_HAVE_LLONG
! 1865: __gmp_expr & operator=(signed long long int l)
! 1866: { mpq_set_si(mp, l, 1); return *this; }
! 1867: __gmp_expr & operator=(unsigned long long int l)
! 1868: { mpq_set_ui(mp, l, 1); return *this; }
! 1869: #endif
! 1870:
! 1871: __gmp_expr & operator=(float f) { mpq_set_d(mp, f); return *this; }
! 1872: __gmp_expr & operator=(double d) { mpq_set_d(mp, d); return *this; }
! 1873:
! 1874: // __gmp_expr & operator=(long double ld)
! 1875: // { mpq_set_ld(mp, ld); return *this; }
! 1876:
! 1877: __gmp_expr & operator=(const char *s)
! 1878: {
! 1879: if (mpq_set_str (mp, s, 0) != 0)
! 1880: throw std::invalid_argument ("mpq_set_str");
! 1881: return *this;
! 1882: }
! 1883: __gmp_expr & operator=(const std::string &s)
! 1884: {
! 1885: if (mpq_set_str(mp, s.c_str(), 0) != 0)
! 1886: throw std::invalid_argument ("mpq_set_str");
! 1887: return *this;
! 1888: }
! 1889:
! 1890: // string input/output functions
! 1891: int set_str(const char *s, int base)
! 1892: { return mpq_set_str(mp, s, base); }
! 1893: int set_str(const std::string &s, int base)
! 1894: { return mpq_set_str(mp, s.c_str(), base); }
! 1895: std::string get_str(int base = 10) const
! 1896: {
! 1897: __gmp_alloc_cstring temp(mpq_get_str(0, base, mp));
! 1898: return std::string(temp.str);
! 1899: }
! 1900:
! 1901: // conversion functions
! 1902:
! 1903: // casting a reference to an mpz_t to mpz_class & is a dirty hack,
! 1904: // but works because the internal representation of mpz_class is
! 1905: // exactly an mpz_t
! 1906: const mpz_class & get_num() const
! 1907: { return reinterpret_cast<const mpz_class &>(*mpq_numref(mp)); }
! 1908: mpz_class & get_num()
! 1909: { return reinterpret_cast<mpz_class &>(*mpq_numref(mp)); }
! 1910: const mpz_class & get_den() const
! 1911: { return reinterpret_cast<const mpz_class &>(*mpq_denref(mp)); }
! 1912: mpz_class & get_den()
! 1913: { return reinterpret_cast<mpz_class &>(*mpq_denref(mp)); }
! 1914:
! 1915: mpq_srcptr __get_mp() const { return mp; }
! 1916: mpq_ptr __get_mp() { return mp; }
! 1917: mpq_srcptr get_mpq_t() const { return mp; }
! 1918: mpq_ptr get_mpq_t() { return mp; }
! 1919:
! 1920: mpz_srcptr get_num_mpz_t() const { return mpq_numref(mp); }
! 1921: mpz_ptr get_num_mpz_t() { return mpq_numref(mp); }
! 1922: mpz_srcptr get_den_mpz_t() const { return mpq_denref(mp); }
! 1923: mpz_ptr get_den_mpz_t() { return mpq_denref(mp); }
! 1924:
! 1925: double get_d() const { return mpq_get_d(mp); }
! 1926:
! 1927: // compound assignments
! 1928: __GMP_DECLARE_COMPOUND_OPERATOR(operator+=)
! 1929: __GMP_DECLARE_COMPOUND_OPERATOR(operator-=)
! 1930: __GMP_DECLARE_COMPOUND_OPERATOR(operator*=)
! 1931: __GMP_DECLARE_COMPOUND_OPERATOR(operator/=)
! 1932:
! 1933: __GMP_DECLARE_COMPOUND_OPERATOR_UI(operator<<=)
! 1934: __GMP_DECLARE_COMPOUND_OPERATOR_UI(operator>>=)
! 1935:
! 1936: __GMP_DECLARE_INCREMENT_OPERATOR(operator++)
! 1937: __GMP_DECLARE_INCREMENT_OPERATOR(operator--)
! 1938: };
! 1939:
! 1940: typedef __gmp_expr<mpq_t, mpq_t> mpq_class;
! 1941:
! 1942:
! 1943: /**************** mpf_class -- wrapper for mpf_t ****************/
! 1944:
! 1945: template <>
! 1946: class __gmp_expr<mpf_t, mpf_t>
! 1947: {
! 1948: private:
! 1949: typedef mpf_t value_type;
! 1950: value_type mp;
! 1951: public:
! 1952: mp_bitcnt_t get_prec() const { return mpf_get_prec(mp); }
! 1953:
! 1954: void set_prec(mp_bitcnt_t prec) { mpf_set_prec(mp, prec); }
! 1955: void set_prec_raw(mp_bitcnt_t prec) { mpf_set_prec_raw(mp, prec); }
! 1956:
! 1957: // constructors and destructor
! 1958: __gmp_expr() { mpf_init(mp); }
! 1959:
! 1960: __gmp_expr(const __gmp_expr &f)
! 1961: { mpf_init2(mp, f.get_prec()); mpf_set(mp, f.mp); }
! 1962: __gmp_expr(const __gmp_expr &f, mp_bitcnt_t prec)
! 1963: { mpf_init2(mp, prec); mpf_set(mp, f.mp); }
! 1964: template <class T, class U>
! 1965: __gmp_expr(const __gmp_expr<T, U> &expr)
! 1966: { mpf_init2(mp, expr.get_prec()); __gmp_set_expr(mp, expr); }
! 1967: template <class T, class U>
! 1968: __gmp_expr(const __gmp_expr<T, U> &expr, mp_bitcnt_t prec)
! 1969: { mpf_init2(mp, prec); __gmp_set_expr(mp, expr); }
! 1970:
! 1971: __gmp_expr(signed char c) { mpf_init_set_si(mp, c); }
! 1972: __gmp_expr(signed char c, mp_bitcnt_t prec)
! 1973: { mpf_init2(mp, prec); mpf_set_si(mp, c); }
! 1974: __gmp_expr(unsigned char c) { mpf_init_set_ui(mp, c); }
! 1975: __gmp_expr(unsigned char c, mp_bitcnt_t prec)
! 1976: { mpf_init2(mp, prec); mpf_set_ui(mp, c); }
! 1977:
! 1978: __gmp_expr(signed short int s) { mpf_init_set_si(mp, s); }
! 1979: __gmp_expr(signed short int s, mp_bitcnt_t prec)
! 1980: { mpf_init2(mp, prec); mpf_set_si(mp, s); }
! 1981: __gmp_expr(unsigned short int s) { mpf_init_set_ui(mp, s); }
! 1982: __gmp_expr(unsigned short int s, mp_bitcnt_t prec)
! 1983: { mpf_init2(mp, prec); mpf_set_ui(mp, s); }
! 1984:
! 1985: __gmp_expr(signed int i) { mpf_init_set_si(mp, i); }
! 1986: __gmp_expr(signed int i, mp_bitcnt_t prec)
! 1987: { mpf_init2(mp, prec); mpf_set_si(mp, i); }
! 1988: __gmp_expr(unsigned int i) { mpf_init_set_ui(mp, i); }
! 1989: __gmp_expr(unsigned int i, mp_bitcnt_t prec)
! 1990: { mpf_init2(mp, prec); mpf_set_ui(mp, i); }
! 1991:
! 1992: __gmp_expr(signed long int s) { mpf_init_set_si(mp, s); }
! 1993: __gmp_expr(signed long int s, mp_bitcnt_t prec)
! 1994: { mpf_init2(mp, prec); mpf_set_si(mp, s); }
! 1995: __gmp_expr(unsigned long int s) { mpf_init_set_ui(mp, s); }
! 1996: __gmp_expr(unsigned long int s, mp_bitcnt_t prec)
! 1997: { mpf_init2(mp, prec); mpf_set_ui(mp, s); }
! 1998:
! 1999: #ifdef MPIRXX_HAVE_LLONG
! 2000: __gmp_expr(signed long long int s) { mpf_init_set_si(mp, s); }
! 2001: __gmp_expr(signed long long int s, mp_bitcnt_t prec)
! 2002: { mpf_init2(mp, prec); mpf_set_si(mp, s); }
! 2003: __gmp_expr(unsigned long long int s) { mpf_init_set_ui(mp, s); }
! 2004: __gmp_expr(unsigned long long int s, mp_bitcnt_t prec)
! 2005: { mpf_init2(mp, prec); mpf_set_ui(mp, s); }
! 2006: #endif
! 2007:
! 2008: __gmp_expr(float f) { mpf_init_set_d(mp, f); }
! 2009: __gmp_expr(float f, mp_bitcnt_t prec)
! 2010: { mpf_init2(mp, prec); mpf_set_d(mp, f); }
! 2011: __gmp_expr(double d) { mpf_init_set_d(mp, d); }
! 2012: __gmp_expr(double d, mp_bitcnt_t prec)
! 2013: { mpf_init2(mp, prec); mpf_set_d(mp, d); }
! 2014: // __gmp_expr(long double ld) { mpf_init_set_d(mp, ld); }
! 2015: // __gmp_expr(long double ld, mp_bitcnt_t prec)
! 2016: // { mpf_init2(mp, prec); mpf_set_d(mp, ld); }
! 2017:
! 2018: explicit __gmp_expr(const char *s)
! 2019: {
! 2020: if (mpf_init_set_str (mp, s, 0) != 0)
! 2021: {
! 2022: mpf_clear (mp);
! 2023: throw std::invalid_argument ("mpf_set_str");
! 2024: }
! 2025: }
! 2026: __gmp_expr(const char *s, mp_bitcnt_t prec, int base = 0)
! 2027: {
! 2028: mpf_init2(mp, prec);
! 2029: if (mpf_set_str(mp, s, base) != 0)
! 2030: {
! 2031: mpf_clear (mp);
! 2032: throw std::invalid_argument ("mpf_set_str");
! 2033: }
! 2034: }
! 2035: explicit __gmp_expr(const std::string &s)
! 2036: {
! 2037: if (mpf_init_set_str(mp, s.c_str(), 0) != 0)
! 2038: {
! 2039: mpf_clear (mp);
! 2040: throw std::invalid_argument ("mpf_set_str");
! 2041: }
! 2042: }
! 2043: __gmp_expr(const std::string &s, mp_bitcnt_t prec, int base = 0)
! 2044: {
! 2045: mpf_init2(mp, prec);
! 2046: if (mpf_set_str(mp, s.c_str(), base) != 0)
! 2047: {
! 2048: mpf_clear (mp);
! 2049: throw std::invalid_argument ("mpf_set_str");
! 2050: }
! 2051: }
! 2052:
! 2053: explicit __gmp_expr(mpf_srcptr f)
! 2054: { mpf_init2(mp, mpf_get_prec(f)); mpf_set(mp, f); }
! 2055: __gmp_expr(mpf_srcptr f, mp_bitcnt_t prec)
! 2056: { mpf_init2(mp, prec); mpf_set(mp, f); }
! 2057:
! 2058: ~__gmp_expr() { mpf_clear(mp); }
! 2059:
! 2060: // assignment operators
! 2061: __gmp_expr & operator=(const __gmp_expr &f)
! 2062: { mpf_set(mp, f.mp); return *this; }
! 2063: template <class T, class U>
! 2064: __gmp_expr<value_type, value_type> & operator=(const __gmp_expr<T, U> &expr)
! 2065: { __gmp_set_expr(mp, expr); return *this; }
! 2066:
! 2067: __gmp_expr & operator=(signed char c) { mpf_set_si(mp, c); return *this; }
! 2068: __gmp_expr & operator=(unsigned char c) { mpf_set_ui(mp, c); return *this; }
! 2069:
! 2070: __gmp_expr & operator=(signed int i) { mpf_set_si(mp, i); return *this; }
! 2071: __gmp_expr & operator=(unsigned int i) { mpf_set_ui(mp, i); return *this; }
! 2072:
! 2073: __gmp_expr & operator=(signed short int s)
! 2074: { mpf_set_si(mp, s); return *this; }
! 2075: __gmp_expr & operator=(unsigned short int s)
! 2076: { mpf_set_ui(mp, s); return *this; }
! 2077:
! 2078: __gmp_expr & operator=(signed long int l)
! 2079: { mpf_set_si(mp, l); return *this; }
! 2080: __gmp_expr & operator=(unsigned long int l)
! 2081: { mpf_set_ui(mp, l); return *this; }
! 2082:
! 2083: #ifdef MPIRXX_HAVE_LLONG
! 2084: __gmp_expr & operator=(signed long long int l)
! 2085: { mpf_set_si(mp, l); return *this; }
! 2086: __gmp_expr & operator=(unsigned long long int l)
! 2087: { mpf_set_ui(mp, l); return *this; }
! 2088: #endif
! 2089:
! 2090: __gmp_expr & operator=(float f) { mpf_set_d(mp, f); return *this; }
! 2091: __gmp_expr & operator=(double d) { mpf_set_d(mp, d); return *this; }
! 2092: // __gmp_expr & operator=(long double ld)
! 2093: // { mpf_set_ld(mp, ld); return *this; }
! 2094:
! 2095: __gmp_expr & operator=(const char *s)
! 2096: {
! 2097: if (mpf_set_str (mp, s, 0) != 0)
! 2098: throw std::invalid_argument ("mpf_set_str");
! 2099: return *this;
! 2100: }
! 2101: __gmp_expr & operator=(const std::string &s)
! 2102: {
! 2103: if (mpf_set_str(mp, s.c_str(), 0) != 0)
! 2104: throw std::invalid_argument ("mpf_set_str");
! 2105: return *this;
! 2106: }
! 2107:
! 2108: // string input/output functions
! 2109: int set_str(const char *s, int base)
! 2110: { return mpf_set_str(mp, s, base); }
! 2111: int set_str(const std::string &s, int base)
! 2112: { return mpf_set_str(mp, s.c_str(), base); }
! 2113: std::string get_str(mp_exp_t &expo, int base = 10, size_t size = 0) const
! 2114: {
! 2115: __gmp_alloc_cstring temp(mpf_get_str(0, &expo, base, size, mp));
! 2116: return std::string(temp.str);
! 2117: }
! 2118:
! 2119: // conversion functions
! 2120: mpf_srcptr __get_mp() const { return mp; }
! 2121: mpf_ptr __get_mp() { return mp; }
! 2122: mpf_srcptr get_mpf_t() const { return mp; }
! 2123: mpf_ptr get_mpf_t() { return mp; }
! 2124:
! 2125: mpir_si get_si() const { return mpf_get_si(mp); }
! 2126: mpir_ui get_ui() const { return mpf_get_ui(mp); }
! 2127: double get_d() const { return mpf_get_d(mp); }
! 2128:
! 2129: // bool fits_schar_p() const { return mpf_fits_schar_p(mp); }
! 2130: // bool fits_uchar_p() const { return mpf_fits_uchar_p(mp); }
! 2131: bool fits_sint_p() const { return mpf_fits_sint_p(mp); }
! 2132: bool fits_uint_p() const { return mpf_fits_uint_p(mp); }
! 2133: bool fits_si_p() const { return mpf_fits_si_p(mp); }
! 2134: bool fits_ui_p() const { return mpf_fits_ui_p(mp); }
! 2135: bool fits_sshort_p() const { return mpf_fits_sshort_p(mp); }
! 2136: bool fits_ushort_p() const { return mpf_fits_ushort_p(mp); }
! 2137: bool fits_slong_p() const { return mpf_fits_slong_p(mp); }
! 2138: bool fits_ulong_p() const { return mpf_fits_ulong_p(mp); }
! 2139: // bool fits_float_p() const { return mpf_fits_float_p(mp); }
! 2140: // bool fits_double_p() const { return mpf_fits_double_p(mp); }
! 2141: // bool fits_ldouble_p() const { return mpf_fits_ldouble_p(mp); }
! 2142:
! 2143: // compound assignments
! 2144: __GMP_DECLARE_COMPOUND_OPERATOR(operator+=)
! 2145: __GMP_DECLARE_COMPOUND_OPERATOR(operator-=)
! 2146: __GMP_DECLARE_COMPOUND_OPERATOR(operator*=)
! 2147: __GMP_DECLARE_COMPOUND_OPERATOR(operator/=)
! 2148:
! 2149: __GMP_DECLARE_COMPOUND_OPERATOR_UI(operator<<=)
! 2150: __GMP_DECLARE_COMPOUND_OPERATOR_UI(operator>>=)
! 2151:
! 2152: __GMP_DECLARE_INCREMENT_OPERATOR(operator++)
! 2153: __GMP_DECLARE_INCREMENT_OPERATOR(operator--)
! 2154: };
! 2155:
! 2156: typedef __gmp_expr<mpf_t, mpf_t> mpf_class;
! 2157:
! 2158: /**************** I/O operators ****************/
! 2159:
! 2160: // these should (and will) be provided separately
! 2161:
! 2162: template <class T>
! 2163: inline std::ostream & operator<<
! 2164: (std::ostream &o, const __gmp_expr<T, T> &expr)
! 2165: {
! 2166: return o << expr.__get_mp();
! 2167: }
! 2168:
! 2169: template <class T, class U>
! 2170: inline std::ostream & operator<<
! 2171: (std::ostream &o, const __gmp_expr<T, U> &expr)
! 2172: {
! 2173: __gmp_expr<T, T> temp(expr);
! 2174: return o << temp.__get_mp();
! 2175: }
! 2176:
! 2177:
! 2178: template <class T>
! 2179: inline std::istream & operator>>(std::istream &i, __gmp_expr<T, T> &expr)
! 2180: {
! 2181: return i >> expr.__get_mp();
! 2182: }
! 2183:
! 2184: inline std::istream & operator>>(std::istream &i, mpq_class &q)
! 2185: {
! 2186: i >> q.get_mpq_t();
! 2187: // q.canonicalize(); // you might want to uncomment this
! 2188: return i;
! 2189: }
! 2190:
! 2191:
! 2192: /**************** Functions for type conversion ****************/
! 2193:
! 2194: template <>
! 2195: inline void __gmp_set_expr(mpz_ptr z, const mpz_class &w)
! 2196: {
! 2197: mpz_set(z, w.get_mpz_t());
! 2198: }
! 2199:
! 2200: template <class T>
! 2201: inline void __gmp_set_expr(mpz_ptr z, const __gmp_expr<mpz_t, T> &expr)
! 2202: {
! 2203: expr.eval(z);
! 2204: }
! 2205:
! 2206: template <>
! 2207: inline void __gmp_set_expr(mpz_ptr z, const mpq_class &q)
! 2208: {
! 2209: mpz_set_q(z, q.get_mpq_t());
! 2210: }
! 2211:
! 2212: template <class T>
! 2213: inline void __gmp_set_expr(mpz_ptr z, const __gmp_expr<mpq_t, T> &expr)
! 2214: {
! 2215: mpq_class temp(expr);
! 2216: mpz_set_q(z, temp.get_mpq_t());
! 2217: }
! 2218:
! 2219: template <class T>
! 2220: inline void __gmp_set_expr(mpz_ptr z, const mpf_class &f)
! 2221: {
! 2222: mpz_set_f(z, f.get_mpf_t());
! 2223: }
! 2224:
! 2225: template <class T>
! 2226: inline void __gmp_set_expr(mpz_ptr z, const __gmp_expr<mpf_t, T> &expr)
! 2227: {
! 2228: mpf_class temp(expr);
! 2229: mpz_set_f(z, temp.get_mpf_t());
! 2230: }
! 2231:
! 2232: template <>
! 2233: inline void __gmp_set_expr(mpq_ptr q, const mpz_class &z)
! 2234: {
! 2235: mpq_set_z(q, z.get_mpz_t());
! 2236: }
! 2237:
! 2238: template <class T>
! 2239: inline void __gmp_set_expr(mpq_ptr q, const __gmp_expr<mpz_t, T> &expr)
! 2240: {
! 2241: mpz_class temp(expr);
! 2242: mpq_set_z(q, temp.get_mpz_t());
! 2243: }
! 2244:
! 2245: template <>
! 2246: inline void __gmp_set_expr(mpq_ptr q, const mpq_class &r)
! 2247: {
! 2248: mpq_set(q, r.get_mpq_t());
! 2249: }
! 2250:
! 2251: template <class T>
! 2252: inline void __gmp_set_expr(mpq_ptr q, const __gmp_expr<mpq_t, T> &expr)
! 2253: {
! 2254: expr.eval(q);
! 2255: }
! 2256:
! 2257: template <class T>
! 2258: inline void __gmp_set_expr(mpq_ptr q, const mpf_class &f)
! 2259: {
! 2260: mpq_set_f(q, f.get_mpf_t());
! 2261: }
! 2262:
! 2263: template <class T>
! 2264: inline void __gmp_set_expr(mpq_ptr q, const __gmp_expr<mpf_t, T> &expr)
! 2265: {
! 2266: mpf_class temp(expr);
! 2267: mpq_set_f(q, temp.get_mpf_t());
! 2268: }
! 2269:
! 2270: template <class T>
! 2271: inline void __gmp_set_expr(mpf_ptr f, const mpz_class &z)
! 2272: {
! 2273: mpf_set_z(f, z.get_mpz_t());
! 2274: }
! 2275:
! 2276: template <class T>
! 2277: inline void __gmp_set_expr(mpf_ptr f, const __gmp_expr<mpz_t, T> &expr)
! 2278: {
! 2279: mpz_class temp(expr);
! 2280: mpf_set_z(f, temp.get_mpz_t());
! 2281: }
! 2282:
! 2283: template <class T>
! 2284: inline void __gmp_set_expr(mpf_ptr f, const mpq_class &q)
! 2285: {
! 2286: mpf_set_q(f, q.get_mpq_t());
! 2287: }
! 2288:
! 2289: template <class T>
! 2290: inline void __gmp_set_expr(mpf_ptr f, const __gmp_expr<mpq_t, T> &expr)
! 2291: {
! 2292: mpq_class temp(expr);
! 2293: mpf_set_q(f, temp.get_mpq_t());
! 2294: }
! 2295:
! 2296: template <>
! 2297: inline void __gmp_set_expr(mpf_ptr f, const mpf_class &g)
! 2298: {
! 2299: mpf_set(f, g.get_mpf_t());
! 2300: }
! 2301:
! 2302: template <class T>
! 2303: inline void __gmp_set_expr(mpf_ptr f, const __gmp_expr<mpf_t, T> &expr)
! 2304: {
! 2305: expr.eval(f, mpf_get_prec(f));
! 2306: }
! 2307:
! 2308:
! 2309: /**************** Specializations of __gmp_expr ****************/
! 2310: /* The eval() method of __gmp_expr<T, U> evaluates the corresponding
! 2311: expression and assigns the result to its argument, which is either an
! 2312: mpz_t, mpq_t, or mpf_t as specified by the T argument.
! 2313: Compound expressions are evaluated recursively (temporaries are created
! 2314: to hold intermediate values), while for simple expressions the eval()
! 2315: method of the appropriate function object (available as the Op argument
! 2316: of either __gmp_unary_expr<T, Op> or __gmp_binary_expr<T, U, Op>) is
! 2317: called. */
! 2318:
! 2319:
! 2320: /**************** Unary expressions ****************/
! 2321: /* cases:
! 2322: - simple: argument is mp*_class, that is, __gmp_expr<T, T>
! 2323: - compound: argument is __gmp_expr<T, U> (with U not equal to T) */
! 2324:
! 2325:
! 2326: // simple expressions
! 2327:
! 2328: template <class T, class Op>
! 2329: class __gmp_expr<T, __gmp_unary_expr<__gmp_expr<T, T>, Op> >
! 2330: {
! 2331: private:
! 2332: typedef __gmp_expr<T, T> val_type;
! 2333:
! 2334: __gmp_unary_expr<val_type, Op> expr;
! 2335: public:
! 2336: __gmp_expr(const val_type &val) : expr(val) { }
! 2337: void eval(typename __gmp_resolve_expr<T>::ptr_type p,
! 2338: mpir_ui = 0) const
! 2339: { Op::eval(p, expr.val.__get_mp()); }
! 2340: const val_type & get_val() const { return expr.val; }
! 2341: mp_bitcnt_t get_prec() const { return expr.val.get_prec(); }
! 2342: };
! 2343:
! 2344:
! 2345: // compound expressions
! 2346:
! 2347: template <class T, class U, class Op>
! 2348: class __gmp_expr<T, __gmp_unary_expr<__gmp_expr<T, U>, Op> >
! 2349: {
! 2350: private:
! 2351: typedef __gmp_expr<T, U> val_type;
! 2352:
! 2353: __gmp_unary_expr<val_type, Op> expr;
! 2354: public:
! 2355: __gmp_expr(const val_type &val) : expr(val) { }
! 2356: void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
! 2357: { __gmp_expr<T, T> temp(expr.val); Op::eval(p, temp.__get_mp()); }
! 2358: void eval(typename __gmp_resolve_expr<T>::ptr_type p,
! 2359: mp_bitcnt_t prec) const
! 2360: { __gmp_expr<T, T> temp(expr.val, prec); Op::eval(p, temp.__get_mp()); }
! 2361: const val_type & get_val() const { return expr.val; }
! 2362: mp_bitcnt_t get_prec() const { return expr.val.get_prec(); }
! 2363: };
! 2364:
! 2365:
! 2366: /**************** Binary expressions ****************/
! 2367: /* simple:
! 2368: - arguments are both mp*_class
! 2369: - one argument is mp*_class, one is a built-in type
! 2370: compound:
! 2371: - one is mp*_class, one is __gmp_expr<T, U>
! 2372: - one is __gmp_expr<T, U>, one is built-in
! 2373: - both arguments are __gmp_expr<...> */
! 2374:
! 2375:
! 2376: // simple expressions
! 2377:
! 2378: template <class T, class Op>
! 2379: class __gmp_expr
! 2380: <T, __gmp_binary_expr<__gmp_expr<T, T>, __gmp_expr<T, T>, Op> >
! 2381: {
! 2382: private:
! 2383: typedef __gmp_expr<T, T> val1_type;
! 2384: typedef __gmp_expr<T, T> val2_type;
! 2385:
! 2386: __gmp_binary_expr<val1_type, val2_type, Op> expr;
! 2387: public:
! 2388: __gmp_expr(const val1_type &val1, const val2_type &val2)
! 2389: : expr(val1, val2) { }
! 2390: void eval(typename __gmp_resolve_expr<T>::ptr_type p,
! 2391: mpir_ui = 0) const
! 2392: { Op::eval(p, expr.val1.__get_mp(), expr.val2.__get_mp()); }
! 2393: const val1_type & get_val1() const { return expr.val1; }
! 2394: const val2_type & get_val2() const { return expr.val2; }
! 2395: mp_bitcnt_t get_prec() const
! 2396: {
! 2397: mp_bitcnt_t prec1 = expr.val1.get_prec(),
! 2398: prec2 = expr.val2.get_prec();
! 2399: return (prec1 > prec2) ? prec1 : prec2;
! 2400: }
! 2401: };
! 2402:
! 2403:
! 2404: // simple expressions, T is a built-in numerical type
! 2405:
! 2406: template <class T, class U, class Op>
! 2407: class __gmp_expr<T, __gmp_binary_expr<__gmp_expr<T, T>, U, Op> >
! 2408: {
! 2409: private:
! 2410: typedef __gmp_expr<T, T> val1_type;
! 2411: typedef U val2_type;
! 2412:
! 2413: __gmp_binary_expr<val1_type, val2_type, Op> expr;
! 2414: public:
! 2415: __gmp_expr(const val1_type &val1, const val2_type &val2) : expr(val1, val2) { }
! 2416: void eval(typename __gmp_resolve_expr<T>::ptr_type p, mpir_ui = 0) const
! 2417: { Op::eval(p, expr.val1.__get_mp(), expr.val2); }
! 2418: const val1_type & get_val1() const { return expr.val1; }
! 2419: const val2_type & get_val2() const { return expr.val2; }
! 2420: mp_bitcnt_t get_prec() const { return expr.val1.get_prec(); }
! 2421: };
! 2422:
! 2423: template <class T, class U, class Op>
! 2424: class __gmp_expr<T, __gmp_binary_expr<U, __gmp_expr<T, T>, Op> >
! 2425: {
! 2426: private:
! 2427: typedef U val1_type;
! 2428: typedef __gmp_expr<T, T> val2_type;
! 2429:
! 2430: __gmp_binary_expr<val1_type, val2_type, Op> expr;
! 2431: public:
! 2432: __gmp_expr(const val1_type &val1, const val2_type &val2)
! 2433: : expr(val1, val2) { }
! 2434: void eval(typename __gmp_resolve_expr<T>::ptr_type p,
! 2435: mpir_ui = 0) const
! 2436: { Op::eval(p, expr.val1, expr.val2.__get_mp()); }
! 2437: const val1_type & get_val1() const { return expr.val1; }
! 2438: const val2_type & get_val2() const { return expr.val2; }
! 2439: mp_bitcnt_t get_prec() const { return expr.val2.get_prec(); }
! 2440: };
! 2441:
! 2442:
! 2443: // compound expressions, one argument is a subexpression
! 2444:
! 2445: template <class T, class U, class V, class Op>
! 2446: class __gmp_expr
! 2447: <T, __gmp_binary_expr<__gmp_expr<T, T>, __gmp_expr<U, V>, Op> >
! 2448: {
! 2449: private:
! 2450: typedef __gmp_expr<T, T> val1_type;
! 2451: typedef __gmp_expr<U, V> val2_type;
! 2452:
! 2453: __gmp_binary_expr<val1_type, val2_type, Op> expr;
! 2454: public:
! 2455: __gmp_expr(const val1_type &val1, const val2_type &val2)
! 2456: : expr(val1, val2) { }
! 2457: void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
! 2458: {
! 2459: __gmp_expr<T, T> temp(expr.val2);
! 2460: Op::eval(p, expr.val1.__get_mp(), temp.__get_mp());
! 2461: }
! 2462: void eval(typename __gmp_resolve_expr<T>::ptr_type p,
! 2463: mp_bitcnt_t prec) const
! 2464: {
! 2465: __gmp_expr<T, T> temp(expr.val2, prec);
! 2466: Op::eval(p, expr.val1.__get_mp(), temp.__get_mp());
! 2467: }
! 2468: const val1_type & get_val1() const { return expr.val1; }
! 2469: const val2_type & get_val2() const { return expr.val2; }
! 2470: mp_bitcnt_t get_prec() const
! 2471: {
! 2472: mp_bitcnt_t prec1 = expr.val1.get_prec(),
! 2473: prec2 = expr.val2.get_prec();
! 2474: return (prec1 > prec2) ? prec1 : prec2;
! 2475: }
! 2476: };
! 2477:
! 2478: template <class T, class U, class V, class Op>
! 2479: class __gmp_expr
! 2480: <T, __gmp_binary_expr<__gmp_expr<U, V>, __gmp_expr<T, T>, Op> >
! 2481: {
! 2482: private:
! 2483: typedef __gmp_expr<U, V> val1_type;
! 2484: typedef __gmp_expr<T, T> val2_type;
! 2485:
! 2486: __gmp_binary_expr<val1_type, val2_type, Op> expr;
! 2487: public:
! 2488: __gmp_expr(const val1_type &val1, const val2_type &val2)
! 2489: : expr(val1, val2) { }
! 2490: void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
! 2491: {
! 2492: __gmp_expr<T, T> temp(expr.val1);
! 2493: Op::eval(p, temp.__get_mp(), expr.val2.__get_mp());
! 2494: }
! 2495: void eval(typename __gmp_resolve_expr<T>::ptr_type p,
! 2496: mp_bitcnt_t prec) const
! 2497: {
! 2498: __gmp_expr<T, T> temp(expr.val1, prec);
! 2499: Op::eval(p, temp.__get_mp(), expr.val2.__get_mp());
! 2500: }
! 2501: const val1_type & get_val1() const { return expr.val1; }
! 2502: const val2_type & get_val2() const { return expr.val2; }
! 2503: mp_bitcnt_t get_prec() const
! 2504: {
! 2505: mp_bitcnt_t prec1 = expr.val1.get_prec(),
! 2506: prec2 = expr.val2.get_prec();
! 2507: return (prec1 > prec2) ? prec1 : prec2;
! 2508: }
! 2509: };
! 2510:
! 2511: template <class T, class U, class Op>
! 2512: class __gmp_expr
! 2513: <T, __gmp_binary_expr<__gmp_expr<T, T>, __gmp_expr<T, U>, Op> >
! 2514: {
! 2515: private:
! 2516: typedef __gmp_expr<T, T> val1_type;
! 2517: typedef __gmp_expr<T, U> val2_type;
! 2518:
! 2519: __gmp_binary_expr<val1_type, val2_type, Op> expr;
! 2520: public:
! 2521: __gmp_expr(const val1_type &val1, const val2_type &val2)
! 2522: : expr(val1, val2) { }
! 2523: void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
! 2524: {
! 2525: __gmp_expr<T, T> temp(expr.val2);
! 2526: Op::eval(p, expr.val1.__get_mp(), temp.__get_mp());
! 2527: }
! 2528: void eval(typename __gmp_resolve_expr<T>::ptr_type p,
! 2529: mp_bitcnt_t prec) const
! 2530: {
! 2531: __gmp_expr<T, T> temp(expr.val2, prec);
! 2532: Op::eval(p, expr.val1.__get_mp(), temp.__get_mp());
! 2533: }
! 2534: const val1_type & get_val1() const { return expr.val1; }
! 2535: const val2_type & get_val2() const { return expr.val2; }
! 2536: mp_bitcnt_t get_prec() const
! 2537: {
! 2538: mp_bitcnt_t prec1 = expr.val1.get_prec(),
! 2539: prec2 = expr.val2.get_prec();
! 2540: return (prec1 > prec2) ? prec1 : prec2;
! 2541: }
! 2542: };
! 2543:
! 2544: template <class T, class U, class Op>
! 2545: class __gmp_expr
! 2546: <T, __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<T, T>, Op> >
! 2547: {
! 2548: private:
! 2549: typedef __gmp_expr<T, U> val1_type;
! 2550: typedef __gmp_expr<T, T> val2_type;
! 2551:
! 2552: __gmp_binary_expr<val1_type, val2_type, Op> expr;
! 2553: public:
! 2554: __gmp_expr(const val1_type &val1, const val2_type &val2)
! 2555: : expr(val1, val2) { }
! 2556: void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
! 2557: {
! 2558: __gmp_expr<T, T> temp(expr.val1);
! 2559: Op::eval(p, temp.__get_mp(), expr.val2.__get_mp());
! 2560: }
! 2561: void eval(typename __gmp_resolve_expr<T>::ptr_type p,
! 2562: mp_bitcnt_t prec) const
! 2563: {
! 2564: __gmp_expr<T, T> temp(expr.val1, prec);
! 2565: Op::eval(p, temp.__get_mp(), expr.val2.__get_mp());
! 2566: }
! 2567: const val1_type & get_val1() const { return expr.val1; }
! 2568: const val2_type & get_val2() const { return expr.val2; }
! 2569: mp_bitcnt_t get_prec() const
! 2570: {
! 2571: mp_bitcnt_t prec1 = expr.val1.get_prec(),
! 2572: prec2 = expr.val2.get_prec();
! 2573: return (prec1 > prec2) ? prec1 : prec2;
! 2574: }
! 2575: };
! 2576:
! 2577:
! 2578: // one argument is a subexpression, one is a built-in
! 2579:
! 2580: template <class T, class U, class V, class Op>
! 2581: class __gmp_expr<T, __gmp_binary_expr<__gmp_expr<T, U>, V, Op> >
! 2582: {
! 2583: private:
! 2584: typedef __gmp_expr<T, U> val1_type;
! 2585: typedef V val2_type;
! 2586:
! 2587: __gmp_binary_expr<val1_type, val2_type, Op> expr;
! 2588: public:
! 2589: __gmp_expr(const val1_type &val1, const val2_type &val2)
! 2590: : expr(val1, val2) { }
! 2591: void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
! 2592: {
! 2593: __gmp_expr<T, T> temp(expr.val1);
! 2594: Op::eval(p, temp.__get_mp(), expr.val2);
! 2595: }
! 2596: void eval(typename __gmp_resolve_expr<T>::ptr_type p,
! 2597: mp_bitcnt_t prec) const
! 2598: {
! 2599: __gmp_expr<T, T> temp(expr.val1, prec);
! 2600: Op::eval(p, temp.__get_mp(), expr.val2);
! 2601: }
! 2602: const val1_type & get_val1() const { return expr.val1; }
! 2603: const val2_type & get_val2() const { return expr.val2; }
! 2604: mp_bitcnt_t get_prec() const { return expr.val1.get_prec(); }
! 2605: };
! 2606:
! 2607: template <class T, class U, class V, class Op>
! 2608: class __gmp_expr<T, __gmp_binary_expr<U, __gmp_expr<T, V>, Op> >
! 2609: {
! 2610: private:
! 2611: typedef U val1_type;
! 2612: typedef __gmp_expr<T, V> val2_type;
! 2613:
! 2614: __gmp_binary_expr<val1_type, val2_type, Op> expr;
! 2615: public:
! 2616: __gmp_expr(const val1_type &val1, const val2_type &val2)
! 2617: : expr(val1, val2) { }
! 2618: void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
! 2619: {
! 2620: __gmp_expr<T, T> temp(expr.val2);
! 2621: Op::eval(p, expr.val1, temp.__get_mp());
! 2622: }
! 2623: void eval(typename __gmp_resolve_expr<T>::ptr_type p,
! 2624: mp_bitcnt_t prec) const
! 2625: {
! 2626: __gmp_expr<T, T> temp(expr.val2, prec);
! 2627: Op::eval(p, expr.val1, temp.__get_mp());
! 2628: }
! 2629: const val1_type & get_val1() const { return expr.val1; }
! 2630: const val2_type & get_val2() const { return expr.val2; }
! 2631: mp_bitcnt_t get_prec() const { return expr.val2.get_prec(); }
! 2632: };
! 2633:
! 2634:
! 2635: // both arguments are subexpressions
! 2636:
! 2637: template <class T, class U, class V, class W, class Op>
! 2638: class __gmp_expr
! 2639: <T, __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<V, W>, Op> >
! 2640: {
! 2641: private:
! 2642: typedef __gmp_expr<T, U> val1_type;
! 2643: typedef __gmp_expr<V, W> val2_type;
! 2644:
! 2645: __gmp_binary_expr<val1_type, val2_type, Op> expr;
! 2646: public:
! 2647: __gmp_expr(const val1_type &val1, const val2_type &val2)
! 2648: : expr(val1, val2) { }
! 2649: void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
! 2650: {
! 2651: __gmp_expr<T, T> temp1(expr.val1), temp2(expr.val2);
! 2652: Op::eval(p, temp1.__get_mp(), temp2.__get_mp());
! 2653: }
! 2654: void eval(typename __gmp_resolve_expr<T>::ptr_type p,
! 2655: mp_bitcnt_t prec) const
! 2656: {
! 2657: __gmp_expr<T, T> temp1(expr.val1, prec), temp2(expr.val2, prec);
! 2658: Op::eval(p, temp1.__get_mp(), temp2.__get_mp());
! 2659: }
! 2660: const val1_type & get_val1() const { return expr.val1; }
! 2661: const val2_type & get_val2() const { return expr.val2; }
! 2662: mp_bitcnt_t get_prec() const
! 2663: {
! 2664: mp_bitcnt_t prec1 = expr.val1.get_prec(),
! 2665: prec2 = expr.val2.get_prec();
! 2666: return (prec1 > prec2) ? prec1 : prec2;
! 2667: }
! 2668: };
! 2669:
! 2670: template <class T, class U, class V, class W, class Op>
! 2671: class __gmp_expr
! 2672: <T, __gmp_binary_expr<__gmp_expr<U, V>, __gmp_expr<T, W>, Op> >
! 2673: {
! 2674: private:
! 2675: typedef __gmp_expr<U, V> val1_type;
! 2676: typedef __gmp_expr<T, W> val2_type;
! 2677:
! 2678: __gmp_binary_expr<val1_type, val2_type, Op> expr;
! 2679: public:
! 2680: __gmp_expr(const val1_type &val1, const val2_type &val2)
! 2681: : expr(val1, val2) { }
! 2682: void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
! 2683: {
! 2684: __gmp_expr<T, T> temp1(expr.val1), temp2(expr.val2);
! 2685: Op::eval(p, temp1.__get_mp(), temp2.__get_mp());
! 2686: }
! 2687: void eval(typename __gmp_resolve_expr<T>::ptr_type p,
! 2688: mp_bitcnt_t prec) const
! 2689: {
! 2690: __gmp_expr<T, T> temp1(expr.val1, prec), temp2(expr.val2, prec);
! 2691: Op::eval(p, temp1.__get_mp(), temp2.__get_mp());
! 2692: }
! 2693: const val1_type & get_val1() const { return expr.val1; }
! 2694: const val2_type & get_val2() const { return expr.val2; }
! 2695: mp_bitcnt_t get_prec() const
! 2696: {
! 2697: mp_bitcnt_t prec1 = expr.val1.get_prec(),
! 2698: prec2 = expr.val2.get_prec();
! 2699: return (prec1 > prec2) ? prec1 : prec2;
! 2700: }
! 2701: };
! 2702:
! 2703: template <class T, class U, class V, class Op>
! 2704: class __gmp_expr
! 2705: <T, __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<T, V>, Op> >
! 2706: {
! 2707: private:
! 2708: typedef __gmp_expr<T, U> val1_type;
! 2709: typedef __gmp_expr<T, V> val2_type;
! 2710:
! 2711: __gmp_binary_expr<val1_type, val2_type, Op> expr;
! 2712: public:
! 2713: __gmp_expr(const val1_type &val1, const val2_type &val2)
! 2714: : expr(val1, val2) { }
! 2715: void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
! 2716: {
! 2717: __gmp_expr<T, T> temp1(expr.val1), temp2(expr.val2);
! 2718: Op::eval(p, temp1.__get_mp(), temp2.__get_mp());
! 2719: }
! 2720: void eval(typename __gmp_resolve_expr<T>::ptr_type p,
! 2721: mp_bitcnt_t prec) const
! 2722: {
! 2723: __gmp_expr<T, T> temp1(expr.val1, prec), temp2(expr.val2, prec);
! 2724: Op::eval(p, temp1.__get_mp(), temp2.__get_mp());
! 2725: }
! 2726: const val1_type & get_val1() const { return expr.val1; }
! 2727: const val2_type & get_val2() const { return expr.val2; }
! 2728: mp_bitcnt_t get_prec() const
! 2729: {
! 2730: mp_bitcnt_t prec1 = expr.val1.get_prec(),
! 2731: prec2 = expr.val2.get_prec();
! 2732: return (prec1 > prec2) ? prec1 : prec2;
! 2733: }
! 2734: };
! 2735:
! 2736:
! 2737: /**************** Special cases ****************/
! 2738:
! 2739: /* Some operations (i.e., add and subtract) with mixed mpz/mpq arguments
! 2740: can be done directly without first converting the mpz to mpq.
! 2741: Appropriate specializations of __gmp_expr are required. */
! 2742:
! 2743:
! 2744: #define __GMPZQ_DEFINE_EXPR(eval_fun) \
! 2745: \
! 2746: template <> \
! 2747: class __gmp_expr<mpq_t, __gmp_binary_expr<mpz_class, mpq_class, eval_fun> > \
! 2748: { \
! 2749: private: \
! 2750: typedef mpz_class val1_type; \
! 2751: typedef mpq_class val2_type; \
! 2752: \
! 2753: __gmp_binary_expr<val1_type, val2_type, eval_fun> expr; \
! 2754: public: \
! 2755: __gmp_expr(const val1_type &val1, const val2_type &val2) \
! 2756: : expr(val1, val2) { } \
! 2757: void eval(mpq_ptr q) const \
! 2758: { eval_fun::eval(q, expr.val1.get_mpz_t(), expr.val2.get_mpq_t()); } \
! 2759: const val1_type & get_val1() const { return expr.val1; } \
! 2760: const val2_type & get_val2() const { return expr.val2; } \
! 2761: mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); } \
! 2762: }; \
! 2763: \
! 2764: template <> \
! 2765: class __gmp_expr<mpq_t, __gmp_binary_expr<mpq_class, mpz_class, eval_fun> > \
! 2766: { \
! 2767: private: \
! 2768: typedef mpq_class val1_type; \
! 2769: typedef mpz_class val2_type; \
! 2770: \
! 2771: __gmp_binary_expr<val1_type, val2_type, eval_fun> expr; \
! 2772: public: \
! 2773: __gmp_expr(const val1_type &val1, const val2_type &val2) \
! 2774: : expr(val1, val2) { } \
! 2775: void eval(mpq_ptr q) const \
! 2776: { eval_fun::eval(q, expr.val1.get_mpq_t(), expr.val2.get_mpz_t()); } \
! 2777: const val1_type & get_val1() const { return expr.val1; } \
! 2778: const val2_type & get_val2() const { return expr.val2; } \
! 2779: mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); } \
! 2780: }; \
! 2781: \
! 2782: template <class T> \
! 2783: class __gmp_expr \
! 2784: <mpq_t, __gmp_binary_expr<mpz_class, __gmp_expr<mpq_t, T>, eval_fun> > \
! 2785: { \
! 2786: private: \
! 2787: typedef mpz_class val1_type; \
! 2788: typedef __gmp_expr<mpq_t, T> val2_type; \
! 2789: \
! 2790: __gmp_binary_expr<val1_type, val2_type, eval_fun> expr; \
! 2791: public: \
! 2792: __gmp_expr(const val1_type &val1, const val2_type &val2) \
! 2793: : expr(val1, val2) { } \
! 2794: void eval(mpq_ptr q) const \
! 2795: { \
! 2796: mpq_class temp(expr.val2); \
! 2797: eval_fun::eval(q, expr.val1.get_mpz_t(), temp.get_mpq_t()); \
! 2798: } \
! 2799: const val1_type & get_val1() const { return expr.val1; } \
! 2800: const val2_type & get_val2() const { return expr.val2; } \
! 2801: mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); } \
! 2802: }; \
! 2803: \
! 2804: template <class T> \
! 2805: class __gmp_expr \
! 2806: <mpq_t, __gmp_binary_expr<mpq_class, __gmp_expr<mpz_t, T>, eval_fun> > \
! 2807: { \
! 2808: private: \
! 2809: typedef mpq_class val1_type; \
! 2810: typedef __gmp_expr<mpz_t, T> val2_type; \
! 2811: \
! 2812: __gmp_binary_expr<val1_type, val2_type, eval_fun> expr; \
! 2813: public: \
! 2814: __gmp_expr(const val1_type &val1, const val2_type &val2) \
! 2815: : expr(val1, val2) { } \
! 2816: void eval(mpq_ptr q) const \
! 2817: { \
! 2818: mpz_class temp(expr.val2); \
! 2819: eval_fun::eval(q, expr.val1.get_mpq_t(), temp.get_mpz_t()); \
! 2820: } \
! 2821: const val1_type & get_val1() const { return expr.val1; } \
! 2822: const val2_type & get_val2() const { return expr.val2; } \
! 2823: mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); } \
! 2824: }; \
! 2825: \
! 2826: template <class T> \
! 2827: class __gmp_expr \
! 2828: <mpq_t, __gmp_binary_expr<__gmp_expr<mpz_t, T>, mpq_class, eval_fun> > \
! 2829: { \
! 2830: private: \
! 2831: typedef __gmp_expr<mpz_t, T> val1_type; \
! 2832: typedef mpq_class val2_type; \
! 2833: \
! 2834: __gmp_binary_expr<val1_type, val2_type, eval_fun> expr; \
! 2835: public: \
! 2836: __gmp_expr(const val1_type &val1, const val2_type &val2) \
! 2837: : expr(val1, val2) { } \
! 2838: void eval(mpq_ptr q) const \
! 2839: { \
! 2840: mpz_class temp(expr.val1); \
! 2841: eval_fun::eval(q, temp.get_mpz_t(), expr.val2.get_mpq_t()); \
! 2842: } \
! 2843: const val1_type & get_val1() const { return expr.val1; } \
! 2844: const val2_type & get_val2() const { return expr.val2; } \
! 2845: mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); } \
! 2846: }; \
! 2847: \
! 2848: template <class T> \
! 2849: class __gmp_expr \
! 2850: <mpq_t, __gmp_binary_expr<__gmp_expr<mpq_t, T>, mpz_class, eval_fun> > \
! 2851: { \
! 2852: private: \
! 2853: typedef __gmp_expr<mpq_t, T> val1_type; \
! 2854: typedef mpz_class val2_type; \
! 2855: \
! 2856: __gmp_binary_expr<val1_type, val2_type, eval_fun> expr; \
! 2857: public: \
! 2858: __gmp_expr(const val1_type &val1, const val2_type &val2) \
! 2859: : expr(val1, val2) { } \
! 2860: void eval(mpq_ptr q) const \
! 2861: { \
! 2862: mpq_class temp(expr.val1); \
! 2863: eval_fun::eval(q, temp.get_mpq_t(), expr.val2.get_mpz_t()); \
! 2864: } \
! 2865: const val1_type & get_val1() const { return expr.val1; } \
! 2866: const val2_type & get_val2() const { return expr.val2; } \
! 2867: mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); } \
! 2868: }; \
! 2869: \
! 2870: template <class T, class U> \
! 2871: class __gmp_expr<mpq_t, __gmp_binary_expr \
! 2872: <__gmp_expr<mpz_t, T>, __gmp_expr<mpq_t, U>, eval_fun> > \
! 2873: { \
! 2874: private: \
! 2875: typedef __gmp_expr<mpz_t, T> val1_type; \
! 2876: typedef __gmp_expr<mpq_t, U> val2_type; \
! 2877: \
! 2878: __gmp_binary_expr<val1_type, val2_type, eval_fun> expr; \
! 2879: public: \
! 2880: __gmp_expr(const val1_type &val1, const val2_type &val2) \
! 2881: : expr(val1, val2) { } \
! 2882: void eval(mpq_ptr q) const \
! 2883: { \
! 2884: mpz_class temp1(expr.val1); \
! 2885: mpq_class temp2(expr.val2); \
! 2886: eval_fun::eval(q, temp1.get_mpz_t(), temp2.get_mpq_t()); \
! 2887: } \
! 2888: const val1_type & get_val1() const { return expr.val1; } \
! 2889: const val2_type & get_val2() const { return expr.val2; } \
! 2890: mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); } \
! 2891: }; \
! 2892: \
! 2893: template <class T, class U> \
! 2894: class __gmp_expr<mpq_t, __gmp_binary_expr \
! 2895: <__gmp_expr<mpq_t, T>, __gmp_expr<mpz_t, U>, eval_fun> > \
! 2896: { \
! 2897: private: \
! 2898: typedef __gmp_expr<mpq_t, T> val1_type; \
! 2899: typedef __gmp_expr<mpz_t, U> val2_type; \
! 2900: \
! 2901: __gmp_binary_expr<val1_type, val2_type, eval_fun> expr; \
! 2902: public: \
! 2903: __gmp_expr(const val1_type &val1, const val2_type &val2) \
! 2904: : expr(val1, val2) { } \
! 2905: void eval(mpq_ptr q) const \
! 2906: { \
! 2907: mpq_class temp1(expr.val1); \
! 2908: mpz_class temp2(expr.val2); \
! 2909: eval_fun::eval(q, temp1.get_mpq_t(), temp2.get_mpz_t()); \
! 2910: } \
! 2911: const val1_type & get_val1() const { return expr.val1; } \
! 2912: const val2_type & get_val2() const { return expr.val2; } \
! 2913: mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); } \
! 2914: };
! 2915:
! 2916:
! 2917: __GMPZQ_DEFINE_EXPR(__gmp_binary_plus)
! 2918: __GMPZQ_DEFINE_EXPR(__gmp_binary_minus)
! 2919:
! 2920: /**************** Macros for defining functions ****************/
! 2921: /* Results of operators and functions are instances of __gmp_expr<T, U>.
! 2922: T determines the numerical type of the expression: it can be either
! 2923: mpz_t, mpq_t, or mpf_t. When the arguments of a binary
! 2924: expression have different numerical types, __gmp_resolve_expr is used
! 2925: to determine the "larger" type.
! 2926: U is either __gmp_unary_expr<V, Op> or __gmp_binary_expr<V, W, Op>,
! 2927: where V and W are the arguments' types -- they can in turn be
! 2928: expressions, thus allowing to build compound expressions to any
! 2929: degree of complexity.
! 2930: Op is a function object that must have an eval() method accepting
! 2931: appropriate arguments.
! 2932: Actual evaluation of a __gmp_expr<T, U> object is done when it gets
! 2933: assigned to an mp*_class ("lazy" evaluation): this is done by calling
! 2934: its eval() method. */
! 2935:
! 2936:
! 2937: // non-member unary operators and functions
! 2938:
! 2939: #define __GMP_DEFINE_UNARY_FUNCTION(fun, eval_fun) \
! 2940: \
! 2941: template <class T, class U> \
! 2942: inline __gmp_expr<T, __gmp_unary_expr<__gmp_expr<T, U>, eval_fun> > \
! 2943: fun(const __gmp_expr<T, U> &expr) \
! 2944: { \
! 2945: return __gmp_expr<T, __gmp_unary_expr<__gmp_expr<T, U>, eval_fun> >(expr); \
! 2946: }
! 2947:
! 2948: #define __GMP_DEFINE_UNARY_TYPE_FUNCTION(type, fun, eval_fun) \
! 2949: \
! 2950: template <class T, class U> \
! 2951: inline type fun(const __gmp_expr<T, U> &expr) \
! 2952: { \
! 2953: typename __gmp_resolve_temp<T, T, U>::temp_type temp(expr); \
! 2954: return eval_fun::eval(temp.__get_mp()); \
! 2955: }
! 2956:
! 2957:
! 2958: // non-member binary operators and functions
! 2959:
! 2960: #define __GMPP_DEFINE_BINARY_FUNCTION(fun, eval_fun) \
! 2961: \
! 2962: template <class T, class U, class V, class W> \
! 2963: inline __gmp_expr<typename __gmp_resolve_expr<T, V>::value_type, \
! 2964: __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<V, W>, eval_fun> > \
! 2965: fun(const __gmp_expr<T, U> &expr1, const __gmp_expr<V, W> &expr2) \
! 2966: { \
! 2967: return __gmp_expr<typename __gmp_resolve_expr<T, V>::value_type, \
! 2968: __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<V, W>, eval_fun> > \
! 2969: (expr1, expr2); \
! 2970: }
! 2971:
! 2972: #define __GMPNN_DEFINE_BINARY_FUNCTION(fun, eval_fun, type, bigtype) \
! 2973: \
! 2974: template <class T, class U> \
! 2975: inline __gmp_expr \
! 2976: <T, __gmp_binary_expr<__gmp_expr<T, U>, bigtype, eval_fun> > \
! 2977: fun(const __gmp_expr<T, U> &expr, type t) \
! 2978: { \
! 2979: return __gmp_expr \
! 2980: <T, __gmp_binary_expr<__gmp_expr<T, U>, bigtype, eval_fun> >(expr, t); \
! 2981: } \
! 2982: \
! 2983: template <class T, class U> \
! 2984: inline __gmp_expr \
! 2985: <T, __gmp_binary_expr<bigtype, __gmp_expr<T, U>, eval_fun> > \
! 2986: fun(type t, const __gmp_expr<T, U> &expr) \
! 2987: { \
! 2988: return __gmp_expr \
! 2989: <T, __gmp_binary_expr<bigtype, __gmp_expr<T, U>, eval_fun> >(t, expr); \
! 2990: }
! 2991:
! 2992: #define __GMPNS_DEFINE_BINARY_FUNCTION(fun, eval_fun, type) \
! 2993: __GMPNN_DEFINE_BINARY_FUNCTION(fun, eval_fun, type, mpir_si)
! 2994:
! 2995: #define __GMPNU_DEFINE_BINARY_FUNCTION(fun, eval_fun, type) \
! 2996: __GMPNN_DEFINE_BINARY_FUNCTION(fun, eval_fun, type, mpir_ui)
! 2997:
! 2998: #define __GMPND_DEFINE_BINARY_FUNCTION(fun, eval_fun, type) \
! 2999: __GMPNN_DEFINE_BINARY_FUNCTION(fun, eval_fun, type, double)
! 3000:
! 3001: #define __GMPNLD_DEFINE_BINARY_FUNCTION(fun, eval_fun, type) \
! 3002: __GMPNN_DEFINE_BINARY_FUNCTION(fun, eval_fun, type, long double)
! 3003:
! 3004: #ifdef MPIRXX_HAVE_LLONG
! 3005: #define __GMPN_DEFINE_BINARY_FUNCTION(fun, eval_fun) \
! 3006: __GMPNS_DEFINE_BINARY_FUNCTION(fun, eval_fun, signed char) \
! 3007: __GMPNU_DEFINE_BINARY_FUNCTION(fun, eval_fun, unsigned char) \
! 3008: __GMPNS_DEFINE_BINARY_FUNCTION(fun, eval_fun, signed int) \
! 3009: __GMPNU_DEFINE_BINARY_FUNCTION(fun, eval_fun, unsigned int) \
! 3010: __GMPNS_DEFINE_BINARY_FUNCTION(fun, eval_fun, signed short int) \
! 3011: __GMPNU_DEFINE_BINARY_FUNCTION(fun, eval_fun, unsigned short int) \
! 3012: __GMPNS_DEFINE_BINARY_FUNCTION(fun, eval_fun, signed long int) \
! 3013: __GMPNU_DEFINE_BINARY_FUNCTION(fun, eval_fun, unsigned long int) \
! 3014: __GMPNS_DEFINE_BINARY_FUNCTION(fun, eval_fun, signed long long int) \
! 3015: __GMPNU_DEFINE_BINARY_FUNCTION(fun, eval_fun, unsigned long long int) \
! 3016: __GMPND_DEFINE_BINARY_FUNCTION(fun, eval_fun, float) \
! 3017: __GMPND_DEFINE_BINARY_FUNCTION(fun, eval_fun, double) \
! 3018: __GMPNLD_DEFINE_BINARY_FUNCTION(fun, eval_fun, long double)
! 3019: #else
! 3020: #define __GMPN_DEFINE_BINARY_FUNCTION(fun, eval_fun) \
! 3021: __GMPNS_DEFINE_BINARY_FUNCTION(fun, eval_fun, signed char) \
! 3022: __GMPNU_DEFINE_BINARY_FUNCTION(fun, eval_fun, unsigned char) \
! 3023: __GMPNS_DEFINE_BINARY_FUNCTION(fun, eval_fun, signed int) \
! 3024: __GMPNU_DEFINE_BINARY_FUNCTION(fun, eval_fun, unsigned int) \
! 3025: __GMPNS_DEFINE_BINARY_FUNCTION(fun, eval_fun, signed short int) \
! 3026: __GMPNU_DEFINE_BINARY_FUNCTION(fun, eval_fun, unsigned short int) \
! 3027: __GMPNS_DEFINE_BINARY_FUNCTION(fun, eval_fun, signed long int) \
! 3028: __GMPNU_DEFINE_BINARY_FUNCTION(fun, eval_fun, unsigned long int) \
! 3029: __GMPND_DEFINE_BINARY_FUNCTION(fun, eval_fun, float) \
! 3030: __GMPND_DEFINE_BINARY_FUNCTION(fun, eval_fun, double) \
! 3031: __GMPNLD_DEFINE_BINARY_FUNCTION(fun, eval_fun, long double)
! 3032: #endif
! 3033:
! 3034: #define __GMP_DEFINE_BINARY_FUNCTION(fun, eval_fun) \
! 3035: __GMPP_DEFINE_BINARY_FUNCTION(fun, eval_fun) \
! 3036: __GMPN_DEFINE_BINARY_FUNCTION(fun, eval_fun)
! 3037:
! 3038:
! 3039: #define __GMP_DEFINE_BINARY_FUNCTION_UI(fun, eval_fun) \
! 3040: \
! 3041: template <class T, class U> \
! 3042: inline __gmp_expr \
! 3043: <T, __gmp_binary_expr<__gmp_expr<T, U>, mpir_ui, eval_fun> > \
! 3044: fun(const __gmp_expr<T, U> &expr, mpir_ui l) \
! 3045: { \
! 3046: return __gmp_expr<T, __gmp_binary_expr \
! 3047: <__gmp_expr<T, U>, mpir_ui, eval_fun> >(expr, l); \
! 3048: }
! 3049:
! 3050:
! 3051: #define __GMPP_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun) \
! 3052: \
! 3053: template <class T, class U, class V, class W> \
! 3054: inline type fun(const __gmp_expr<T, U> &expr1, \
! 3055: const __gmp_expr<V, W> &expr2) \
! 3056: { \
! 3057: typedef typename __gmp_resolve_expr<T, V>::value_type eval_type; \
! 3058: typename __gmp_resolve_temp<eval_type, T, U>::temp_type temp1(expr1); \
! 3059: typename __gmp_resolve_temp<eval_type, V, W>::temp_type temp2(expr2); \
! 3060: return eval_fun::eval(temp1.__get_mp(), temp2.__get_mp()); \
! 3061: }
! 3062:
! 3063: #define __GMPNN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, \
! 3064: type2, bigtype) \
! 3065: \
! 3066: template <class T, class U> \
! 3067: inline type fun(const __gmp_expr<T, U> &expr, type2 t) \
! 3068: { \
! 3069: typename __gmp_resolve_temp<T, T, U>::temp_type temp(expr); \
! 3070: return eval_fun::eval(temp.__get_mp(), static_cast<bigtype>(t)); \
! 3071: } \
! 3072: \
! 3073: template <class T, class U> \
! 3074: inline type fun(type2 t, const __gmp_expr<T, U> &expr) \
! 3075: { \
! 3076: typename __gmp_resolve_temp<T, T, U>::temp_type temp(expr); \
! 3077: return eval_fun::eval(static_cast<bigtype>(t), temp.__get_mp()); \
! 3078: }
! 3079:
! 3080: #define __GMPNS_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, type2) \
! 3081: __GMPNN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, \
! 3082: type2, mpir_si)
! 3083:
! 3084: #define __GMPNU_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, type2) \
! 3085: __GMPNN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, \
! 3086: type2, mpir_ui)
! 3087:
! 3088: #define __GMPND_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, type2) \
! 3089: __GMPNN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, type2, double)
! 3090:
! 3091: #define __GMPNLD_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, type2) \
! 3092: __GMPNN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, type2, long double)
! 3093:
! 3094: #ifdef MPIRXX_HAVE_LLONG
! 3095: #define __GMPN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun) \
! 3096: __GMPNS_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, signed char) \
! 3097: __GMPNU_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, unsigned char) \
! 3098: __GMPNS_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, signed int) \
! 3099: __GMPNU_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, unsigned int) \
! 3100: __GMPNS_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, signed short int) \
! 3101: __GMPNU_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, unsigned short int) \
! 3102: __GMPNS_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, signed long int) \
! 3103: __GMPNU_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, unsigned long int) \
! 3104: __GMPNS_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, signed long long int) \
! 3105: __GMPNU_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, unsigned long long int) \
! 3106: __GMPND_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, float) \
! 3107: __GMPND_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, double) \
! 3108: __GMPNLD_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, long double)
! 3109: #else
! 3110: #define __GMPN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun) \
! 3111: __GMPNS_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, signed char) \
! 3112: __GMPNU_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, unsigned char) \
! 3113: __GMPNS_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, signed int) \
! 3114: __GMPNU_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, unsigned int) \
! 3115: __GMPNS_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, signed short int) \
! 3116: __GMPNU_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, unsigned short int) \
! 3117: __GMPNS_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, signed long int) \
! 3118: __GMPNU_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, unsigned long int) \
! 3119: __GMPND_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, float) \
! 3120: __GMPND_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, double) \
! 3121: __GMPNLD_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, long double)
! 3122: #endif
! 3123:
! 3124: #define __GMP_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun) \
! 3125: __GMPP_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun) \
! 3126: __GMPN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun)
! 3127:
! 3128:
! 3129: // member operators
! 3130:
! 3131: #define __GMPP_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun) \
! 3132: \
! 3133: template <class T, class U> \
! 3134: inline type##_class & type##_class::fun(const __gmp_expr<T, U> &expr) \
! 3135: { \
! 3136: __gmp_set_expr(mp, __gmp_expr<type##_t, __gmp_binary_expr \
! 3137: <type##_class, __gmp_expr<T, U>, eval_fun> >(*this, expr)); \
! 3138: return *this; \
! 3139: }
! 3140:
! 3141: #define __GMPNN_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, \
! 3142: type2, bigtype) \
! 3143: \
! 3144: inline type##_class & type##_class::fun(type2 t) \
! 3145: { \
! 3146: __gmp_set_expr(mp, __gmp_expr<type##_t, __gmp_binary_expr \
! 3147: <type##_class, bigtype, eval_fun> >(*this, t)); \
! 3148: return *this; \
! 3149: }
! 3150:
! 3151: #define __GMPNS_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, type2) \
! 3152: __GMPNN_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, \
! 3153: type2, mpir_si)
! 3154:
! 3155: #define __GMPNU_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, type2) \
! 3156: __GMPNN_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, \
! 3157: type2, mpir_ui)
! 3158:
! 3159: #define __GMPND_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, type2) \
! 3160: __GMPNN_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, type2, double)
! 3161:
! 3162: #define __GMPNLD_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, type2) \
! 3163: __GMPNN_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, type2, long double)
! 3164:
! 3165: #ifdef MPIRXX_HAVE_LLONG
! 3166: #define __GMPN_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun) \
! 3167: __GMPNS_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, signed char) \
! 3168: __GMPNU_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, unsigned char) \
! 3169: __GMPNS_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, signed int) \
! 3170: __GMPNU_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, unsigned int) \
! 3171: __GMPNS_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, signed short int) \
! 3172: __GMPNU_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, unsigned short int) \
! 3173: __GMPNS_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, signed long int) \
! 3174: __GMPNU_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, unsigned long int) \
! 3175: __GMPNS_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, signed long long int) \
! 3176: __GMPNU_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, unsigned long long int) \
! 3177: __GMPND_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, float) \
! 3178: __GMPND_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, double) \
! 3179: /* __GMPNLD_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, long double) */
! 3180: #else
! 3181: #define __GMPN_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun) \
! 3182: __GMPNS_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, signed char) \
! 3183: __GMPNU_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, unsigned char) \
! 3184: __GMPNS_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, signed int) \
! 3185: __GMPNU_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, unsigned int) \
! 3186: __GMPNS_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, signed short int) \
! 3187: __GMPNU_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, unsigned short int) \
! 3188: __GMPNS_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, signed long int) \
! 3189: __GMPNU_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, unsigned long int) \
! 3190: __GMPND_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, float) \
! 3191: __GMPND_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, double) \
! 3192: /* __GMPNLD_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, long double) */
! 3193: #endif
! 3194: #define __GMP_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun) \
! 3195: __GMPP_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun) \
! 3196: __GMPN_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun)
! 3197:
! 3198: #define __GMPZ_DEFINE_COMPOUND_OPERATOR(fun, eval_fun) \
! 3199: __GMP_DEFINE_COMPOUND_OPERATOR(mpz, fun, eval_fun)
! 3200:
! 3201: #define __GMPZZ_DEFINE_COMPOUND_OPERATOR(fun, eval_fun) \
! 3202: __GMPP_DEFINE_COMPOUND_OPERATOR(mpz, fun, eval_fun)
! 3203:
! 3204: #define __GMPQ_DEFINE_COMPOUND_OPERATOR(fun, eval_fun) \
! 3205: __GMP_DEFINE_COMPOUND_OPERATOR(mpq, fun, eval_fun)
! 3206:
! 3207: #define __GMPF_DEFINE_COMPOUND_OPERATOR(fun, eval_fun) \
! 3208: __GMP_DEFINE_COMPOUND_OPERATOR(mpf, fun, eval_fun)
! 3209:
! 3210:
! 3211:
! 3212: #define __GMP_DEFINE_COMPOUND_OPERATOR_UI(type, fun, eval_fun) \
! 3213: \
! 3214: inline type##_class & type##_class::fun(mpir_ui l) \
! 3215: { \
! 3216: __gmp_set_expr(mp, __gmp_expr<type##_t, __gmp_binary_expr \
! 3217: <type##_class, mpir_ui, eval_fun> >(*this, l)); \
! 3218: return *this; \
! 3219: }
! 3220:
! 3221: #define __GMPZ_DEFINE_COMPOUND_OPERATOR_UI(fun, eval_fun) \
! 3222: __GMP_DEFINE_COMPOUND_OPERATOR_UI(mpz, fun, eval_fun)
! 3223:
! 3224: #define __GMPQ_DEFINE_COMPOUND_OPERATOR_UI(fun, eval_fun) \
! 3225: __GMP_DEFINE_COMPOUND_OPERATOR_UI(mpq, fun, eval_fun)
! 3226:
! 3227: #define __GMPF_DEFINE_COMPOUND_OPERATOR_UI(fun, eval_fun) \
! 3228: __GMP_DEFINE_COMPOUND_OPERATOR_UI(mpf, fun, eval_fun)
! 3229:
! 3230:
! 3231:
! 3232: #define __GMP_DEFINE_INCREMENT_OPERATOR(type, fun, eval_fun) \
! 3233: \
! 3234: inline type##_class & type##_class::fun() \
! 3235: { \
! 3236: eval_fun::eval(mp); \
! 3237: return *this; \
! 3238: } \
! 3239: \
! 3240: inline type##_class type##_class::fun(int) \
! 3241: { \
! 3242: type##_class temp(*this); \
! 3243: eval_fun::eval(mp); \
! 3244: return temp; \
! 3245: }
! 3246:
! 3247: #define __GMPZ_DEFINE_INCREMENT_OPERATOR(fun, eval_fun) \
! 3248: __GMP_DEFINE_INCREMENT_OPERATOR(mpz, fun, eval_fun)
! 3249:
! 3250: #define __GMPQ_DEFINE_INCREMENT_OPERATOR(fun, eval_fun) \
! 3251: __GMP_DEFINE_INCREMENT_OPERATOR(mpq, fun, eval_fun)
! 3252:
! 3253: #define __GMPF_DEFINE_INCREMENT_OPERATOR(fun, eval_fun) \
! 3254: __GMP_DEFINE_INCREMENT_OPERATOR(mpf, fun, eval_fun)
! 3255:
! 3256:
! 3257:
! 3258: /**************** Arithmetic operators and functions ****************/
! 3259:
! 3260: // non-member operators and functions
! 3261:
! 3262: __GMP_DEFINE_UNARY_FUNCTION(operator+, __gmp_unary_plus)
! 3263: __GMP_DEFINE_UNARY_FUNCTION(operator-, __gmp_unary_minus)
! 3264: __GMP_DEFINE_UNARY_FUNCTION(operator~, __gmp_unary_com)
! 3265:
! 3266: __GMP_DEFINE_BINARY_FUNCTION(operator+, __gmp_binary_plus)
! 3267: __GMP_DEFINE_BINARY_FUNCTION(operator-, __gmp_binary_minus)
! 3268: __GMP_DEFINE_BINARY_FUNCTION(operator*, __gmp_binary_multiplies)
! 3269: __GMP_DEFINE_BINARY_FUNCTION(operator/, __gmp_binary_divides)
! 3270: __GMP_DEFINE_BINARY_FUNCTION(operator%, __gmp_binary_modulus)
! 3271: __GMP_DEFINE_BINARY_FUNCTION(operator&, __gmp_binary_and)
! 3272: __GMP_DEFINE_BINARY_FUNCTION(operator|, __gmp_binary_ior)
! 3273: __GMP_DEFINE_BINARY_FUNCTION(operator^, __gmp_binary_xor)
! 3274:
! 3275: __GMP_DEFINE_BINARY_FUNCTION_UI(operator<<, __gmp_binary_lshift)
! 3276: __GMP_DEFINE_BINARY_FUNCTION_UI(operator>>, __gmp_binary_rshift)
! 3277:
! 3278: __GMP_DEFINE_BINARY_TYPE_FUNCTION(bool, operator==, __gmp_binary_equal)
! 3279: __GMP_DEFINE_BINARY_TYPE_FUNCTION(bool, operator!=, __gmp_binary_not_equal)
! 3280: __GMP_DEFINE_BINARY_TYPE_FUNCTION(bool, operator<, __gmp_binary_less)
! 3281: __GMP_DEFINE_BINARY_TYPE_FUNCTION(bool, operator<=, __gmp_binary_less_equal)
! 3282: __GMP_DEFINE_BINARY_TYPE_FUNCTION(bool, operator>, __gmp_binary_greater)
! 3283: __GMP_DEFINE_BINARY_TYPE_FUNCTION(bool, operator>=, \
! 3284: __gmp_binary_greater_equal)
! 3285:
! 3286: __GMP_DEFINE_UNARY_FUNCTION(abs, __gmp_abs_function)
! 3287: __GMP_DEFINE_UNARY_FUNCTION(trunc, __gmp_trunc_function)
! 3288: __GMP_DEFINE_UNARY_FUNCTION(floor, __gmp_floor_function)
! 3289: __GMP_DEFINE_UNARY_FUNCTION(ceil, __gmp_ceil_function)
! 3290: __GMP_DEFINE_UNARY_FUNCTION(sqrt, __gmp_sqrt_function)
! 3291: __GMP_DEFINE_BINARY_FUNCTION(hypot, __gmp_hypot_function)
! 3292:
! 3293: __GMP_DEFINE_UNARY_TYPE_FUNCTION(int, sgn, __gmp_sgn_function)
! 3294: __GMP_DEFINE_BINARY_TYPE_FUNCTION(int, cmp, __gmp_cmp_function)
! 3295:
! 3296: // member operators for mpz_class
! 3297:
! 3298: __GMPZ_DEFINE_COMPOUND_OPERATOR(operator+=, __gmp_binary_plus)
! 3299: __GMPZ_DEFINE_COMPOUND_OPERATOR(operator-=, __gmp_binary_minus)
! 3300: __GMPZ_DEFINE_COMPOUND_OPERATOR(operator*=, __gmp_binary_multiplies)
! 3301: __GMPZ_DEFINE_COMPOUND_OPERATOR(operator/=, __gmp_binary_divides)
! 3302: __GMPZ_DEFINE_COMPOUND_OPERATOR(operator%=, __gmp_binary_modulus)
! 3303:
! 3304: __GMPZZ_DEFINE_COMPOUND_OPERATOR(operator&=, __gmp_binary_and)
! 3305: __GMPZZ_DEFINE_COMPOUND_OPERATOR(operator|=, __gmp_binary_ior)
! 3306: __GMPZZ_DEFINE_COMPOUND_OPERATOR(operator^=, __gmp_binary_xor)
! 3307:
! 3308: __GMPZ_DEFINE_COMPOUND_OPERATOR_UI(operator<<=, __gmp_binary_lshift)
! 3309: __GMPZ_DEFINE_COMPOUND_OPERATOR_UI(operator>>=, __gmp_binary_rshift)
! 3310:
! 3311: __GMPZ_DEFINE_INCREMENT_OPERATOR(operator++, __gmp_unary_increment)
! 3312: __GMPZ_DEFINE_INCREMENT_OPERATOR(operator--, __gmp_unary_decrement)
! 3313:
! 3314: // member operators for mpq_class
! 3315:
! 3316: __GMPQ_DEFINE_COMPOUND_OPERATOR(operator+=, __gmp_binary_plus)
! 3317: __GMPQ_DEFINE_COMPOUND_OPERATOR(operator-=, __gmp_binary_minus)
! 3318: __GMPQ_DEFINE_COMPOUND_OPERATOR(operator*=, __gmp_binary_multiplies)
! 3319: __GMPQ_DEFINE_COMPOUND_OPERATOR(operator/=, __gmp_binary_divides)
! 3320:
! 3321: __GMPQ_DEFINE_COMPOUND_OPERATOR_UI(operator<<=, __gmp_binary_lshift)
! 3322: __GMPQ_DEFINE_COMPOUND_OPERATOR_UI(operator>>=, __gmp_binary_rshift)
! 3323:
! 3324: __GMPQ_DEFINE_INCREMENT_OPERATOR(operator++, __gmp_unary_increment)
! 3325: __GMPQ_DEFINE_INCREMENT_OPERATOR(operator--, __gmp_unary_decrement)
! 3326:
! 3327: // member operators for mpf_class
! 3328:
! 3329: __GMPF_DEFINE_COMPOUND_OPERATOR(operator+=, __gmp_binary_plus)
! 3330: __GMPF_DEFINE_COMPOUND_OPERATOR(operator-=, __gmp_binary_minus)
! 3331: __GMPF_DEFINE_COMPOUND_OPERATOR(operator*=, __gmp_binary_multiplies)
! 3332: __GMPF_DEFINE_COMPOUND_OPERATOR(operator/=, __gmp_binary_divides)
! 3333:
! 3334: __GMPF_DEFINE_COMPOUND_OPERATOR_UI(operator<<=, __gmp_binary_lshift)
! 3335: __GMPF_DEFINE_COMPOUND_OPERATOR_UI(operator>>=, __gmp_binary_rshift)
! 3336:
! 3337: __GMPF_DEFINE_INCREMENT_OPERATOR(operator++, __gmp_unary_increment)
! 3338: __GMPF_DEFINE_INCREMENT_OPERATOR(operator--, __gmp_unary_decrement)
! 3339:
! 3340:
! 3341:
! 3342: /**************** Class wrapper for gmp_randstate_t ****************/
! 3343:
! 3344: class __gmp_urandomb_value { };
! 3345: class __gmp_urandomm_value { };
! 3346:
! 3347: template <>
! 3348: class __gmp_expr<mpz_t, __gmp_urandomb_value>
! 3349: {
! 3350: private:
! 3351: __gmp_randstate_struct *state;
! 3352: mp_bitcnt_t bits;
! 3353: public:
! 3354: __gmp_expr(gmp_randstate_t s, mp_bitcnt_t l) : state(s), bits(l) { }
! 3355: void eval(mpz_ptr z) const { __gmp_rand_function::eval(z, state, bits); }
! 3356: mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); }
! 3357: };
! 3358:
! 3359: template <>
! 3360: class __gmp_expr<mpz_t, __gmp_urandomm_value>
! 3361: {
! 3362: private:
! 3363: __gmp_randstate_struct *state;
! 3364: mpz_class range;
! 3365: public:
! 3366: __gmp_expr(gmp_randstate_t s, const mpz_class &z) : state(s), range(z) { }
! 3367: void eval(mpz_ptr z) const
! 3368: { __gmp_rand_function::eval(z, state, range.get_mpz_t()); }
! 3369: mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); }
! 3370: };
! 3371:
! 3372: template <>
! 3373: class __gmp_expr<mpf_t, __gmp_urandomb_value>
! 3374: {
! 3375: private:
! 3376: __gmp_randstate_struct *state;
! 3377: mp_bitcnt_t bits;
! 3378: public:
! 3379: __gmp_expr(gmp_randstate_t s, mp_bitcnt_t l) : state(s), bits(l) { }
! 3380: void eval(mpf_ptr f, mp_bitcnt_t prec) const
! 3381: { __gmp_rand_function::eval(f, state, (bits>0) ? get_prec() : prec); }
! 3382: mp_bitcnt_t get_prec() const
! 3383: {
! 3384: if (bits == 0)
! 3385: return mpf_get_default_prec();
! 3386: else
! 3387: return bits;
! 3388: }
! 3389: };
! 3390:
! 3391: extern "C" {
! 3392: typedef void __gmp_randinit_default_t (gmp_randstate_t);
! 3393: typedef void __gmp_randinit_lc_2exp_t (gmp_randstate_t, mpz_srcptr, mpir_ui, mp_bitcnt_t);
! 3394: typedef int __gmp_randinit_lc_2exp_size_t (gmp_randstate_t, mp_bitcnt_t);
! 3395: }
! 3396:
! 3397: class gmp_randclass
! 3398: {
! 3399: private:
! 3400: gmp_randstate_t state;
! 3401:
! 3402: // copy construction and assignment not allowed
! 3403: gmp_randclass(const gmp_randclass &);
! 3404: void operator=(const gmp_randclass &);
! 3405: public:
! 3406: // constructors and destructor
! 3407: gmp_randclass(gmp_randalg_t alg, mp_bitcnt_t size)
! 3408: {
! 3409: switch (alg)
! 3410: {
! 3411: case GMP_RAND_ALG_LC: // no other cases for now
! 3412: default:
! 3413: gmp_randinit_lc_2exp_size(state, size);
! 3414: break;
! 3415: }
! 3416: }
! 3417:
! 3418: // gmp_randinit_default
! 3419: gmp_randclass(__gmp_randinit_default_t* f) { f(state); }
! 3420:
! 3421: // gmp_randinit_lc_2exp
! 3422: gmp_randclass(__gmp_randinit_lc_2exp_t* f,
! 3423: mpz_class z, mpir_ui l1, mp_bitcnt_t l2)
! 3424: { f(state, z.get_mpz_t(), l1, l2); }
! 3425:
! 3426: // gmp_randinit_lc_2exp_size
! 3427: gmp_randclass(__gmp_randinit_lc_2exp_size_t* f,
! 3428: mp_bitcnt_t size)
! 3429: {
! 3430: if (f (state, size) == 0)
! 3431: throw std::length_error ("gmp_randinit_lc_2exp_size");
! 3432: }
! 3433:
! 3434: ~gmp_randclass() { gmp_randclear(state); }
! 3435:
! 3436: // initialize
! 3437: void seed(); // choose a random seed some way (?)
! 3438: void seed(mpir_ui s) { gmp_randseed_ui(state, s); }
! 3439: void seed(const mpz_class &z) { gmp_randseed(state, z.get_mpz_t()); }
! 3440:
! 3441: // get random number
! 3442: __gmp_expr<mpz_t, __gmp_urandomb_value> get_z_bits(mp_bitcnt_t l)
! 3443: { return __gmp_expr<mpz_t, __gmp_urandomb_value>(state, l); }
! 3444: __gmp_expr<mpz_t, __gmp_urandomb_value> get_z_bits(const mpz_class &z)
! 3445: { return get_z_bits(z.get_ui()); }
! 3446:
! 3447: __gmp_expr<mpz_t, __gmp_urandomm_value> get_z_range(const mpz_class &z)
! 3448: { return __gmp_expr<mpz_t, __gmp_urandomm_value>(state, z); }
! 3449:
! 3450: __gmp_expr<mpf_t, __gmp_urandomb_value> get_f(mp_bitcnt_t prec = 0)
! 3451: { return __gmp_expr<mpf_t, __gmp_urandomb_value>(state, prec); }
! 3452: };
! 3453:
! 3454:
! 3455: /**************** #undef all private macros ****************/
! 3456:
! 3457: #undef __GMPP_DECLARE_COMPOUND_OPERATOR
! 3458: #undef __GMPN_DECLARE_COMPOUND_OPERATOR
! 3459: #undef __GMP_DECLARE_COMPOUND_OPERATOR
! 3460: #undef __GMP_DECLARE_COMPOUND_OPERATOR_UI
! 3461: #undef __GMP_DECLARE_INCREMENT_OPERATOR
! 3462:
! 3463: #undef __GMPZQ_DEFINE_EXPR
! 3464: #undef __GMP_DEFINE_TERNARY_EXPR
! 3465:
! 3466: #undef __GMP_DEFINE_UNARY_FUNCTION
! 3467: #undef __GMP_DEFINE_UNARY_TYPE_FUNCTION
! 3468:
! 3469: #undef __GMPP_DEFINE_BINARY_FUNCTION
! 3470: #undef __GMPNN_DEFINE_BINARY_FUNCTION
! 3471: #undef __GMPNS_DEFINE_BINARY_FUNCTION
! 3472: #undef __GMPNU_DEFINE_BINARY_FUNCTION
! 3473: #undef __GMPND_DEFINE_BINARY_FUNCTION
! 3474: #undef __GMPNLD_DEFINE_BINARY_FUNCTION
! 3475: #undef __GMPN_DEFINE_BINARY_FUNCTION
! 3476: #undef __GMP_DEFINE_BINARY_FUNCTION
! 3477:
! 3478: #undef __GMP_DEFINE_BINARY_FUNCTION_UI
! 3479:
! 3480: #undef __GMPP_DEFINE_BINARY_TYPE_FUNCTION
! 3481: #undef __GMPNN_DEFINE_BINARY_TYPE_FUNCTION
! 3482: #undef __GMPNS_DEFINE_BINARY_TYPE_FUNCTION
! 3483: #undef __GMPNU_DEFINE_BINARY_TYPE_FUNCTION
! 3484: #undef __GMPND_DEFINE_BINARY_TYPE_FUNCTION
! 3485: #undef __GMPNLD_DEFINE_BINARY_TYPE_FUNCTION
! 3486: #undef __GMPN_DEFINE_BINARY_TYPE_FUNCTION
! 3487: #undef __GMP_DEFINE_BINARY_TYPE_FUNCTION
! 3488:
! 3489: #undef __GMPP_DECLARE_COMPOUND_OPERATOR
! 3490: #undef __GMPN_DECLARE_COMPOUND_OPERATOR
! 3491: #undef __GMP_DECLARE_COMPOUND_OPERATOR
! 3492:
! 3493: #undef __GMP_DECLARE_COMPOUND_OPERATOR_UI
! 3494: #undef __GMP_DECLARE_INCREMENT_OPERATOR
! 3495:
! 3496: #undef __GMPZ_DEFINE_COMPOUND_OPERATOR
! 3497: #undef __GMPZZ_DEFINE_COMPOUND_OPERATOR
! 3498: #undef __GMPZN_DEFINE_COMPOUND_OPERATOR
! 3499: #undef __GMPZNN_DEFINE_COMPOUND_OPERATOR
! 3500: #undef __GMPZNS_DEFINE_COMPOUND_OPERATOR
! 3501: #undef __GMPZNU_DEFINE_COMPOUND_OPERATOR
! 3502: #undef __GMPZND_DEFINE_COMPOUND_OPERATOR
! 3503: #undef __GMPZNLD_DEFINE_COMPOUND_OPERATOR
! 3504:
! 3505: #undef __GMPP_DEFINE_COMPOUND_OPERATOR
! 3506: #undef __GMPNN_DEFINE_COMPOUND_OPERATOR
! 3507: #undef __GMPNS_DEFINE_COMPOUND_OPERATOR
! 3508: #undef __GMPNU_DEFINE_COMPOUND_OPERATOR
! 3509: #undef __GMPND_DEFINE_COMPOUND_OPERATOR
! 3510: #undef __GMPNLD_DEFINE_COMPOUND_OPERATOR
! 3511: #undef __GMPN_DEFINE_COMPOUND_OPERATOR
! 3512: #undef __GMP_DEFINE_COMPOUND_OPERATOR
! 3513:
! 3514: #undef __GMPZ_DEFINE_COMPOUND_OPERATOR
! 3515: #undef __GMPZZ_DEFINE_COMPOUND_OPERATOR
! 3516: #undef __GMPQ_DEFINE_COMPOUND_OPERATOR
! 3517: #undef __GMPF_DEFINE_COMPOUND_OPERATOR
! 3518:
! 3519: #undef __GMP_DEFINE_COMPOUND_OPERATOR_UI
! 3520: #undef __GMPZ_DEFINE_COMPOUND_OPERATOR_UI
! 3521: #undef __GMPQ_DEFINE_COMPOUND_OPERATOR_UI
! 3522: #undef __GMPF_DEFINE_COMPOUND_OPERATOR_UI
! 3523:
! 3524: #undef __GMP_DEFINE_INCREMENT_OPERATOR
! 3525: #undef __GMPZ_DEFINE_INCREMENT_OPERATOR
! 3526: #undef __GMPQ_DEFINE_INCREMENT_OPERATOR
! 3527: #undef __GMPF_DEFINE_INCREMENT_OPERATOR
! 3528:
! 3529: #endif /* __GMP_PLUSPLUS__ */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>