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