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