File indexing completed on 2025-01-17 09:55:31
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032 #ifndef __GMP_PLUSPLUS__
0033 #define __GMP_PLUSPLUS__
0034
0035 #include <iosfwd>
0036
0037 #include <cstring> /* for strlen */
0038 #include <limits> /* numeric_limits */
0039 #include <utility>
0040 #include <algorithm> /* swap */
0041 #include <string>
0042 #include <stdexcept>
0043 #include <cfloat>
0044 #include <gmp.h>
0045
0046
0047
0048
0049 #if __GMP_GNUC_PREREQ(4, 2)
0050 #define __GMPXX_CONSTANT(X) __builtin_constant_p(X)
0051 #else
0052 #define __GMPXX_CONSTANT(X) false
0053 #endif
0054 #define __GMPXX_CONSTANT_TRUE(X) (__GMPXX_CONSTANT(X) && (X))
0055
0056
0057 #ifndef __GMPXX_USE_CXX11
0058 #if __cplusplus >= 201103L
0059 #define __GMPXX_USE_CXX11 1
0060 #else
0061 #define __GMPXX_USE_CXX11 0
0062 #endif
0063 #endif
0064
0065 #if __GMPXX_USE_CXX11
0066 #define __GMPXX_NOEXCEPT noexcept
0067 #include <type_traits> // for common_type
0068 #else
0069 #define __GMPXX_NOEXCEPT
0070 #endif
0071
0072
0073 #if GMP_NAIL_BITS != 0 && ! defined _LONG_LONG_LIMB
0074 #define __GMPZ_ULI_LIMBS 2
0075 #else
0076 #define __GMPZ_ULI_LIMBS 1
0077 #endif
0078
0079 #define __GMPXX_BITS_TO_LIMBS(n) (((n) + (GMP_NUMB_BITS - 1)) / GMP_NUMB_BITS)
0080 #define __GMPZ_DBL_LIMBS __GMPXX_BITS_TO_LIMBS(DBL_MAX_EXP)+1
0081 #define __GMPQ_NUM_DBL_LIMBS __GMPZ_DBL_LIMBS
0082 #define __GMPQ_DEN_DBL_LIMBS __GMPXX_BITS_TO_LIMBS(DBL_MANT_DIG+1-DBL_MIN_EXP)+1
0083
0084
0085
0086 inline void __mpz_set_ui_safe(mpz_ptr p, unsigned long l)
0087 {
0088 p->_mp_size = (l != 0);
0089 p->_mp_d[0] = l & GMP_NUMB_MASK;
0090 #if __GMPZ_ULI_LIMBS > 1
0091 l >>= GMP_NUMB_BITS;
0092 p->_mp_d[1] = l;
0093 p->_mp_size += (l != 0);
0094 #endif
0095 }
0096
0097 inline void __mpz_set_si_safe(mpz_ptr p, long l)
0098 {
0099 if(l < 0)
0100 {
0101 __mpz_set_ui_safe(p, -static_cast<unsigned long>(l));
0102 mpz_neg(p, p);
0103 }
0104 else
0105 __mpz_set_ui_safe(p, l);
0106
0107 }
0108
0109
0110 #define __GMPXX_TMPZ_UI \
0111 mpz_t temp; \
0112 mp_limb_t limbs[__GMPZ_ULI_LIMBS]; \
0113 temp->_mp_d = limbs; \
0114 __mpz_set_ui_safe (temp, l)
0115 #define __GMPXX_TMPZ_SI \
0116 mpz_t temp; \
0117 mp_limb_t limbs[__GMPZ_ULI_LIMBS]; \
0118 temp->_mp_d = limbs; \
0119 __mpz_set_si_safe (temp, l)
0120 #define __GMPXX_TMPZ_D \
0121 mpz_t temp; \
0122 mp_limb_t limbs[__GMPZ_DBL_LIMBS]; \
0123 temp->_mp_d = limbs; \
0124 temp->_mp_alloc = __GMPZ_DBL_LIMBS; \
0125 mpz_set_d (temp, d)
0126
0127 #define __GMPXX_TMPQ_UI \
0128 mpq_t temp; \
0129 mp_limb_t limbs[__GMPZ_ULI_LIMBS+1]; \
0130 mpq_numref(temp)->_mp_d = limbs; \
0131 __mpz_set_ui_safe (mpq_numref(temp), l); \
0132 mpq_denref(temp)->_mp_d = limbs + __GMPZ_ULI_LIMBS; \
0133 mpq_denref(temp)->_mp_size = 1; \
0134 mpq_denref(temp)->_mp_d[0] = 1
0135 #define __GMPXX_TMPQ_SI \
0136 mpq_t temp; \
0137 mp_limb_t limbs[__GMPZ_ULI_LIMBS+1]; \
0138 mpq_numref(temp)->_mp_d = limbs; \
0139 __mpz_set_si_safe (mpq_numref(temp), l); \
0140 mpq_denref(temp)->_mp_d = limbs + __GMPZ_ULI_LIMBS; \
0141 mpq_denref(temp)->_mp_size = 1; \
0142 mpq_denref(temp)->_mp_d[0] = 1
0143 #define __GMPXX_TMPQ_D \
0144 mpq_t temp; \
0145 mp_limb_t limbs[__GMPQ_NUM_DBL_LIMBS + __GMPQ_DEN_DBL_LIMBS]; \
0146 mpq_numref(temp)->_mp_d = limbs; \
0147 mpq_numref(temp)->_mp_alloc = __GMPQ_NUM_DBL_LIMBS; \
0148 mpq_denref(temp)->_mp_d = limbs + __GMPQ_NUM_DBL_LIMBS; \
0149 mpq_denref(temp)->_mp_alloc = __GMPQ_DEN_DBL_LIMBS; \
0150 mpq_set_d (temp, d)
0151
0152 inline unsigned long __gmpxx_abs_ui (signed long l)
0153 {
0154 return l >= 0 ? static_cast<unsigned long>(l)
0155 : -static_cast<unsigned long>(l);
0156 }
0157
0158
0159
0160
0161
0162
0163
0164 struct __gmp_unary_plus
0165 {
0166 static void eval(mpz_ptr z, mpz_srcptr w) { mpz_set(z, w); }
0167 static void eval(mpq_ptr q, mpq_srcptr r) { mpq_set(q, r); }
0168 static void eval(mpf_ptr f, mpf_srcptr g) { mpf_set(f, g); }
0169 };
0170
0171 struct __gmp_unary_minus
0172 {
0173 static void eval(mpz_ptr z, mpz_srcptr w) { mpz_neg(z, w); }
0174 static void eval(mpq_ptr q, mpq_srcptr r) { mpq_neg(q, r); }
0175 static void eval(mpf_ptr f, mpf_srcptr g) { mpf_neg(f, g); }
0176 };
0177
0178 struct __gmp_unary_com
0179 {
0180 static void eval(mpz_ptr z, mpz_srcptr w) { mpz_com(z, w); }
0181 };
0182
0183 struct __gmp_binary_plus
0184 {
0185 static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v)
0186 { mpz_add(z, w, v); }
0187
0188 static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l)
0189 {
0190
0191
0192 if (__GMPXX_CONSTANT(l) && l == 0)
0193 {
0194 if (z != w) mpz_set(z, w);
0195 }
0196 else
0197 mpz_add_ui(z, w, l);
0198 }
0199 static void eval(mpz_ptr z, unsigned long int l, mpz_srcptr w)
0200 { eval(z, w, l); }
0201 static void eval(mpz_ptr z, mpz_srcptr w, signed long int l)
0202 {
0203 if (l >= 0)
0204 eval(z, w, static_cast<unsigned long>(l));
0205 else
0206 mpz_sub_ui(z, w, -static_cast<unsigned long>(l));
0207 }
0208 static void eval(mpz_ptr z, signed long int l, mpz_srcptr w)
0209 { eval(z, w, l); }
0210 static void eval(mpz_ptr z, mpz_srcptr w, double d)
0211 { __GMPXX_TMPZ_D; mpz_add (z, w, temp); }
0212 static void eval(mpz_ptr z, double d, mpz_srcptr w)
0213 { eval(z, w, d); }
0214
0215 static void eval(mpq_ptr q, mpq_srcptr r, mpq_srcptr s)
0216 { mpq_add(q, r, s); }
0217
0218 static void eval(mpq_ptr q, mpq_srcptr r, unsigned long int l)
0219 {
0220 if (__GMPXX_CONSTANT(l) && l == 0)
0221 {
0222 if (q != r) mpq_set(q, r);
0223 }
0224 else if (__GMPXX_CONSTANT(l) && l == 1)
0225 {
0226 mpz_add (mpq_numref(q), mpq_numref(r), mpq_denref(r));
0227 if (q != r) mpz_set(mpq_denref(q), mpq_denref(r));
0228 }
0229 else
0230 {
0231 if (q == r)
0232 mpz_addmul_ui(mpq_numref(q), mpq_denref(q), l);
0233 else
0234 {
0235 mpz_mul_ui(mpq_numref(q), mpq_denref(r), l);
0236 mpz_add(mpq_numref(q), mpq_numref(q), mpq_numref(r));
0237 mpz_set(mpq_denref(q), mpq_denref(r));
0238 }
0239 }
0240 }
0241 static void eval(mpq_ptr q, unsigned long int l, mpq_srcptr r)
0242 { eval(q, r, l); }
0243 static inline void eval(mpq_ptr q, mpq_srcptr r, signed long int l);
0244
0245 static void eval(mpq_ptr q, signed long int l, mpq_srcptr r)
0246 { eval(q, r, l); }
0247 static void eval(mpq_ptr q, mpq_srcptr r, double d)
0248 { __GMPXX_TMPQ_D; mpq_add (q, r, temp); }
0249 static void eval(mpq_ptr q, double d, mpq_srcptr r)
0250 { eval(q, r, d); }
0251
0252 static void eval(mpq_ptr q, mpq_srcptr r, mpz_srcptr z)
0253 {
0254 if (q == r)
0255 mpz_addmul(mpq_numref(q), mpq_denref(q), z);
0256 else
0257 {
0258 mpz_mul(mpq_numref(q), mpq_denref(r), z);
0259 mpz_add(mpq_numref(q), mpq_numref(q), mpq_numref(r));
0260 mpz_set(mpq_denref(q), mpq_denref(r));
0261 }
0262 }
0263 static void eval(mpq_ptr q, mpz_srcptr z, mpq_srcptr r)
0264 { eval(q, r, z); }
0265
0266 static void eval(mpf_ptr f, mpf_srcptr g, mpf_srcptr h)
0267 { mpf_add(f, g, h); }
0268
0269 static void eval(mpf_ptr f, mpf_srcptr g, unsigned long int l)
0270 { mpf_add_ui(f, g, l); }
0271 static void eval(mpf_ptr f, unsigned long int l, mpf_srcptr g)
0272 { mpf_add_ui(f, g, l); }
0273 static void eval(mpf_ptr f, mpf_srcptr g, signed long int l)
0274 {
0275 if (l >= 0)
0276 mpf_add_ui(f, g, l);
0277 else
0278 mpf_sub_ui(f, g, -static_cast<unsigned long>(l));
0279 }
0280 static void eval(mpf_ptr f, signed long int l, mpf_srcptr g)
0281 { eval(f, g, l); }
0282 static void eval(mpf_ptr f, mpf_srcptr g, double d)
0283 {
0284 mpf_t temp;
0285 mpf_init2(temp, 8*sizeof(double));
0286 mpf_set_d(temp, d);
0287 mpf_add(f, g, temp);
0288 mpf_clear(temp);
0289 }
0290 static void eval(mpf_ptr f, double d, mpf_srcptr g)
0291 { eval(f, g, d); }
0292 };
0293
0294 struct __gmp_binary_minus
0295 {
0296 static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v)
0297 { mpz_sub(z, w, v); }
0298
0299 static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l)
0300 {
0301 if (__GMPXX_CONSTANT(l) && l == 0)
0302 {
0303 if (z != w) mpz_set(z, w);
0304 }
0305 else
0306 mpz_sub_ui(z, w, l);
0307 }
0308 static void eval(mpz_ptr z, unsigned long int l, mpz_srcptr w)
0309 {
0310 if (__GMPXX_CONSTANT(l) && l == 0)
0311 {
0312 mpz_neg(z, w);
0313 }
0314 else
0315 mpz_ui_sub(z, l, w);
0316 }
0317 static void eval(mpz_ptr z, mpz_srcptr w, signed long int l)
0318 {
0319 if (l >= 0)
0320 eval(z, w, static_cast<unsigned long>(l));
0321 else
0322 mpz_add_ui(z, w, -static_cast<unsigned long>(l));
0323 }
0324 static void eval(mpz_ptr z, signed long int l, mpz_srcptr w)
0325 {
0326 if (l >= 0)
0327 eval(z, static_cast<unsigned long>(l), w);
0328 else
0329 {
0330 mpz_add_ui(z, w, -static_cast<unsigned long>(l));
0331 mpz_neg(z, z);
0332 }
0333 }
0334 static void eval(mpz_ptr z, mpz_srcptr w, double d)
0335 { __GMPXX_TMPZ_D; mpz_sub (z, w, temp); }
0336 static void eval(mpz_ptr z, double d, mpz_srcptr w)
0337 { __GMPXX_TMPZ_D; mpz_sub (z, temp, w); }
0338
0339 static void eval(mpq_ptr q, mpq_srcptr r, mpq_srcptr s)
0340 { mpq_sub(q, r, s); }
0341
0342 static void eval(mpq_ptr q, mpq_srcptr r, unsigned long int l)
0343 {
0344 if (__GMPXX_CONSTANT(l) && l == 0)
0345 {
0346 if (q != r) mpq_set(q, r);
0347 }
0348 else if (__GMPXX_CONSTANT(l) && l == 1)
0349 {
0350 mpz_sub (mpq_numref(q), mpq_numref(r), mpq_denref(r));
0351 if (q != r) mpz_set(mpq_denref(q), mpq_denref(r));
0352 }
0353 else
0354 {
0355 if (q == r)
0356 mpz_submul_ui(mpq_numref(q), mpq_denref(q), l);
0357 else
0358 {
0359 mpz_mul_ui(mpq_numref(q), mpq_denref(r), l);
0360 mpz_sub(mpq_numref(q), mpq_numref(r), mpq_numref(q));
0361 mpz_set(mpq_denref(q), mpq_denref(r));
0362 }
0363 }
0364 }
0365 static void eval(mpq_ptr q, unsigned long int l, mpq_srcptr r)
0366 { eval(q, r, l); mpq_neg(q, q); }
0367 static void eval(mpq_ptr q, mpq_srcptr r, signed long int l)
0368 {
0369 if (l >= 0)
0370 eval(q, r, static_cast<unsigned long>(l));
0371 else
0372 __gmp_binary_plus::eval(q, r, -static_cast<unsigned long>(l));
0373 }
0374 static void eval(mpq_ptr q, signed long int l, mpq_srcptr r)
0375 { eval(q, r, l); mpq_neg(q, q); }
0376 static void eval(mpq_ptr q, mpq_srcptr r, double d)
0377 { __GMPXX_TMPQ_D; mpq_sub (q, r, temp); }
0378 static void eval(mpq_ptr q, double d, mpq_srcptr r)
0379 { __GMPXX_TMPQ_D; mpq_sub (q, temp, r); }
0380
0381 static void eval(mpq_ptr q, mpq_srcptr r, mpz_srcptr z)
0382 {
0383 if (q == r)
0384 mpz_submul(mpq_numref(q), mpq_denref(q), z);
0385 else
0386 {
0387 mpz_mul(mpq_numref(q), mpq_denref(r), z);
0388 mpz_sub(mpq_numref(q), mpq_numref(r), mpq_numref(q));
0389 mpz_set(mpq_denref(q), mpq_denref(r));
0390 }
0391 }
0392 static void eval(mpq_ptr q, mpz_srcptr z, mpq_srcptr r)
0393 { eval(q, r, z); mpq_neg(q, q); }
0394
0395 static void eval(mpf_ptr f, mpf_srcptr g, mpf_srcptr h)
0396 { mpf_sub(f, g, h); }
0397
0398 static void eval(mpf_ptr f, mpf_srcptr g, unsigned long int l)
0399 { mpf_sub_ui(f, g, l); }
0400 static void eval(mpf_ptr f, unsigned long int l, mpf_srcptr g)
0401 { mpf_ui_sub(f, l, g); }
0402 static void eval(mpf_ptr f, mpf_srcptr g, signed long int l)
0403 {
0404 if (l >= 0)
0405 mpf_sub_ui(f, g, l);
0406 else
0407 mpf_add_ui(f, g, -static_cast<unsigned long>(l));
0408 }
0409 static void eval(mpf_ptr f, signed long int l, mpf_srcptr g)
0410 {
0411 if (l >= 0)
0412 mpf_sub_ui(f, g, l);
0413 else
0414 mpf_add_ui(f, g, -static_cast<unsigned long>(l));
0415 mpf_neg(f, f);
0416 }
0417 static void eval(mpf_ptr f, mpf_srcptr g, double d)
0418 {
0419 mpf_t temp;
0420 mpf_init2(temp, 8*sizeof(double));
0421 mpf_set_d(temp, d);
0422 mpf_sub(f, g, temp);
0423 mpf_clear(temp);
0424 }
0425 static void eval(mpf_ptr f, double d, mpf_srcptr g)
0426 {
0427 mpf_t temp;
0428 mpf_init2(temp, 8*sizeof(double));
0429 mpf_set_d(temp, d);
0430 mpf_sub(f, temp, g);
0431 mpf_clear(temp);
0432 }
0433 };
0434
0435
0436 inline void
0437 __gmp_binary_plus::eval(mpq_ptr q, mpq_srcptr r, signed long int l)
0438 {
0439 if (l >= 0)
0440 eval(q, r, static_cast<unsigned long>(l));
0441 else
0442 __gmp_binary_minus::eval(q, r, -static_cast<unsigned long>(l));
0443 }
0444
0445 struct __gmp_binary_lshift
0446 {
0447 static void eval(mpz_ptr z, mpz_srcptr w, mp_bitcnt_t l)
0448 {
0449 if (__GMPXX_CONSTANT(l) && (l == 0))
0450 {
0451 if (z != w) mpz_set(z, w);
0452 }
0453 else
0454 mpz_mul_2exp(z, w, l);
0455 }
0456 static void eval(mpq_ptr q, mpq_srcptr r, mp_bitcnt_t l)
0457 {
0458 if (__GMPXX_CONSTANT(l) && (l == 0))
0459 {
0460 if (q != r) mpq_set(q, r);
0461 }
0462 else
0463 mpq_mul_2exp(q, r, l);
0464 }
0465 static void eval(mpf_ptr f, mpf_srcptr g, mp_bitcnt_t l)
0466 { mpf_mul_2exp(f, g, l); }
0467 };
0468
0469 struct __gmp_binary_rshift
0470 {
0471 static void eval(mpz_ptr z, mpz_srcptr w, mp_bitcnt_t l)
0472 {
0473 if (__GMPXX_CONSTANT(l) && (l == 0))
0474 {
0475 if (z != w) mpz_set(z, w);
0476 }
0477 else
0478 mpz_fdiv_q_2exp(z, w, l);
0479 }
0480 static void eval(mpq_ptr q, mpq_srcptr r, mp_bitcnt_t l)
0481 {
0482 if (__GMPXX_CONSTANT(l) && (l == 0))
0483 {
0484 if (q != r) mpq_set(q, r);
0485 }
0486 else
0487 mpq_div_2exp(q, r, l);
0488 }
0489 static void eval(mpf_ptr f, mpf_srcptr g, mp_bitcnt_t l)
0490 { mpf_div_2exp(f, g, l); }
0491 };
0492
0493 struct __gmp_binary_multiplies
0494 {
0495 static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v)
0496 { mpz_mul(z, w, v); }
0497
0498 static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l)
0499 {
0500
0501 #if __GMP_GNUC_PREREQ(3, 4)
0502 if (__GMPXX_CONSTANT(l) && (l & (l-1)) == 0)
0503 {
0504 if (l == 0)
0505 {
0506 z->_mp_size = 0;
0507 }
0508 else
0509 {
0510 __gmp_binary_lshift::eval(z, w, __builtin_ctzl(l));
0511 }
0512 }
0513 else
0514 #endif
0515 mpz_mul_ui(z, w, l);
0516 }
0517 static void eval(mpz_ptr z, unsigned long int l, mpz_srcptr w)
0518 { eval(z, w, l); }
0519 static void eval(mpz_ptr z, mpz_srcptr w, signed long int l)
0520 {
0521 if (__GMPXX_CONSTANT_TRUE(l >= 0))
0522 eval(z, w, static_cast<unsigned long>(l));
0523 else if (__GMPXX_CONSTANT_TRUE(l <= 0))
0524 {
0525 eval(z, w, -static_cast<unsigned long>(l));
0526 mpz_neg(z, z);
0527 }
0528 else
0529 mpz_mul_si (z, w, l);
0530 }
0531 static void eval(mpz_ptr z, signed long int l, mpz_srcptr w)
0532 { eval(z, w, l); }
0533 static void eval(mpz_ptr z, mpz_srcptr w, double d)
0534 { __GMPXX_TMPZ_D; mpz_mul (z, w, temp); }
0535 static void eval(mpz_ptr z, double d, mpz_srcptr w)
0536 { eval(z, w, d); }
0537
0538 static void eval(mpq_ptr q, mpq_srcptr r, mpq_srcptr s)
0539 { mpq_mul(q, r, s); }
0540
0541 static void eval(mpq_ptr q, mpq_srcptr r, unsigned long int l)
0542 {
0543 #if __GMP_GNUC_PREREQ(3, 4)
0544 if (__GMPXX_CONSTANT(l) && (l & (l-1)) == 0)
0545 {
0546 if (l == 0)
0547 {
0548 mpq_set_ui(q, 0, 1);
0549 }
0550 else
0551 {
0552 __gmp_binary_lshift::eval(q, r, __builtin_ctzl(l));
0553 }
0554 }
0555 else
0556 #endif
0557 {
0558 __GMPXX_TMPQ_UI;
0559 mpq_mul (q, r, temp);
0560 }
0561 }
0562 static void eval(mpq_ptr q, unsigned long int l, mpq_srcptr r)
0563 { eval(q, r, l); }
0564 static void eval(mpq_ptr q, mpq_srcptr r, signed long int l)
0565 {
0566 if (__GMPXX_CONSTANT_TRUE(l >= 0))
0567 eval(q, r, static_cast<unsigned long>(l));
0568 else if (__GMPXX_CONSTANT_TRUE(l <= 0))
0569 {
0570 eval(q, r, -static_cast<unsigned long>(l));
0571 mpq_neg(q, q);
0572 }
0573 else
0574 {
0575 __GMPXX_TMPQ_SI;
0576 mpq_mul (q, r, temp);
0577 }
0578 }
0579 static void eval(mpq_ptr q, signed long int l, mpq_srcptr r)
0580 { eval(q, r, l); }
0581 static void eval(mpq_ptr q, mpq_srcptr r, double d)
0582 { __GMPXX_TMPQ_D; mpq_mul (q, r, temp); }
0583 static void eval(mpq_ptr q, double d, mpq_srcptr r)
0584 { eval(q, r, d); }
0585
0586 static void eval(mpf_ptr f, mpf_srcptr g, mpf_srcptr h)
0587 { mpf_mul(f, g, h); }
0588
0589 static void eval(mpf_ptr f, mpf_srcptr g, unsigned long int l)
0590 { mpf_mul_ui(f, g, l); }
0591 static void eval(mpf_ptr f, unsigned long int l, mpf_srcptr g)
0592 { mpf_mul_ui(f, g, l); }
0593 static void eval(mpf_ptr f, mpf_srcptr g, signed long int l)
0594 {
0595 if (l >= 0)
0596 mpf_mul_ui(f, g, l);
0597 else
0598 {
0599 mpf_mul_ui(f, g, -static_cast<unsigned long>(l));
0600 mpf_neg(f, f);
0601 }
0602 }
0603 static void eval(mpf_ptr f, signed long int l, mpf_srcptr g)
0604 { eval(f, g, l); }
0605 static void eval(mpf_ptr f, mpf_srcptr g, double d)
0606 {
0607 mpf_t temp;
0608 mpf_init2(temp, 8*sizeof(double));
0609 mpf_set_d(temp, d);
0610 mpf_mul(f, g, temp);
0611 mpf_clear(temp);
0612 }
0613 static void eval(mpf_ptr f, double d, mpf_srcptr g)
0614 { eval(f, g, d); }
0615 };
0616
0617 struct __gmp_binary_divides
0618 {
0619 static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v)
0620 { mpz_tdiv_q(z, w, v); }
0621
0622 static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l)
0623 {
0624 #if __GMP_GNUC_PREREQ(3, 4)
0625
0626 if (__GMPXX_CONSTANT(l) && (l & (l-1)) == 0 && l != 0)
0627 {
0628 if (l == 1)
0629 {
0630 if (z != w) mpz_set(z, w);
0631 }
0632 else
0633 mpz_tdiv_q_2exp(z, w, __builtin_ctzl(l));
0634
0635 }
0636 else
0637 #endif
0638 mpz_tdiv_q_ui(z, w, l);
0639 }
0640 static void eval(mpz_ptr z, unsigned long int l, mpz_srcptr w)
0641 {
0642 if (mpz_sgn(w) >= 0)
0643 {
0644 if (mpz_fits_ulong_p(w))
0645 mpz_set_ui(z, l / mpz_get_ui(w));
0646 else
0647 mpz_set_ui(z, 0);
0648 }
0649 else
0650 {
0651 mpz_neg(z, w);
0652 if (mpz_fits_ulong_p(z))
0653 {
0654 mpz_set_ui(z, l / mpz_get_ui(z));
0655 mpz_neg(z, z);
0656 }
0657 else
0658 mpz_set_ui(z, 0);
0659 }
0660 }
0661 static void eval(mpz_ptr z, mpz_srcptr w, signed long int l)
0662 {
0663 if (l >= 0)
0664 eval(z, w, static_cast<unsigned long>(l));
0665 else
0666 {
0667 eval(z, w, -static_cast<unsigned long>(l));
0668 mpz_neg(z, z);
0669 }
0670 }
0671 static void eval(mpz_ptr z, signed long int l, mpz_srcptr w)
0672 {
0673 if (mpz_fits_slong_p(w))
0674 mpz_set_si(z, l / mpz_get_si(w));
0675 else
0676 {
0677
0678
0679 mpz_set_si (z, (mpz_cmpabs_ui (w, __gmpxx_abs_ui(l)) == 0 ? -1 : 0));
0680 }
0681 }
0682 static void eval(mpz_ptr z, mpz_srcptr w, double d)
0683 { __GMPXX_TMPZ_D; mpz_tdiv_q (z, w, temp); }
0684 static void eval(mpz_ptr z, double d, mpz_srcptr w)
0685 { __GMPXX_TMPZ_D; mpz_tdiv_q (z, temp, w); }
0686
0687 static void eval(mpq_ptr q, mpq_srcptr r, mpq_srcptr s)
0688 { mpq_div(q, r, s); }
0689
0690 static void eval(mpq_ptr q, mpq_srcptr r, unsigned long int l)
0691 {
0692 #if __GMP_GNUC_PREREQ(3, 4)
0693 if (__GMPXX_CONSTANT(l) && (l & (l-1)) == 0 && l != 0)
0694 __gmp_binary_rshift::eval(q, r, __builtin_ctzl(l));
0695 else
0696 #endif
0697 {
0698 __GMPXX_TMPQ_UI;
0699 mpq_div (q, r, temp);
0700 }
0701 }
0702 static void eval(mpq_ptr q, unsigned long int l, mpq_srcptr r)
0703 {
0704 if (__GMPXX_CONSTANT_TRUE(l == 0))
0705 mpq_set_ui(q, 0, 1);
0706 else if (__GMPXX_CONSTANT_TRUE(l == 1))
0707 mpq_inv(q, r);
0708 else
0709 {
0710 __GMPXX_TMPQ_UI;
0711 mpq_div (q, temp, r);
0712 }
0713 }
0714 static void eval(mpq_ptr q, mpq_srcptr r, signed long int l)
0715 {
0716 if (__GMPXX_CONSTANT_TRUE(l >= 0))
0717 eval(q, r, static_cast<unsigned long>(l));
0718 else if (__GMPXX_CONSTANT_TRUE(l <= 0))
0719 {
0720 eval(q, r, -static_cast<unsigned long>(l));
0721 mpq_neg(q, q);
0722 }
0723 else
0724 {
0725 __GMPXX_TMPQ_SI;
0726 mpq_div (q, r, temp);
0727 }
0728 }
0729 static void eval(mpq_ptr q, signed long int l, mpq_srcptr r)
0730 {
0731 if (__GMPXX_CONSTANT_TRUE(l == 0))
0732 mpq_set_ui(q, 0, 1);
0733 else if (__GMPXX_CONSTANT_TRUE(l == 1))
0734 mpq_inv(q, r);
0735 else if (__GMPXX_CONSTANT_TRUE(l == -1))
0736 {
0737 mpq_inv(q, r);
0738 mpq_neg(q, q);
0739 }
0740 else
0741 {
0742 __GMPXX_TMPQ_SI;
0743 mpq_div (q, temp, r);
0744 }
0745 }
0746 static void eval(mpq_ptr q, mpq_srcptr r, double d)
0747 { __GMPXX_TMPQ_D; mpq_div (q, r, temp); }
0748 static void eval(mpq_ptr q, double d, mpq_srcptr r)
0749 { __GMPXX_TMPQ_D; mpq_div (q, temp, r); }
0750
0751 static void eval(mpf_ptr f, mpf_srcptr g, mpf_srcptr h)
0752 { mpf_div(f, g, h); }
0753
0754 static void eval(mpf_ptr f, mpf_srcptr g, unsigned long int l)
0755 { mpf_div_ui(f, g, l); }
0756 static void eval(mpf_ptr f, unsigned long int l, mpf_srcptr g)
0757 { mpf_ui_div(f, l, g); }
0758 static void eval(mpf_ptr f, mpf_srcptr g, signed long int l)
0759 {
0760 if (l >= 0)
0761 mpf_div_ui(f, g, l);
0762 else
0763 {
0764 mpf_div_ui(f, g, -static_cast<unsigned long>(l));
0765 mpf_neg(f, f);
0766 }
0767 }
0768 static void eval(mpf_ptr f, signed long int l, mpf_srcptr g)
0769 {
0770 if (l >= 0)
0771 mpf_ui_div(f, l, g);
0772 else
0773 {
0774 mpf_ui_div(f, -static_cast<unsigned long>(l), g);
0775 mpf_neg(f, f);
0776 }
0777 }
0778 static void eval(mpf_ptr f, mpf_srcptr g, double d)
0779 {
0780 mpf_t temp;
0781 mpf_init2(temp, 8*sizeof(double));
0782 mpf_set_d(temp, d);
0783 mpf_div(f, g, temp);
0784 mpf_clear(temp);
0785 }
0786 static void eval(mpf_ptr f, double d, mpf_srcptr g)
0787 {
0788 mpf_t temp;
0789 mpf_init2(temp, 8*sizeof(double));
0790 mpf_set_d(temp, d);
0791 mpf_div(f, temp, g);
0792 mpf_clear(temp);
0793 }
0794 };
0795
0796 struct __gmp_binary_modulus
0797 {
0798 static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v)
0799 { mpz_tdiv_r(z, w, v); }
0800
0801 static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l)
0802 { mpz_tdiv_r_ui(z, w, l); }
0803 static void eval(mpz_ptr z, unsigned long int l, mpz_srcptr w)
0804 {
0805 if (mpz_sgn(w) >= 0)
0806 {
0807 if (mpz_fits_ulong_p(w))
0808 mpz_set_ui(z, l % mpz_get_ui(w));
0809 else
0810 mpz_set_ui(z, l);
0811 }
0812 else
0813 {
0814 mpz_neg(z, w);
0815 if (mpz_fits_ulong_p(z))
0816 mpz_set_ui(z, l % mpz_get_ui(z));
0817 else
0818 mpz_set_ui(z, l);
0819 }
0820 }
0821 static void eval(mpz_ptr z, mpz_srcptr w, signed long int l)
0822 {
0823 mpz_tdiv_r_ui (z, w, __gmpxx_abs_ui(l));
0824 }
0825 static void eval(mpz_ptr z, signed long int l, mpz_srcptr w)
0826 {
0827 if (mpz_fits_slong_p(w))
0828 mpz_set_si(z, l % mpz_get_si(w));
0829 else
0830 {
0831
0832
0833 mpz_set_si (z, mpz_cmpabs_ui (w, __gmpxx_abs_ui(l)) == 0 ? 0 : l);
0834 }
0835 }
0836 static void eval(mpz_ptr z, mpz_srcptr w, double d)
0837 { __GMPXX_TMPZ_D; mpz_tdiv_r (z, w, temp); }
0838 static void eval(mpz_ptr z, double d, mpz_srcptr w)
0839 { __GMPXX_TMPZ_D; mpz_tdiv_r (z, temp, w); }
0840 };
0841
0842 struct __gmp_binary_and
0843 {
0844 static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v)
0845 { mpz_and(z, w, v); }
0846
0847 static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l)
0848 { __GMPXX_TMPZ_UI; mpz_and (z, w, temp); }
0849 static void eval(mpz_ptr z, unsigned long int l, mpz_srcptr w)
0850 { eval(z, w, l); }
0851 static void eval(mpz_ptr z, mpz_srcptr w, signed long int l)
0852 { __GMPXX_TMPZ_SI; mpz_and (z, w, temp); }
0853 static void eval(mpz_ptr z, signed long int l, mpz_srcptr w)
0854 { eval(z, w, l); }
0855 static void eval(mpz_ptr z, mpz_srcptr w, double d)
0856 { __GMPXX_TMPZ_D; mpz_and (z, w, temp); }
0857 static void eval(mpz_ptr z, double d, mpz_srcptr w)
0858 { eval(z, w, d); }
0859 };
0860
0861 struct __gmp_binary_ior
0862 {
0863 static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v)
0864 { mpz_ior(z, w, v); }
0865 static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l)
0866 { __GMPXX_TMPZ_UI; mpz_ior (z, w, temp); }
0867 static void eval(mpz_ptr z, unsigned long int l, mpz_srcptr w)
0868 { eval(z, w, l); }
0869 static void eval(mpz_ptr z, mpz_srcptr w, signed long int l)
0870 { __GMPXX_TMPZ_SI; mpz_ior (z, w, temp); }
0871 static void eval(mpz_ptr z, signed long int l, mpz_srcptr w)
0872 { eval(z, w, l); }
0873 static void eval(mpz_ptr z, mpz_srcptr w, double d)
0874 { __GMPXX_TMPZ_D; mpz_ior (z, w, temp); }
0875 static void eval(mpz_ptr z, double d, mpz_srcptr w)
0876 { eval(z, w, d); }
0877 };
0878
0879 struct __gmp_binary_xor
0880 {
0881 static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v)
0882 { mpz_xor(z, w, v); }
0883 static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l)
0884 { __GMPXX_TMPZ_UI; mpz_xor (z, w, temp); }
0885 static void eval(mpz_ptr z, unsigned long int l, mpz_srcptr w)
0886 { eval(z, w, l); }
0887 static void eval(mpz_ptr z, mpz_srcptr w, signed long int l)
0888 { __GMPXX_TMPZ_SI; mpz_xor (z, w, temp); }
0889 static void eval(mpz_ptr z, signed long int l, mpz_srcptr w)
0890 { eval(z, w, l); }
0891 static void eval(mpz_ptr z, mpz_srcptr w, double d)
0892 { __GMPXX_TMPZ_D; mpz_xor (z, w, temp); }
0893 static void eval(mpz_ptr z, double d, mpz_srcptr w)
0894 { eval(z, w, d); }
0895 };
0896
0897 struct __gmp_cmp_function
0898 {
0899 static int eval(mpz_srcptr z, mpz_srcptr w) { return mpz_cmp(z, w); }
0900
0901 static int eval(mpz_srcptr z, unsigned long int l)
0902 { return mpz_cmp_ui(z, l); }
0903 static int eval(unsigned long int l, mpz_srcptr z)
0904 { return -mpz_cmp_ui(z, l); }
0905 static int eval(mpz_srcptr z, signed long int l)
0906 { return mpz_cmp_si(z, l); }
0907 static int eval(signed long int l, mpz_srcptr z)
0908 { return -mpz_cmp_si(z, l); }
0909 static int eval(mpz_srcptr z, double d)
0910 { return mpz_cmp_d(z, d); }
0911 static int eval(double d, mpz_srcptr z)
0912 { return -mpz_cmp_d(z, d); }
0913
0914 static int eval(mpq_srcptr q, mpq_srcptr r) { return mpq_cmp(q, r); }
0915
0916 static int eval(mpq_srcptr q, unsigned long int l)
0917 { return mpq_cmp_ui(q, l, 1); }
0918 static int eval(unsigned long int l, mpq_srcptr q)
0919 { return -mpq_cmp_ui(q, l, 1); }
0920 static int eval(mpq_srcptr q, signed long int l)
0921 { return mpq_cmp_si(q, l, 1); }
0922 static int eval(signed long int l, mpq_srcptr q)
0923 { return -mpq_cmp_si(q, l, 1); }
0924 static int eval(mpq_srcptr q, double d)
0925 { __GMPXX_TMPQ_D; return mpq_cmp (q, temp); }
0926 static int eval(double d, mpq_srcptr q)
0927 { __GMPXX_TMPQ_D; return mpq_cmp (temp, q); }
0928 static int eval(mpq_srcptr q, mpz_srcptr z)
0929 { return mpq_cmp_z(q, z); }
0930 static int eval(mpz_srcptr z, mpq_srcptr q)
0931 { return -mpq_cmp_z(q, z); }
0932
0933 static int eval(mpf_srcptr f, mpf_srcptr g) { return mpf_cmp(f, g); }
0934
0935 static int eval(mpf_srcptr f, unsigned long int l)
0936 { return mpf_cmp_ui(f, l); }
0937 static int eval(unsigned long int l, mpf_srcptr f)
0938 { return -mpf_cmp_ui(f, l); }
0939 static int eval(mpf_srcptr f, signed long int l)
0940 { return mpf_cmp_si(f, l); }
0941 static int eval(signed long int l, mpf_srcptr f)
0942 { return -mpf_cmp_si(f, l); }
0943 static int eval(mpf_srcptr f, double d)
0944 { return mpf_cmp_d(f, d); }
0945 static int eval(double d, mpf_srcptr f)
0946 { return -mpf_cmp_d(f, d); }
0947 static int eval(mpf_srcptr f, mpz_srcptr z)
0948 { return mpf_cmp_z(f, z); }
0949 static int eval(mpz_srcptr z, mpf_srcptr f)
0950 { return -mpf_cmp_z(f, z); }
0951 static int eval(mpf_srcptr f, mpq_srcptr q)
0952 {
0953 mpf_t qf;
0954 mpf_init(qf);
0955 mpf_set_q(qf, q);
0956 int ret = eval(f, qf);
0957 mpf_clear(qf);
0958 return ret;
0959 }
0960 static int eval(mpq_srcptr q, mpf_srcptr f)
0961 { return -eval(f, q); }
0962 };
0963
0964 struct __gmp_binary_equal
0965 {
0966 static bool eval(mpz_srcptr z, mpz_srcptr w) { return mpz_cmp(z, w) == 0; }
0967
0968 static bool eval(mpz_srcptr z, unsigned long int l)
0969 { return mpz_cmp_ui(z, l) == 0; }
0970 static bool eval(unsigned long int l, mpz_srcptr z)
0971 { return eval(z, l); }
0972 static bool eval(mpz_srcptr z, signed long int l)
0973 { return mpz_cmp_si(z, l) == 0; }
0974 static bool eval(signed long int l, mpz_srcptr z)
0975 { return eval(z, l); }
0976 static bool eval(mpz_srcptr z, double d)
0977 { return mpz_cmp_d(z, d) == 0; }
0978 static bool eval(double d, mpz_srcptr z)
0979 { return eval(z, d); }
0980
0981 static bool eval(mpq_srcptr q, mpq_srcptr r)
0982 { return mpq_equal(q, r) != 0; }
0983
0984 static bool eval(mpq_srcptr q, unsigned long int l)
0985 { return ((__GMPXX_CONSTANT(l) && l == 0) ||
0986 mpz_cmp_ui(mpq_denref(q), 1) == 0) &&
0987 mpz_cmp_ui(mpq_numref(q), l) == 0; }
0988 static bool eval(unsigned long int l, mpq_srcptr q)
0989 { return eval(q, l); }
0990 static bool eval(mpq_srcptr q, signed long int l)
0991 { return ((__GMPXX_CONSTANT(l) && l == 0) ||
0992 mpz_cmp_ui(mpq_denref(q), 1) == 0) &&
0993 mpz_cmp_si(mpq_numref(q), l) == 0; }
0994 static bool eval(signed long int l, mpq_srcptr q)
0995 { return eval(q, l); }
0996 static bool eval(mpq_srcptr q, double d)
0997 { __GMPXX_TMPQ_D; return mpq_equal (q, temp) != 0; }
0998 static bool eval(double d, mpq_srcptr q)
0999 { return eval(q, d); }
1000 static bool eval(mpq_srcptr q, mpz_srcptr z)
1001 { return mpz_cmp_ui(mpq_denref(q), 1) == 0 && mpz_cmp(mpq_numref(q), z) == 0; }
1002 static bool eval(mpz_srcptr z, mpq_srcptr q)
1003 { return eval(q, z); }
1004
1005 static bool eval(mpf_srcptr f, mpf_srcptr g) { return mpf_cmp(f, g) == 0; }
1006
1007 static bool eval(mpf_srcptr f, unsigned long int l)
1008 { return mpf_cmp_ui(f, l) == 0; }
1009 static bool eval(unsigned long int l, mpf_srcptr f)
1010 { return eval(f, l); }
1011 static bool eval(mpf_srcptr f, signed long int l)
1012 { return mpf_cmp_si(f, l) == 0; }
1013 static bool eval(signed long int l, mpf_srcptr f)
1014 { return eval(f, l); }
1015 static bool eval(mpf_srcptr f, double d)
1016 { return mpf_cmp_d(f, d) == 0; }
1017 static bool eval(double d, mpf_srcptr f)
1018 { return eval(f, d); }
1019 static bool eval(mpf_srcptr f, mpz_srcptr z)
1020 { return mpf_cmp_z(f, z) == 0; }
1021 static bool eval(mpz_srcptr z, mpf_srcptr f)
1022 { return eval(f, z); }
1023 static bool eval(mpf_srcptr f, mpq_srcptr q)
1024 { return __gmp_cmp_function::eval(f, q) == 0; }
1025 static bool eval(mpq_srcptr q, mpf_srcptr f)
1026 { return eval(f, q); }
1027 };
1028
1029 struct __gmp_binary_less
1030 {
1031 static bool eval(mpz_srcptr z, mpz_srcptr w) { return mpz_cmp(z, w) < 0; }
1032
1033 static bool eval(mpz_srcptr z, unsigned long int l)
1034 { return mpz_cmp_ui(z, l) < 0; }
1035 static bool eval(unsigned long int l, mpz_srcptr z)
1036 { return mpz_cmp_ui(z, l) > 0; }
1037 static bool eval(mpz_srcptr z, signed long int l)
1038 { return mpz_cmp_si(z, l) < 0; }
1039 static bool eval(signed long int l, mpz_srcptr z)
1040 { return mpz_cmp_si(z, l) > 0; }
1041 static bool eval(mpz_srcptr z, double d)
1042 { return mpz_cmp_d(z, d) < 0; }
1043 static bool eval(double d, mpz_srcptr z)
1044 { return mpz_cmp_d(z, d) > 0; }
1045
1046 static bool eval(mpq_srcptr q, mpq_srcptr r) { return mpq_cmp(q, r) < 0; }
1047
1048 static bool eval(mpq_srcptr q, unsigned long int l)
1049 { return mpq_cmp_ui(q, l, 1) < 0; }
1050 static bool eval(unsigned long int l, mpq_srcptr q)
1051 { return mpq_cmp_ui(q, l, 1) > 0; }
1052 static bool eval(mpq_srcptr q, signed long int l)
1053 { return mpq_cmp_si(q, l, 1) < 0; }
1054 static bool eval(signed long int l, mpq_srcptr q)
1055 { return mpq_cmp_si(q, l, 1) > 0; }
1056 static bool eval(mpq_srcptr q, double d)
1057 { __GMPXX_TMPQ_D; return mpq_cmp (q, temp) < 0; }
1058 static bool eval(double d, mpq_srcptr q)
1059 { __GMPXX_TMPQ_D; return mpq_cmp (temp, q) < 0; }
1060 static bool eval(mpq_srcptr q, mpz_srcptr z)
1061 { return mpq_cmp_z(q, z) < 0; }
1062 static bool eval(mpz_srcptr z, mpq_srcptr q)
1063 { return mpq_cmp_z(q, z) > 0; }
1064
1065 static bool eval(mpf_srcptr f, mpf_srcptr g) { return mpf_cmp(f, g) < 0; }
1066
1067 static bool eval(mpf_srcptr f, unsigned long int l)
1068 { return mpf_cmp_ui(f, l) < 0; }
1069 static bool eval(unsigned long int l, mpf_srcptr f)
1070 { return mpf_cmp_ui(f, l) > 0; }
1071 static bool eval(mpf_srcptr f, signed long int l)
1072 { return mpf_cmp_si(f, l) < 0; }
1073 static bool eval(signed long int l, mpf_srcptr f)
1074 { return mpf_cmp_si(f, l) > 0; }
1075 static bool eval(mpf_srcptr f, double d)
1076 { return mpf_cmp_d(f, d) < 0; }
1077 static bool eval(double d, mpf_srcptr f)
1078 { return mpf_cmp_d(f, d) > 0; }
1079 static bool eval(mpf_srcptr f, mpz_srcptr z)
1080 { return mpf_cmp_z(f, z) < 0; }
1081 static bool eval(mpz_srcptr z, mpf_srcptr f)
1082 { return mpf_cmp_z(f, z) > 0; }
1083 static bool eval(mpf_srcptr f, mpq_srcptr q)
1084 { return __gmp_cmp_function::eval(f, q) < 0; }
1085 static bool eval(mpq_srcptr q, mpf_srcptr f)
1086 { return __gmp_cmp_function::eval(q, f) < 0; }
1087 };
1088
1089 struct __gmp_binary_greater
1090 {
1091 template <class T, class U>
1092 static inline bool eval(T t, U u) { return __gmp_binary_less::eval(u, t); }
1093 };
1094
1095 struct __gmp_unary_increment
1096 {
1097 static void eval(mpz_ptr z) { mpz_add_ui(z, z, 1); }
1098 static void eval(mpq_ptr q)
1099 { mpz_add(mpq_numref(q), mpq_numref(q), mpq_denref(q)); }
1100 static void eval(mpf_ptr f) { mpf_add_ui(f, f, 1); }
1101 };
1102
1103 struct __gmp_unary_decrement
1104 {
1105 static void eval(mpz_ptr z) { mpz_sub_ui(z, z, 1); }
1106 static void eval(mpq_ptr q)
1107 { mpz_sub(mpq_numref(q), mpq_numref(q), mpq_denref(q)); }
1108 static void eval(mpf_ptr f) { mpf_sub_ui(f, f, 1); }
1109 };
1110
1111 struct __gmp_abs_function
1112 {
1113 static void eval(mpz_ptr z, mpz_srcptr w) { mpz_abs(z, w); }
1114 static void eval(mpq_ptr q, mpq_srcptr r) { mpq_abs(q, r); }
1115 static void eval(mpf_ptr f, mpf_srcptr g) { mpf_abs(f, g); }
1116 };
1117
1118 struct __gmp_trunc_function
1119 {
1120 static void eval(mpf_ptr f, mpf_srcptr g) { mpf_trunc(f, g); }
1121 };
1122
1123 struct __gmp_floor_function
1124 {
1125 static void eval(mpf_ptr f, mpf_srcptr g) { mpf_floor(f, g); }
1126 };
1127
1128 struct __gmp_ceil_function
1129 {
1130 static void eval(mpf_ptr f, mpf_srcptr g) { mpf_ceil(f, g); }
1131 };
1132
1133 struct __gmp_sqrt_function
1134 {
1135 static void eval(mpz_ptr z, mpz_srcptr w) { mpz_sqrt(z, w); }
1136 static void eval(mpf_ptr f, mpf_srcptr g) { mpf_sqrt(f, g); }
1137 };
1138
1139 struct __gmp_hypot_function
1140 {
1141 static void eval(mpf_ptr f, mpf_srcptr g, mpf_srcptr h)
1142 {
1143 mpf_t temp;
1144 mpf_init2(temp, mpf_get_prec(f));
1145 mpf_mul(temp, g, g);
1146 mpf_mul(f, h, h);
1147 mpf_add(f, f, temp);
1148 mpf_sqrt(f, f);
1149 mpf_clear(temp);
1150 }
1151
1152 static void eval(mpf_ptr f, mpf_srcptr g, unsigned long int l)
1153 {
1154 mpf_t temp;
1155 mpf_init2(temp, mpf_get_prec(f));
1156 mpf_mul(temp, g, g);
1157 mpf_set_ui(f, l);
1158 mpf_mul_ui(f, f, l);
1159 mpf_add(f, f, temp);
1160 mpf_clear(temp);
1161 mpf_sqrt(f, f);
1162 }
1163 static void eval(mpf_ptr f, unsigned long int l, mpf_srcptr g)
1164 { eval(f, g, l); }
1165 static void eval(mpf_ptr f, mpf_srcptr g, signed long int l)
1166 { eval(f, g, __gmpxx_abs_ui(l)); }
1167 static void eval(mpf_ptr f, signed long int l, mpf_srcptr g)
1168 { eval(f, g, l); }
1169 static void eval(mpf_ptr f, mpf_srcptr g, double d)
1170 {
1171 mpf_t temp;
1172 mpf_init2(temp, mpf_get_prec(f));
1173 mpf_mul(temp, g, g);
1174 mpf_set_d(f, d);
1175 mpf_mul(f, f, f);
1176 mpf_add(f, f, temp);
1177 mpf_sqrt(f, f);
1178 mpf_clear(temp);
1179 }
1180 static void eval(mpf_ptr f, double d, mpf_srcptr g)
1181 { eval(f, g, d); }
1182 };
1183
1184 struct __gmp_sgn_function
1185 {
1186 static int eval(mpz_srcptr z) { return mpz_sgn(z); }
1187 static int eval(mpq_srcptr q) { return mpq_sgn(q); }
1188 static int eval(mpf_srcptr f) { return mpf_sgn(f); }
1189 };
1190
1191 struct __gmp_gcd_function
1192 {
1193 static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v)
1194 { mpz_gcd(z, w, v); }
1195 static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l)
1196 { mpz_gcd_ui(z, w, l); }
1197 static void eval(mpz_ptr z, unsigned long int l, mpz_srcptr w)
1198 { eval(z, w, l); }
1199 static void eval(mpz_ptr z, mpz_srcptr w, signed long int l)
1200 { eval(z, w, __gmpxx_abs_ui(l)); }
1201 static void eval(mpz_ptr z, signed long int l, mpz_srcptr w)
1202 { eval(z, w, l); }
1203 static void eval(mpz_ptr z, mpz_srcptr w, double d)
1204 { __GMPXX_TMPZ_D; mpz_gcd (z, w, temp); }
1205 static void eval(mpz_ptr z, double d, mpz_srcptr w)
1206 { eval(z, w, d); }
1207 };
1208
1209 struct __gmp_lcm_function
1210 {
1211 static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v)
1212 { mpz_lcm(z, w, v); }
1213 static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l)
1214 { mpz_lcm_ui(z, w, l); }
1215 static void eval(mpz_ptr z, unsigned long int l, mpz_srcptr w)
1216 { eval(z, w, l); }
1217 static void eval(mpz_ptr z, mpz_srcptr w, signed long int l)
1218 { eval(z, w, __gmpxx_abs_ui(l)); }
1219 static void eval(mpz_ptr z, signed long int l, mpz_srcptr w)
1220 { eval(z, w, l); }
1221 static void eval(mpz_ptr z, mpz_srcptr w, double d)
1222 { __GMPXX_TMPZ_D; mpz_lcm (z, w, temp); }
1223 static void eval(mpz_ptr z, double d, mpz_srcptr w)
1224 { eval(z, w, d); }
1225 };
1226
1227 struct __gmp_rand_function
1228 {
1229 static void eval(mpz_ptr z, gmp_randstate_t s, mp_bitcnt_t l)
1230 { mpz_urandomb(z, s, l); }
1231 static void eval(mpz_ptr z, gmp_randstate_t s, mpz_srcptr w)
1232 { mpz_urandomm(z, s, w); }
1233 static void eval(mpf_ptr f, gmp_randstate_t s, mp_bitcnt_t prec)
1234 { mpf_urandomb(f, s, prec); }
1235 };
1236
1237 struct __gmp_fac_function
1238 {
1239 static void eval(mpz_ptr z, unsigned long l) { mpz_fac_ui(z, l); }
1240 static void eval(mpz_ptr z, signed long l)
1241 {
1242 if (l < 0)
1243 throw std::domain_error ("factorial(negative)");
1244 eval(z, static_cast<unsigned long>(l));
1245 }
1246 static void eval(mpz_ptr z, mpz_srcptr w)
1247 {
1248 if (!mpz_fits_ulong_p(w))
1249 {
1250 if (mpz_sgn(w) < 0)
1251 throw std::domain_error ("factorial(negative)");
1252 else
1253 throw std::bad_alloc();
1254 }
1255 eval(z, mpz_get_ui(w));
1256 }
1257 static void eval(mpz_ptr z, double d)
1258 { __GMPXX_TMPZ_D; eval (z, temp); }
1259 };
1260
1261 struct __gmp_primorial_function
1262 {
1263 static void eval(mpz_ptr z, unsigned long l) { mpz_primorial_ui(z, l); }
1264 static void eval(mpz_ptr z, signed long l)
1265 {
1266 if (l < 0)
1267 throw std::domain_error ("primorial(negative)");
1268 eval(z, static_cast<unsigned long>(l));
1269 }
1270 static void eval(mpz_ptr z, mpz_srcptr w)
1271 {
1272 if (!mpz_fits_ulong_p(w))
1273 {
1274 if (mpz_sgn(w) < 0)
1275 throw std::domain_error ("primorial(negative)");
1276 else
1277 throw std::bad_alloc();
1278 }
1279 eval(z, mpz_get_ui(w));
1280 }
1281 static void eval(mpz_ptr z, double d)
1282 { __GMPXX_TMPZ_D; eval (z, temp); }
1283 };
1284
1285 struct __gmp_fib_function
1286 {
1287 static void eval(mpz_ptr z, unsigned long l) { mpz_fib_ui(z, l); }
1288 static void eval(mpz_ptr z, signed long l)
1289 {
1290 if (l < 0)
1291 {
1292 eval(z, -static_cast<unsigned long>(l));
1293 if ((l & 1) == 0)
1294 mpz_neg(z, z);
1295 }
1296 else
1297 eval(z, static_cast<unsigned long>(l));
1298 }
1299 static void eval(mpz_ptr z, mpz_srcptr w)
1300 {
1301 if (!mpz_fits_slong_p(w))
1302 throw std::bad_alloc();
1303 eval(z, mpz_get_si(w));
1304 }
1305 static void eval(mpz_ptr z, double d)
1306 { __GMPXX_TMPZ_D; eval (z, temp); }
1307 };
1308
1309
1310
1311
1312
1313
1314
1315
1316 extern "C" {
1317 typedef void (*__gmp_freefunc_t) (void *, size_t);
1318 }
1319 struct __gmp_alloc_cstring
1320 {
1321 char *str;
1322 __gmp_alloc_cstring(char *s) { str = s; }
1323 ~__gmp_alloc_cstring()
1324 {
1325 __gmp_freefunc_t freefunc;
1326 mp_get_memory_functions (NULL, NULL, &freefunc);
1327 (*freefunc) (str, std::strlen(str)+1);
1328 }
1329 };
1330
1331
1332
1333 template <class T, class U>
1334 class __gmp_expr;
1335
1336
1337
1338 template <class T>
1339 struct __gmp_resolve_ref
1340 {
1341 typedef T ref_type;
1342 };
1343
1344 template <class T, class U>
1345 struct __gmp_resolve_ref<__gmp_expr<T, U> >
1346 {
1347 typedef const __gmp_expr<T, U> & ref_type;
1348 };
1349
1350
1351 template <class T, class U = T>
1352 struct __gmp_resolve_expr;
1353
1354 template <>
1355 struct __gmp_resolve_expr<mpz_t>
1356 {
1357 typedef mpz_t value_type;
1358 typedef mpz_ptr ptr_type;
1359 typedef mpz_srcptr srcptr_type;
1360 };
1361
1362 template <>
1363 struct __gmp_resolve_expr<mpq_t>
1364 {
1365 typedef mpq_t value_type;
1366 typedef mpq_ptr ptr_type;
1367 typedef mpq_srcptr srcptr_type;
1368 };
1369
1370 template <>
1371 struct __gmp_resolve_expr<mpf_t>
1372 {
1373 typedef mpf_t value_type;
1374 typedef mpf_ptr ptr_type;
1375 typedef mpf_srcptr srcptr_type;
1376 };
1377
1378 template <>
1379 struct __gmp_resolve_expr<mpz_t, mpq_t>
1380 {
1381 typedef mpq_t value_type;
1382 };
1383
1384 template <>
1385 struct __gmp_resolve_expr<mpq_t, mpz_t>
1386 {
1387 typedef mpq_t value_type;
1388 };
1389
1390 template <>
1391 struct __gmp_resolve_expr<mpz_t, mpf_t>
1392 {
1393 typedef mpf_t value_type;
1394 };
1395
1396 template <>
1397 struct __gmp_resolve_expr<mpf_t, mpz_t>
1398 {
1399 typedef mpf_t value_type;
1400 };
1401
1402 template <>
1403 struct __gmp_resolve_expr<mpq_t, mpf_t>
1404 {
1405 typedef mpf_t value_type;
1406 };
1407
1408 template <>
1409 struct __gmp_resolve_expr<mpf_t, mpq_t>
1410 {
1411 typedef mpf_t value_type;
1412 };
1413
1414 #if __GMPXX_USE_CXX11
1415 namespace std {
1416 template <class T, class U, class V, class W>
1417 struct common_type <__gmp_expr<T, U>, __gmp_expr<V, W> >
1418 {
1419 private:
1420 typedef typename __gmp_resolve_expr<T, V>::value_type X;
1421 public:
1422 typedef __gmp_expr<X, X> type;
1423 };
1424
1425 template <class T, class U>
1426 struct common_type <__gmp_expr<T, U> >
1427 {
1428 typedef __gmp_expr<T, T> type;
1429 };
1430
1431 #define __GMPXX_DECLARE_COMMON_TYPE(typ) \
1432 template <class T, class U> \
1433 struct common_type <__gmp_expr<T, U>, typ > \
1434 { \
1435 typedef __gmp_expr<T, T> type; \
1436 }; \
1437 \
1438 template <class T, class U> \
1439 struct common_type <typ, __gmp_expr<T, U> > \
1440 { \
1441 typedef __gmp_expr<T, T> type; \
1442 }
1443
1444 __GMPXX_DECLARE_COMMON_TYPE(signed char);
1445 __GMPXX_DECLARE_COMMON_TYPE(unsigned char);
1446 __GMPXX_DECLARE_COMMON_TYPE(signed int);
1447 __GMPXX_DECLARE_COMMON_TYPE(unsigned int);
1448 __GMPXX_DECLARE_COMMON_TYPE(signed short int);
1449 __GMPXX_DECLARE_COMMON_TYPE(unsigned short int);
1450 __GMPXX_DECLARE_COMMON_TYPE(signed long int);
1451 __GMPXX_DECLARE_COMMON_TYPE(unsigned long int);
1452 __GMPXX_DECLARE_COMMON_TYPE(float);
1453 __GMPXX_DECLARE_COMMON_TYPE(double);
1454 #undef __GMPXX_DECLARE_COMMON_TYPE
1455 }
1456 #endif
1457
1458
1459 template <class T, class Op>
1460 struct __gmp_unary_expr
1461 {
1462 typename __gmp_resolve_ref<T>::ref_type val;
1463
1464 __gmp_unary_expr(const T &v) : val(v) { }
1465 private:
1466 __gmp_unary_expr();
1467 };
1468
1469 template <class T, class U, class Op>
1470 struct __gmp_binary_expr
1471 {
1472 typename __gmp_resolve_ref<T>::ref_type val1;
1473 typename __gmp_resolve_ref<U>::ref_type val2;
1474
1475 __gmp_binary_expr(const T &v1, const U &v2) : val1(v1), val2(v2) { }
1476 private:
1477 __gmp_binary_expr();
1478 };
1479
1480
1481
1482
1483
1484
1485
1486 #define __GMPP_DECLARE_COMPOUND_OPERATOR(fun) \
1487 template <class T, class U> \
1488 __gmp_expr<value_type, value_type> & fun(const __gmp_expr<T, U> &);
1489
1490 #define __GMPN_DECLARE_COMPOUND_OPERATOR(fun) \
1491 __gmp_expr & fun(signed char); \
1492 __gmp_expr & fun(unsigned char); \
1493 __gmp_expr & fun(signed int); \
1494 __gmp_expr & fun(unsigned int); \
1495 __gmp_expr & fun(signed short int); \
1496 __gmp_expr & fun(unsigned short int); \
1497 __gmp_expr & fun(signed long int); \
1498 __gmp_expr & fun(unsigned long int); \
1499 __gmp_expr & fun(float); \
1500 __gmp_expr & fun(double); \
1501
1502
1503 #define __GMP_DECLARE_COMPOUND_OPERATOR(fun) \
1504 __GMPP_DECLARE_COMPOUND_OPERATOR(fun) \
1505 __GMPN_DECLARE_COMPOUND_OPERATOR(fun)
1506
1507 #define __GMP_DECLARE_COMPOUND_OPERATOR_UI(fun) \
1508 __gmp_expr & fun(mp_bitcnt_t);
1509
1510 #define __GMP_DECLARE_INCREMENT_OPERATOR(fun) \
1511 inline __gmp_expr & fun(); \
1512 inline __gmp_expr fun(int);
1513
1514 #define __GMPXX_DEFINE_ARITHMETIC_CONSTRUCTORS \
1515 __gmp_expr(signed char c) { init_si(c); } \
1516 __gmp_expr(unsigned char c) { init_ui(c); } \
1517 __gmp_expr(signed int i) { init_si(i); } \
1518 __gmp_expr(unsigned int i) { init_ui(i); } \
1519 __gmp_expr(signed short int s) { init_si(s); } \
1520 __gmp_expr(unsigned short int s) { init_ui(s); } \
1521 __gmp_expr(signed long int l) { init_si(l); } \
1522 __gmp_expr(unsigned long int l) { init_ui(l); } \
1523 __gmp_expr(float f) { init_d(f); } \
1524 __gmp_expr(double d) { init_d(d); }
1525
1526 #define __GMPXX_DEFINE_ARITHMETIC_ASSIGNMENTS \
1527 __gmp_expr & operator=(signed char c) { assign_si(c); return *this; } \
1528 __gmp_expr & operator=(unsigned char c) { assign_ui(c); return *this; } \
1529 __gmp_expr & operator=(signed int i) { assign_si(i); return *this; } \
1530 __gmp_expr & operator=(unsigned int i) { assign_ui(i); return *this; } \
1531 __gmp_expr & operator=(signed short int s) { assign_si(s); return *this; } \
1532 __gmp_expr & operator=(unsigned short int s) { assign_ui(s); return *this; } \
1533 __gmp_expr & operator=(signed long int l) { assign_si(l); return *this; } \
1534 __gmp_expr & operator=(unsigned long int l) { assign_ui(l); return *this; } \
1535 __gmp_expr & operator=(float f) { assign_d(f); return *this; } \
1536 __gmp_expr & operator=(double d) { assign_d(d); return *this; }
1537
1538 #define __GMPP_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun) \
1539 template <class U> \
1540 static __gmp_expr<T, __gmp_unary_expr<__gmp_expr<T, U>, eval_fun> > \
1541 fun(const __gmp_expr<T, U> &expr);
1542
1543 #define __GMPNN_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, type, bigtype) \
1544 static inline __gmp_expr<T, __gmp_unary_expr<bigtype, eval_fun> > \
1545 fun(type expr);
1546
1547 #define __GMPNS_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, type) \
1548 __GMPNN_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, type, signed long)
1549 #define __GMPNU_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, type) \
1550 __GMPNN_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, type, unsigned long)
1551 #define __GMPND_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, type) \
1552 __GMPNN_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, type, double)
1553
1554 #define __GMPN_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun) \
1555 __GMPNS_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, signed char) \
1556 __GMPNU_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, unsigned char) \
1557 __GMPNS_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, signed int) \
1558 __GMPNU_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, unsigned int) \
1559 __GMPNS_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, signed short int) \
1560 __GMPNU_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, unsigned short int) \
1561 __GMPNS_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, signed long int) \
1562 __GMPNU_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, unsigned long int) \
1563 __GMPND_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, float) \
1564 __GMPND_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, double)
1565
1566 #define __GMP_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun) \
1567 __GMPP_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun) \
1568 __GMPN_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun)
1569
1570
1571
1572 template <>
1573 class __gmp_expr<mpz_t, mpz_t>
1574 {
1575 private:
1576 typedef mpz_t value_type;
1577 value_type mp;
1578
1579
1580 void assign_ui(unsigned long l)
1581 {
1582 if (__GMPXX_CONSTANT_TRUE(l == 0))
1583 __get_mp()->_mp_size = 0;
1584 else
1585 mpz_set_ui(mp, l);
1586 }
1587 void assign_si(signed long l)
1588 {
1589 if (__GMPXX_CONSTANT_TRUE(l >= 0))
1590 assign_ui(l);
1591 else if (__GMPXX_CONSTANT_TRUE(l <= 0))
1592 {
1593 assign_ui(-static_cast<unsigned long>(l));
1594 mpz_neg(mp, mp);
1595 }
1596 else
1597 mpz_set_si(mp, l);
1598 }
1599 void assign_d (double d)
1600 {
1601 mpz_set_d (mp, d);
1602 }
1603
1604 void init_ui(unsigned long l)
1605 {
1606 if (__GMPXX_CONSTANT_TRUE(l == 0))
1607 mpz_init(mp);
1608 else
1609 mpz_init_set_ui(mp, l);
1610 }
1611 void init_si(signed long l)
1612 {
1613 if (__GMPXX_CONSTANT_TRUE(l >= 0))
1614 init_ui(l);
1615 else if (__GMPXX_CONSTANT_TRUE(l <= 0))
1616 {
1617 init_ui(-static_cast<unsigned long>(l));
1618 mpz_neg(mp, mp);
1619 }
1620 else
1621 mpz_init_set_si(mp, l);
1622 }
1623 void init_d (double d)
1624 {
1625 mpz_init_set_d (mp, d);
1626 }
1627
1628 public:
1629 mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); }
1630
1631
1632 __gmp_expr() __GMPXX_NOEXCEPT { mpz_init(mp); }
1633
1634 __gmp_expr(const __gmp_expr &z) { mpz_init_set(mp, z.mp); }
1635 #if __GMPXX_USE_CXX11
1636 __gmp_expr(__gmp_expr &&z) noexcept
1637 { *__get_mp() = *z.__get_mp(); mpz_init(z.mp); }
1638 #endif
1639 template <class T>
1640 __gmp_expr(const __gmp_expr<mpz_t, T> &expr)
1641 { mpz_init(mp); __gmp_set_expr(mp, expr); }
1642 template <class T, class U>
1643 explicit __gmp_expr(const __gmp_expr<T, U> &expr)
1644 { mpz_init(mp); __gmp_set_expr(mp, expr); }
1645
1646 __GMPXX_DEFINE_ARITHMETIC_CONSTRUCTORS
1647
1648 explicit __gmp_expr(const char *s, int base = 0)
1649 {
1650 if (mpz_init_set_str (mp, s, base) != 0)
1651 {
1652 mpz_clear (mp);
1653 throw std::invalid_argument ("mpz_set_str");
1654 }
1655 }
1656 explicit __gmp_expr(const std::string &s, int base = 0)
1657 {
1658 if (mpz_init_set_str(mp, s.c_str(), base) != 0)
1659 {
1660 mpz_clear (mp);
1661 throw std::invalid_argument ("mpz_set_str");
1662 }
1663 }
1664
1665 explicit __gmp_expr(mpz_srcptr z) { mpz_init_set(mp, z); }
1666
1667 ~__gmp_expr() { mpz_clear(mp); }
1668
1669 void swap(__gmp_expr& z) __GMPXX_NOEXCEPT
1670 { std::swap(*__get_mp(), *z.__get_mp()); }
1671
1672
1673 __gmp_expr & operator=(const __gmp_expr &z)
1674 { mpz_set(mp, z.mp); return *this; }
1675 #if __GMPXX_USE_CXX11
1676 __gmp_expr & operator=(__gmp_expr &&z) noexcept
1677 { swap(z); return *this; }
1678 #endif
1679 template <class T, class U>
1680 __gmp_expr<value_type, value_type> & operator=(const __gmp_expr<T, U> &expr)
1681 { __gmp_set_expr(mp, expr); return *this; }
1682
1683 __GMPXX_DEFINE_ARITHMETIC_ASSIGNMENTS
1684
1685 __gmp_expr & operator=(const char *s)
1686 {
1687 if (mpz_set_str (mp, s, 0) != 0)
1688 throw std::invalid_argument ("mpz_set_str");
1689 return *this;
1690 }
1691 __gmp_expr & operator=(const std::string &s)
1692 {
1693 if (mpz_set_str(mp, s.c_str(), 0) != 0)
1694 throw std::invalid_argument ("mpz_set_str");
1695 return *this;
1696 }
1697
1698
1699 int set_str(const char *s, int base)
1700 { return mpz_set_str(mp, s, base); }
1701 int set_str(const std::string &s, int base)
1702 { return mpz_set_str(mp, s.c_str(), base); }
1703 std::string get_str(int base = 10) const
1704 {
1705 __gmp_alloc_cstring temp(mpz_get_str(0, base, mp));
1706 return std::string(temp.str);
1707 }
1708
1709
1710 mpz_srcptr __get_mp() const { return mp; }
1711 mpz_ptr __get_mp() { return mp; }
1712 mpz_srcptr get_mpz_t() const { return mp; }
1713 mpz_ptr get_mpz_t() { return mp; }
1714
1715 signed long int get_si() const { return mpz_get_si(mp); }
1716 unsigned long int get_ui() const { return mpz_get_ui(mp); }
1717 double get_d() const { return mpz_get_d(mp); }
1718
1719
1720
1721 bool fits_sint_p() const { return mpz_fits_sint_p(mp); }
1722 bool fits_uint_p() const { return mpz_fits_uint_p(mp); }
1723 bool fits_sshort_p() const { return mpz_fits_sshort_p(mp); }
1724 bool fits_ushort_p() const { return mpz_fits_ushort_p(mp); }
1725 bool fits_slong_p() const { return mpz_fits_slong_p(mp); }
1726 bool fits_ulong_p() const { return mpz_fits_ulong_p(mp); }
1727
1728
1729
1730
1731 #if __GMPXX_USE_CXX11
1732 explicit operator bool() const { return __get_mp()->_mp_size != 0; }
1733 #endif
1734
1735
1736 __GMP_DECLARE_COMPOUND_OPERATOR(operator+=)
1737 __GMP_DECLARE_COMPOUND_OPERATOR(operator-=)
1738 __GMP_DECLARE_COMPOUND_OPERATOR(operator*=)
1739 __GMP_DECLARE_COMPOUND_OPERATOR(operator/=)
1740 __GMP_DECLARE_COMPOUND_OPERATOR(operator%=)
1741
1742 __GMP_DECLARE_COMPOUND_OPERATOR(operator&=)
1743 __GMP_DECLARE_COMPOUND_OPERATOR(operator|=)
1744 __GMP_DECLARE_COMPOUND_OPERATOR(operator^=)
1745
1746 __GMP_DECLARE_COMPOUND_OPERATOR_UI(operator<<=)
1747 __GMP_DECLARE_COMPOUND_OPERATOR_UI(operator>>=)
1748
1749 __GMP_DECLARE_INCREMENT_OPERATOR(operator++)
1750 __GMP_DECLARE_INCREMENT_OPERATOR(operator--)
1751
1752 __GMP_DECLARE_UNARY_STATIC_MEMFUN(mpz_t, factorial, __gmp_fac_function)
1753 __GMP_DECLARE_UNARY_STATIC_MEMFUN(mpz_t, primorial, __gmp_primorial_function)
1754 __GMP_DECLARE_UNARY_STATIC_MEMFUN(mpz_t, fibonacci, __gmp_fib_function)
1755 };
1756
1757 typedef __gmp_expr<mpz_t, mpz_t> mpz_class;
1758
1759
1760
1761
1762 template <>
1763 class __gmp_expr<mpq_t, mpq_t>
1764 {
1765 private:
1766 typedef mpq_t value_type;
1767 value_type mp;
1768
1769
1770 void assign_ui(unsigned long l) { mpq_set_ui(mp, l, 1); }
1771 void assign_si(signed long l)
1772 {
1773 if (__GMPXX_CONSTANT_TRUE(l >= 0))
1774 assign_ui(l);
1775 else
1776 mpq_set_si(mp, l, 1);
1777 }
1778 void assign_d (double d) { mpq_set_d (mp, d); }
1779
1780 void init_ui(unsigned long l) { mpq_init(mp); get_num() = l; }
1781 void init_si(signed long l) { mpq_init(mp); get_num() = l; }
1782 void init_d (double d) { mpq_init(mp); assign_d (d); }
1783
1784 public:
1785 mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); }
1786 void canonicalize() { mpq_canonicalize(mp); }
1787
1788
1789 __gmp_expr() { mpq_init(mp); }
1790
1791 __gmp_expr(const __gmp_expr &q)
1792 {
1793 mpz_init_set(mpq_numref(mp), mpq_numref(q.mp));
1794 mpz_init_set(mpq_denref(mp), mpq_denref(q.mp));
1795 }
1796 #if __GMPXX_USE_CXX11
1797 __gmp_expr(__gmp_expr &&q)
1798 { *mp = *q.mp; mpq_init(q.mp); }
1799 __gmp_expr(mpz_class &&z)
1800 {
1801 *mpq_numref(mp) = *z.get_mpz_t();
1802 mpz_init_set_ui(mpq_denref(mp), 1);
1803 mpz_init(z.get_mpz_t());
1804 }
1805 #endif
1806 template <class T>
1807 __gmp_expr(const __gmp_expr<mpz_t, T> &expr)
1808 { mpq_init(mp); __gmp_set_expr(mp, expr); }
1809 template <class T>
1810 __gmp_expr(const __gmp_expr<mpq_t, T> &expr)
1811 { mpq_init(mp); __gmp_set_expr(mp, expr); }
1812 template <class T, class U>
1813 explicit __gmp_expr(const __gmp_expr<T, U> &expr)
1814 { mpq_init(mp); __gmp_set_expr(mp, expr); }
1815
1816 __GMPXX_DEFINE_ARITHMETIC_CONSTRUCTORS
1817
1818 explicit __gmp_expr(const char *s, int base = 0)
1819 {
1820 mpq_init (mp);
1821
1822
1823 if (s == 0)
1824 {
1825
1826 mpz_set_si(mpq_denref(mp), base);
1827 }
1828 else if (mpq_set_str(mp, s, base) != 0)
1829 {
1830 mpq_clear (mp);
1831 throw std::invalid_argument ("mpq_set_str");
1832 }
1833 }
1834 explicit __gmp_expr(const std::string &s, int base = 0)
1835 {
1836 mpq_init(mp);
1837 if (mpq_set_str (mp, s.c_str(), base) != 0)
1838 {
1839 mpq_clear (mp);
1840 throw std::invalid_argument ("mpq_set_str");
1841 }
1842 }
1843 explicit __gmp_expr(mpq_srcptr q)
1844 {
1845 mpz_init_set(mpq_numref(mp), mpq_numref(q));
1846 mpz_init_set(mpq_denref(mp), mpq_denref(q));
1847 }
1848
1849 __gmp_expr(const mpz_class &num, const mpz_class &den)
1850 {
1851 mpz_init_set(mpq_numref(mp), num.get_mpz_t());
1852 mpz_init_set(mpq_denref(mp), den.get_mpz_t());
1853 }
1854
1855 ~__gmp_expr() { mpq_clear(mp); }
1856
1857 void swap(__gmp_expr& q) __GMPXX_NOEXCEPT { std::swap(*mp, *q.mp); }
1858
1859
1860 __gmp_expr & operator=(const __gmp_expr &q)
1861 { mpq_set(mp, q.mp); return *this; }
1862 #if __GMPXX_USE_CXX11
1863 __gmp_expr & operator=(__gmp_expr &&q) noexcept
1864 { swap(q); return *this; }
1865 __gmp_expr & operator=(mpz_class &&z) noexcept
1866 { get_num() = std::move(z); get_den() = 1u; return *this; }
1867 #endif
1868 template <class T, class U>
1869 __gmp_expr<value_type, value_type> & operator=(const __gmp_expr<T, U> &expr)
1870 { __gmp_set_expr(mp, expr); return *this; }
1871
1872 __GMPXX_DEFINE_ARITHMETIC_ASSIGNMENTS
1873
1874 __gmp_expr & operator=(const char *s)
1875 {
1876 if (mpq_set_str (mp, s, 0) != 0)
1877 throw std::invalid_argument ("mpq_set_str");
1878 return *this;
1879 }
1880 __gmp_expr & operator=(const std::string &s)
1881 {
1882 if (mpq_set_str(mp, s.c_str(), 0) != 0)
1883 throw std::invalid_argument ("mpq_set_str");
1884 return *this;
1885 }
1886
1887
1888 int set_str(const char *s, int base)
1889 { return mpq_set_str(mp, s, base); }
1890 int set_str(const std::string &s, int base)
1891 { return mpq_set_str(mp, s.c_str(), base); }
1892 std::string get_str(int base = 10) const
1893 {
1894 __gmp_alloc_cstring temp(mpq_get_str(0, base, mp));
1895 return std::string(temp.str);
1896 }
1897
1898
1899
1900
1901
1902
1903
1904
1905 const mpz_class & get_num() const
1906 { return reinterpret_cast<const mpz_class &>(*mpq_numref(mp)); }
1907 mpz_class & get_num()
1908 { return reinterpret_cast<mpz_class &>(*mpq_numref(mp)); }
1909 const mpz_class & get_den() const
1910 { return reinterpret_cast<const mpz_class &>(*mpq_denref(mp)); }
1911 mpz_class & get_den()
1912 { return reinterpret_cast<mpz_class &>(*mpq_denref(mp)); }
1913
1914 mpq_srcptr __get_mp() const { return mp; }
1915 mpq_ptr __get_mp() { return mp; }
1916 mpq_srcptr get_mpq_t() const { return mp; }
1917 mpq_ptr get_mpq_t() { return mp; }
1918
1919 mpz_srcptr get_num_mpz_t() const { return mpq_numref(mp); }
1920 mpz_ptr get_num_mpz_t() { return mpq_numref(mp); }
1921 mpz_srcptr get_den_mpz_t() const { return mpq_denref(mp); }
1922 mpz_ptr get_den_mpz_t() { return mpq_denref(mp); }
1923
1924 double get_d() const { return mpq_get_d(mp); }
1925
1926 #if __GMPXX_USE_CXX11
1927 explicit operator bool() const { return mpq_numref(mp)->_mp_size != 0; }
1928 #endif
1929
1930
1931 __GMP_DECLARE_COMPOUND_OPERATOR(operator+=)
1932 __GMP_DECLARE_COMPOUND_OPERATOR(operator-=)
1933 __GMP_DECLARE_COMPOUND_OPERATOR(operator*=)
1934 __GMP_DECLARE_COMPOUND_OPERATOR(operator/=)
1935
1936 __GMP_DECLARE_COMPOUND_OPERATOR_UI(operator<<=)
1937 __GMP_DECLARE_COMPOUND_OPERATOR_UI(operator>>=)
1938
1939 __GMP_DECLARE_INCREMENT_OPERATOR(operator++)
1940 __GMP_DECLARE_INCREMENT_OPERATOR(operator--)
1941 };
1942
1943 typedef __gmp_expr<mpq_t, mpq_t> mpq_class;
1944
1945
1946
1947
1948 template <>
1949 class __gmp_expr<mpf_t, mpf_t>
1950 {
1951 private:
1952 typedef mpf_t value_type;
1953 value_type mp;
1954
1955
1956 void assign_ui(unsigned long l) { mpf_set_ui(mp, l); }
1957 void assign_si(signed long l)
1958 {
1959 if (__GMPXX_CONSTANT_TRUE(l >= 0))
1960 assign_ui(l);
1961 else
1962 mpf_set_si(mp, l);
1963 }
1964 void assign_d (double d) { mpf_set_d (mp, d); }
1965
1966 void init_ui(unsigned long l)
1967 {
1968 if (__GMPXX_CONSTANT_TRUE(l == 0))
1969 mpf_init(mp);
1970 else
1971 mpf_init_set_ui(mp, l);
1972 }
1973 void init_si(signed long l)
1974 {
1975 if (__GMPXX_CONSTANT_TRUE(l >= 0))
1976 init_ui(l);
1977 else
1978 mpf_init_set_si(mp, l);
1979 }
1980 void init_d (double d) { mpf_init_set_d (mp, d); }
1981
1982 public:
1983 mp_bitcnt_t get_prec() const { return mpf_get_prec(mp); }
1984
1985 void set_prec(mp_bitcnt_t prec) { mpf_set_prec(mp, prec); }
1986 void set_prec_raw(mp_bitcnt_t prec) { mpf_set_prec_raw(mp, prec); }
1987
1988
1989 __gmp_expr() { mpf_init(mp); }
1990
1991 __gmp_expr(const __gmp_expr &f)
1992 { mpf_init2(mp, f.get_prec()); mpf_set(mp, f.mp); }
1993 #if __GMPXX_USE_CXX11
1994 __gmp_expr(__gmp_expr &&f)
1995 { *mp = *f.mp; mpf_init2(f.mp, get_prec()); }
1996 #endif
1997 __gmp_expr(const __gmp_expr &f, mp_bitcnt_t prec)
1998 { mpf_init2(mp, prec); mpf_set(mp, f.mp); }
1999 template <class T, class U>
2000 __gmp_expr(const __gmp_expr<T, U> &expr)
2001 { mpf_init2(mp, expr.get_prec()); __gmp_set_expr(mp, expr); }
2002 template <class T, class U>
2003 __gmp_expr(const __gmp_expr<T, U> &expr, mp_bitcnt_t prec)
2004 { mpf_init2(mp, prec); __gmp_set_expr(mp, expr); }
2005
2006 __GMPXX_DEFINE_ARITHMETIC_CONSTRUCTORS
2007
2008 __gmp_expr(signed char c, mp_bitcnt_t prec)
2009 { mpf_init2(mp, prec); mpf_set_si(mp, c); }
2010 __gmp_expr(unsigned char c, mp_bitcnt_t prec)
2011 { mpf_init2(mp, prec); mpf_set_ui(mp, c); }
2012
2013 __gmp_expr(signed int i, mp_bitcnt_t prec)
2014 { mpf_init2(mp, prec); mpf_set_si(mp, i); }
2015 __gmp_expr(unsigned int i, mp_bitcnt_t prec)
2016 { mpf_init2(mp, prec); mpf_set_ui(mp, i); }
2017
2018 __gmp_expr(signed short int s, mp_bitcnt_t prec)
2019 { mpf_init2(mp, prec); mpf_set_si(mp, s); }
2020 __gmp_expr(unsigned short int s, mp_bitcnt_t prec)
2021 { mpf_init2(mp, prec); mpf_set_ui(mp, s); }
2022
2023 __gmp_expr(signed long int l, mp_bitcnt_t prec)
2024 { mpf_init2(mp, prec); mpf_set_si(mp, l); }
2025 __gmp_expr(unsigned long int l, mp_bitcnt_t prec)
2026 { mpf_init2(mp, prec); mpf_set_ui(mp, l); }
2027
2028 __gmp_expr(float f, mp_bitcnt_t prec)
2029 { mpf_init2(mp, prec); mpf_set_d(mp, f); }
2030 __gmp_expr(double d, mp_bitcnt_t prec)
2031 { mpf_init2(mp, prec); mpf_set_d(mp, d); }
2032
2033
2034
2035
2036 explicit __gmp_expr(const char *s)
2037 {
2038 if (mpf_init_set_str (mp, s, 0) != 0)
2039 {
2040 mpf_clear (mp);
2041 throw std::invalid_argument ("mpf_set_str");
2042 }
2043 }
2044 __gmp_expr(const char *s, mp_bitcnt_t prec, int base = 0)
2045 {
2046 mpf_init2(mp, prec);
2047 if (mpf_set_str(mp, s, base) != 0)
2048 {
2049 mpf_clear (mp);
2050 throw std::invalid_argument ("mpf_set_str");
2051 }
2052 }
2053 explicit __gmp_expr(const std::string &s)
2054 {
2055 if (mpf_init_set_str(mp, s.c_str(), 0) != 0)
2056 {
2057 mpf_clear (mp);
2058 throw std::invalid_argument ("mpf_set_str");
2059 }
2060 }
2061 __gmp_expr(const std::string &s, mp_bitcnt_t prec, int base = 0)
2062 {
2063 mpf_init2(mp, prec);
2064 if (mpf_set_str(mp, s.c_str(), base) != 0)
2065 {
2066 mpf_clear (mp);
2067 throw std::invalid_argument ("mpf_set_str");
2068 }
2069 }
2070
2071 explicit __gmp_expr(mpf_srcptr f)
2072 { mpf_init2(mp, mpf_get_prec(f)); mpf_set(mp, f); }
2073 __gmp_expr(mpf_srcptr f, mp_bitcnt_t prec)
2074 { mpf_init2(mp, prec); mpf_set(mp, f); }
2075
2076 ~__gmp_expr() { mpf_clear(mp); }
2077
2078 void swap(__gmp_expr& f) __GMPXX_NOEXCEPT { std::swap(*mp, *f.mp); }
2079
2080
2081 __gmp_expr & operator=(const __gmp_expr &f)
2082 { mpf_set(mp, f.mp); return *this; }
2083 #if __GMPXX_USE_CXX11
2084 __gmp_expr & operator=(__gmp_expr &&f) noexcept
2085 { swap(f); return *this; }
2086 #endif
2087 template <class T, class U>
2088 __gmp_expr<value_type, value_type> & operator=(const __gmp_expr<T, U> &expr)
2089 { __gmp_set_expr(mp, expr); return *this; }
2090
2091 __GMPXX_DEFINE_ARITHMETIC_ASSIGNMENTS
2092
2093 __gmp_expr & operator=(const char *s)
2094 {
2095 if (mpf_set_str (mp, s, 0) != 0)
2096 throw std::invalid_argument ("mpf_set_str");
2097 return *this;
2098 }
2099 __gmp_expr & operator=(const std::string &s)
2100 {
2101 if (mpf_set_str(mp, s.c_str(), 0) != 0)
2102 throw std::invalid_argument ("mpf_set_str");
2103 return *this;
2104 }
2105
2106
2107 int set_str(const char *s, int base)
2108 { return mpf_set_str(mp, s, base); }
2109 int set_str(const std::string &s, int base)
2110 { return mpf_set_str(mp, s.c_str(), base); }
2111 std::string get_str(mp_exp_t &expo, int base = 10, size_t size = 0) const
2112 {
2113 __gmp_alloc_cstring temp(mpf_get_str(0, &expo, base, size, mp));
2114 return std::string(temp.str);
2115 }
2116
2117
2118 mpf_srcptr __get_mp() const { return mp; }
2119 mpf_ptr __get_mp() { return mp; }
2120 mpf_srcptr get_mpf_t() const { return mp; }
2121 mpf_ptr get_mpf_t() { return mp; }
2122
2123 signed long int get_si() const { return mpf_get_si(mp); }
2124 unsigned long int get_ui() const { return mpf_get_ui(mp); }
2125 double get_d() const { return mpf_get_d(mp); }
2126
2127
2128
2129 bool fits_sint_p() const { return mpf_fits_sint_p(mp); }
2130 bool fits_uint_p() const { return mpf_fits_uint_p(mp); }
2131 bool fits_sshort_p() const { return mpf_fits_sshort_p(mp); }
2132 bool fits_ushort_p() const { return mpf_fits_ushort_p(mp); }
2133 bool fits_slong_p() const { return mpf_fits_slong_p(mp); }
2134 bool fits_ulong_p() const { return mpf_fits_ulong_p(mp); }
2135
2136
2137
2138
2139 #if __GMPXX_USE_CXX11
2140 explicit operator bool() const { return mpf_sgn(mp) != 0; }
2141 #endif
2142
2143
2144 __GMP_DECLARE_COMPOUND_OPERATOR(operator+=)
2145 __GMP_DECLARE_COMPOUND_OPERATOR(operator-=)
2146 __GMP_DECLARE_COMPOUND_OPERATOR(operator*=)
2147 __GMP_DECLARE_COMPOUND_OPERATOR(operator/=)
2148
2149 __GMP_DECLARE_COMPOUND_OPERATOR_UI(operator<<=)
2150 __GMP_DECLARE_COMPOUND_OPERATOR_UI(operator>>=)
2151
2152 __GMP_DECLARE_INCREMENT_OPERATOR(operator++)
2153 __GMP_DECLARE_INCREMENT_OPERATOR(operator--)
2154 };
2155
2156 typedef __gmp_expr<mpf_t, mpf_t> mpf_class;
2157
2158
2159
2160
2161
2162 #if __GMPXX_USE_CXX11
2163 inline mpz_class operator"" _mpz(const char* s)
2164 {
2165 return mpz_class(s);
2166 }
2167
2168 inline mpq_class operator"" _mpq(const char* s)
2169 {
2170 mpq_class q;
2171 q.get_num() = s;
2172 return q;
2173 }
2174
2175 inline mpf_class operator"" _mpf(const char* s)
2176 {
2177 return mpf_class(s);
2178 }
2179 #endif
2180
2181
2182
2183
2184
2185 template <class T, class U>
2186 inline std::ostream & operator<<
2187 (std::ostream &o, const __gmp_expr<T, U> &expr)
2188 {
2189 __gmp_expr<T, T> const& temp(expr);
2190 return o << temp.__get_mp();
2191 }
2192
2193 template <class T>
2194 inline std::istream & operator>>(std::istream &i, __gmp_expr<T, T> &expr)
2195 {
2196 return i >> expr.__get_mp();
2197 }
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212 inline void __gmp_set_expr(mpz_ptr z, const mpz_class &w)
2213 {
2214 mpz_set(z, w.get_mpz_t());
2215 }
2216
2217 template <class T>
2218 inline void __gmp_set_expr(mpz_ptr z, const __gmp_expr<mpz_t, T> &expr)
2219 {
2220 expr.eval(z);
2221 }
2222
2223 template <class T>
2224 inline void __gmp_set_expr(mpz_ptr z, const __gmp_expr<mpq_t, T> &expr)
2225 {
2226 mpq_class const& temp(expr);
2227 mpz_set_q(z, temp.get_mpq_t());
2228 }
2229
2230 template <class T>
2231 inline void __gmp_set_expr(mpz_ptr z, const __gmp_expr<mpf_t, T> &expr)
2232 {
2233 mpf_class const& temp(expr);
2234 mpz_set_f(z, temp.get_mpf_t());
2235 }
2236
2237 inline void __gmp_set_expr(mpq_ptr q, const mpz_class &z)
2238 {
2239 mpq_set_z(q, z.get_mpz_t());
2240 }
2241
2242 template <class T>
2243 inline void __gmp_set_expr(mpq_ptr q, const __gmp_expr<mpz_t, T> &expr)
2244 {
2245 __gmp_set_expr(mpq_numref(q), expr);
2246 mpz_set_ui(mpq_denref(q), 1);
2247 }
2248
2249 inline void __gmp_set_expr(mpq_ptr q, const mpq_class &r)
2250 {
2251 mpq_set(q, r.get_mpq_t());
2252 }
2253
2254 template <class T>
2255 inline void __gmp_set_expr(mpq_ptr q, const __gmp_expr<mpq_t, T> &expr)
2256 {
2257 expr.eval(q);
2258 }
2259
2260 template <class T>
2261 inline void __gmp_set_expr(mpq_ptr q, const __gmp_expr<mpf_t, T> &expr)
2262 {
2263 mpf_class const& temp(expr);
2264 mpq_set_f(q, temp.get_mpf_t());
2265 }
2266
2267 template <class T>
2268 inline void __gmp_set_expr(mpf_ptr f, const __gmp_expr<mpz_t, T> &expr)
2269 {
2270 mpz_class const& temp(expr);
2271 mpf_set_z(f, temp.get_mpz_t());
2272 }
2273
2274 template <class T>
2275 inline void __gmp_set_expr(mpf_ptr f, const __gmp_expr<mpq_t, T> &expr)
2276 {
2277 mpq_class const& temp(expr);
2278 mpf_set_q(f, temp.get_mpq_t());
2279 }
2280
2281 inline void __gmp_set_expr(mpf_ptr f, const mpf_class &g)
2282 {
2283 mpf_set(f, g.get_mpf_t());
2284 }
2285
2286 template <class T>
2287 inline void __gmp_set_expr(mpf_ptr f, const __gmp_expr<mpf_t, T> &expr)
2288 {
2289 expr.eval(f);
2290 }
2291
2292
2293
2294
2295 template <class T>
2296 class __gmp_temp
2297 {
2298 __gmp_expr<T, T> val;
2299 public:
2300 template<class U, class V>
2301 __gmp_temp(U const& u, V) : val (u) {}
2302 typename __gmp_resolve_expr<T>::srcptr_type
2303 __get_mp() const { return val.__get_mp(); }
2304 };
2305
2306 template <>
2307 class __gmp_temp <mpf_t>
2308 {
2309 mpf_class val;
2310 public:
2311 template<class U>
2312 __gmp_temp(U const& u, mpf_ptr res) : val (u, mpf_get_prec(res)) {}
2313 mpf_srcptr __get_mp() const { return val.__get_mp(); }
2314 };
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335 template <class T, class Op>
2336 class __gmp_expr<T, __gmp_unary_expr<__gmp_expr<T, T>, Op> >
2337 {
2338 private:
2339 typedef __gmp_expr<T, T> val_type;
2340
2341 __gmp_unary_expr<val_type, Op> expr;
2342 public:
2343 explicit __gmp_expr(const val_type &val) : expr(val) { }
2344 void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
2345 { Op::eval(p, expr.val.__get_mp()); }
2346 const val_type & get_val() const { return expr.val; }
2347 mp_bitcnt_t get_prec() const { return expr.val.get_prec(); }
2348 };
2349
2350
2351
2352
2353 template <class T, class U, class Op>
2354 class __gmp_expr<T, __gmp_unary_expr<U, Op> >
2355 {
2356 private:
2357 typedef U val_type;
2358
2359 __gmp_unary_expr<val_type, Op> expr;
2360 public:
2361 explicit __gmp_expr(const val_type &val) : expr(val) { }
2362 void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
2363 { Op::eval(p, expr.val); }
2364 const val_type & get_val() const { return expr.val; }
2365 mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); }
2366 };
2367
2368
2369
2370
2371 template <class T, class U, class Op>
2372 class __gmp_expr<T, __gmp_unary_expr<__gmp_expr<T, U>, Op> >
2373 {
2374 private:
2375 typedef __gmp_expr<T, U> val_type;
2376
2377 __gmp_unary_expr<val_type, Op> expr;
2378 public:
2379 explicit __gmp_expr(const val_type &val) : expr(val) { }
2380 void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
2381 { expr.val.eval(p); Op::eval(p, p); }
2382 const val_type & get_val() const { return expr.val; }
2383 mp_bitcnt_t get_prec() const { return expr.val.get_prec(); }
2384 };
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399 template <class T, class Op>
2400 class __gmp_expr
2401 <T, __gmp_binary_expr<__gmp_expr<T, T>, __gmp_expr<T, T>, Op> >
2402 {
2403 private:
2404 typedef __gmp_expr<T, T> val1_type;
2405 typedef __gmp_expr<T, T> val2_type;
2406
2407 __gmp_binary_expr<val1_type, val2_type, Op> expr;
2408 public:
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 { Op::eval(p, expr.val1.__get_mp(), expr.val2.__get_mp()); }
2413 const val1_type & get_val1() const { return expr.val1; }
2414 const val2_type & get_val2() const { return expr.val2; }
2415 mp_bitcnt_t get_prec() const
2416 {
2417 mp_bitcnt_t prec1 = expr.val1.get_prec(),
2418 prec2 = expr.val2.get_prec();
2419 return (prec1 > prec2) ? prec1 : prec2;
2420 }
2421 };
2422
2423
2424
2425
2426 template <class T, class U, class Op>
2427 class __gmp_expr<T, __gmp_binary_expr<__gmp_expr<T, T>, U, Op> >
2428 {
2429 private:
2430 typedef __gmp_expr<T, T> val1_type;
2431 typedef U val2_type;
2432
2433 __gmp_binary_expr<val1_type, val2_type, Op> expr;
2434 public:
2435 __gmp_expr(const val1_type &val1, const val2_type &val2)
2436 : expr(val1, val2) { }
2437 void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
2438 { Op::eval(p, expr.val1.__get_mp(), expr.val2); }
2439 const val1_type & get_val1() const { return expr.val1; }
2440 const val2_type & get_val2() const { return expr.val2; }
2441 mp_bitcnt_t get_prec() const { return expr.val1.get_prec(); }
2442 };
2443
2444 template <class T, class U, class Op>
2445 class __gmp_expr<T, __gmp_binary_expr<U, __gmp_expr<T, T>, Op> >
2446 {
2447 private:
2448 typedef U val1_type;
2449 typedef __gmp_expr<T, T> val2_type;
2450
2451 __gmp_binary_expr<val1_type, val2_type, Op> expr;
2452 public:
2453 __gmp_expr(const val1_type &val1, const val2_type &val2)
2454 : expr(val1, val2) { }
2455 void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
2456 { Op::eval(p, expr.val1, expr.val2.__get_mp()); }
2457 const val1_type & get_val1() const { return expr.val1; }
2458 const val2_type & get_val2() const { return expr.val2; }
2459 mp_bitcnt_t get_prec() const { return expr.val2.get_prec(); }
2460 };
2461
2462
2463
2464
2465 template <class T, class U, class V, class Op>
2466 class __gmp_expr
2467 <T, __gmp_binary_expr<__gmp_expr<T, T>, __gmp_expr<U, V>, Op> >
2468 {
2469 private:
2470 typedef __gmp_expr<T, T> val1_type;
2471 typedef __gmp_expr<U, V> val2_type;
2472
2473 __gmp_binary_expr<val1_type, val2_type, Op> expr;
2474 public:
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 if(p != expr.val1.__get_mp())
2480 {
2481 __gmp_set_expr(p, expr.val2);
2482 Op::eval(p, expr.val1.__get_mp(), p);
2483 }
2484 else
2485 {
2486 __gmp_temp<T> temp(expr.val2, p);
2487 Op::eval(p, expr.val1.__get_mp(), temp.__get_mp());
2488 }
2489 }
2490 const val1_type & get_val1() const { return expr.val1; }
2491 const val2_type & get_val2() const { return expr.val2; }
2492 mp_bitcnt_t get_prec() const
2493 {
2494 mp_bitcnt_t prec1 = expr.val1.get_prec(),
2495 prec2 = expr.val2.get_prec();
2496 return (prec1 > prec2) ? prec1 : prec2;
2497 }
2498 };
2499
2500 template <class T, class U, class V, class Op>
2501 class __gmp_expr
2502 <T, __gmp_binary_expr<__gmp_expr<U, V>, __gmp_expr<T, T>, Op> >
2503 {
2504 private:
2505 typedef __gmp_expr<U, V> val1_type;
2506 typedef __gmp_expr<T, T> val2_type;
2507
2508 __gmp_binary_expr<val1_type, val2_type, Op> expr;
2509 public:
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 if(p != expr.val2.__get_mp())
2515 {
2516 __gmp_set_expr(p, expr.val1);
2517 Op::eval(p, p, expr.val2.__get_mp());
2518 }
2519 else
2520 {
2521 __gmp_temp<T> temp(expr.val1, p);
2522 Op::eval(p, temp.__get_mp(), expr.val2.__get_mp());
2523 }
2524 }
2525 const val1_type & get_val1() const { return expr.val1; }
2526 const val2_type & get_val2() const { return expr.val2; }
2527 mp_bitcnt_t get_prec() const
2528 {
2529 mp_bitcnt_t prec1 = expr.val1.get_prec(),
2530 prec2 = expr.val2.get_prec();
2531 return (prec1 > prec2) ? prec1 : prec2;
2532 }
2533 };
2534
2535 template <class T, class U, class Op>
2536 class __gmp_expr
2537 <T, __gmp_binary_expr<__gmp_expr<T, T>, __gmp_expr<T, U>, Op> >
2538 {
2539 private:
2540 typedef __gmp_expr<T, T> val1_type;
2541 typedef __gmp_expr<T, U> val2_type;
2542
2543 __gmp_binary_expr<val1_type, val2_type, Op> expr;
2544 public:
2545 __gmp_expr(const val1_type &val1, const val2_type &val2)
2546 : expr(val1, val2) { }
2547 void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
2548 {
2549 if(p != expr.val1.__get_mp())
2550 {
2551 __gmp_set_expr(p, expr.val2);
2552 Op::eval(p, expr.val1.__get_mp(), p);
2553 }
2554 else
2555 {
2556 __gmp_temp<T> temp(expr.val2, p);
2557 Op::eval(p, expr.val1.__get_mp(), temp.__get_mp());
2558 }
2559 }
2560 const val1_type & get_val1() const { return expr.val1; }
2561 const val2_type & get_val2() const { return expr.val2; }
2562 mp_bitcnt_t get_prec() const
2563 {
2564 mp_bitcnt_t prec1 = expr.val1.get_prec(),
2565 prec2 = expr.val2.get_prec();
2566 return (prec1 > prec2) ? prec1 : prec2;
2567 }
2568 };
2569
2570 template <class T, class U, class Op>
2571 class __gmp_expr
2572 <T, __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<T, T>, Op> >
2573 {
2574 private:
2575 typedef __gmp_expr<T, U> val1_type;
2576 typedef __gmp_expr<T, T> val2_type;
2577
2578 __gmp_binary_expr<val1_type, val2_type, Op> expr;
2579 public:
2580 __gmp_expr(const val1_type &val1, const val2_type &val2)
2581 : expr(val1, val2) { }
2582 void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
2583 {
2584 if(p != expr.val2.__get_mp())
2585 {
2586 __gmp_set_expr(p, expr.val1);
2587 Op::eval(p, p, expr.val2.__get_mp());
2588 }
2589 else
2590 {
2591 __gmp_temp<T> temp(expr.val1, p);
2592 Op::eval(p, temp.__get_mp(), expr.val2.__get_mp());
2593 }
2594 }
2595 const val1_type & get_val1() const { return expr.val1; }
2596 const val2_type & get_val2() const { return expr.val2; }
2597 mp_bitcnt_t get_prec() const
2598 {
2599 mp_bitcnt_t prec1 = expr.val1.get_prec(),
2600 prec2 = expr.val2.get_prec();
2601 return (prec1 > prec2) ? prec1 : prec2;
2602 }
2603 };
2604
2605
2606
2607
2608 template <class T, class U, class V, class Op>
2609 class __gmp_expr<T, __gmp_binary_expr<__gmp_expr<T, U>, V, Op> >
2610 {
2611 private:
2612 typedef __gmp_expr<T, U> val1_type;
2613 typedef V val2_type;
2614
2615 __gmp_binary_expr<val1_type, val2_type, Op> expr;
2616 public:
2617 __gmp_expr(const val1_type &val1, const val2_type &val2)
2618 : expr(val1, val2) { }
2619 void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
2620 {
2621 expr.val1.eval(p);
2622 Op::eval(p, p, expr.val2);
2623 }
2624 const val1_type & get_val1() const { return expr.val1; }
2625 const val2_type & get_val2() const { return expr.val2; }
2626 mp_bitcnt_t get_prec() const { return expr.val1.get_prec(); }
2627 };
2628
2629 template <class T, class U, class V, class Op>
2630 class __gmp_expr<T, __gmp_binary_expr<U, __gmp_expr<T, V>, Op> >
2631 {
2632 private:
2633 typedef U val1_type;
2634 typedef __gmp_expr<T, V> val2_type;
2635
2636 __gmp_binary_expr<val1_type, val2_type, Op> expr;
2637 public:
2638 __gmp_expr(const val1_type &val1, const val2_type &val2)
2639 : expr(val1, val2) { }
2640 void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
2641 {
2642 expr.val2.eval(p);
2643 Op::eval(p, expr.val1, p);
2644 }
2645 const val1_type & get_val1() const { return expr.val1; }
2646 const val2_type & get_val2() const { return expr.val2; }
2647 mp_bitcnt_t get_prec() const { return expr.val2.get_prec(); }
2648 };
2649
2650
2651
2652
2653 template <class T, class U, class V, class W, class Op>
2654 class __gmp_expr
2655 <T, __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<V, W>, Op> >
2656 {
2657 private:
2658 typedef __gmp_expr<T, U> val1_type;
2659 typedef __gmp_expr<V, W> val2_type;
2660
2661 __gmp_binary_expr<val1_type, val2_type, Op> expr;
2662 public:
2663 __gmp_expr(const val1_type &val1, const val2_type &val2)
2664 : expr(val1, val2) { }
2665 void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
2666 {
2667 __gmp_temp<T> temp2(expr.val2, p);
2668 expr.val1.eval(p);
2669 Op::eval(p, p, temp2.__get_mp());
2670 }
2671 const val1_type & get_val1() const { return expr.val1; }
2672 const val2_type & get_val2() const { return expr.val2; }
2673 mp_bitcnt_t get_prec() const
2674 {
2675 mp_bitcnt_t prec1 = expr.val1.get_prec(),
2676 prec2 = expr.val2.get_prec();
2677 return (prec1 > prec2) ? prec1 : prec2;
2678 }
2679 };
2680
2681 template <class T, class U, class V, class W, class Op>
2682 class __gmp_expr
2683 <T, __gmp_binary_expr<__gmp_expr<U, V>, __gmp_expr<T, W>, Op> >
2684 {
2685 private:
2686 typedef __gmp_expr<U, V> val1_type;
2687 typedef __gmp_expr<T, W> val2_type;
2688
2689 __gmp_binary_expr<val1_type, val2_type, Op> expr;
2690 public:
2691 __gmp_expr(const val1_type &val1, const val2_type &val2)
2692 : expr(val1, val2) { }
2693 void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
2694 {
2695 __gmp_temp<T> temp1(expr.val1, p);
2696 expr.val2.eval(p);
2697 Op::eval(p, temp1.__get_mp(), p);
2698 }
2699 const val1_type & get_val1() const { return expr.val1; }
2700 const val2_type & get_val2() const { return expr.val2; }
2701 mp_bitcnt_t get_prec() const
2702 {
2703 mp_bitcnt_t prec1 = expr.val1.get_prec(),
2704 prec2 = expr.val2.get_prec();
2705 return (prec1 > prec2) ? prec1 : prec2;
2706 }
2707 };
2708
2709 template <class T, class U, class V, class Op>
2710 class __gmp_expr
2711 <T, __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<T, V>, Op> >
2712 {
2713 private:
2714 typedef __gmp_expr<T, U> val1_type;
2715 typedef __gmp_expr<T, V> val2_type;
2716
2717 __gmp_binary_expr<val1_type, val2_type, Op> expr;
2718 public:
2719 __gmp_expr(const val1_type &val1, const val2_type &val2)
2720 : expr(val1, val2) { }
2721 void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
2722 {
2723 __gmp_temp<T> temp2(expr.val2, p);
2724 expr.val1.eval(p);
2725 Op::eval(p, p, temp2.__get_mp());
2726 }
2727 const val1_type & get_val1() const { return expr.val1; }
2728 const val2_type & get_val2() const { return expr.val2; }
2729 mp_bitcnt_t get_prec() const
2730 {
2731 mp_bitcnt_t prec1 = expr.val1.get_prec(),
2732 prec2 = expr.val2.get_prec();
2733 return (prec1 > prec2) ? prec1 : prec2;
2734 }
2735 };
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745 #define __GMPZQ_DEFINE_EXPR(eval_fun) \
2746 \
2747 template <> \
2748 class __gmp_expr<mpq_t, __gmp_binary_expr<mpz_class, mpq_class, eval_fun> > \
2749 { \
2750 private: \
2751 typedef mpz_class val1_type; \
2752 typedef mpq_class val2_type; \
2753 \
2754 __gmp_binary_expr<val1_type, val2_type, eval_fun> expr; \
2755 public: \
2756 __gmp_expr(const val1_type &val1, const val2_type &val2) \
2757 : expr(val1, val2) { } \
2758 void eval(mpq_ptr q) const \
2759 { eval_fun::eval(q, expr.val1.get_mpz_t(), expr.val2.get_mpq_t()); } \
2760 const val1_type & get_val1() const { return expr.val1; } \
2761 const val2_type & get_val2() const { return expr.val2; } \
2762 mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); } \
2763 }; \
2764 \
2765 template <> \
2766 class __gmp_expr<mpq_t, __gmp_binary_expr<mpq_class, mpz_class, eval_fun> > \
2767 { \
2768 private: \
2769 typedef mpq_class val1_type; \
2770 typedef mpz_class val2_type; \
2771 \
2772 __gmp_binary_expr<val1_type, val2_type, eval_fun> expr; \
2773 public: \
2774 __gmp_expr(const val1_type &val1, const val2_type &val2) \
2775 : expr(val1, val2) { } \
2776 void eval(mpq_ptr q) const \
2777 { eval_fun::eval(q, expr.val1.get_mpq_t(), expr.val2.get_mpz_t()); } \
2778 const val1_type & get_val1() const { return expr.val1; } \
2779 const val2_type & get_val2() const { return expr.val2; } \
2780 mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); } \
2781 }; \
2782 \
2783 template <class T> \
2784 class __gmp_expr \
2785 <mpq_t, __gmp_binary_expr<mpz_class, __gmp_expr<mpq_t, T>, eval_fun> > \
2786 { \
2787 private: \
2788 typedef mpz_class val1_type; \
2789 typedef __gmp_expr<mpq_t, T> val2_type; \
2790 \
2791 __gmp_binary_expr<val1_type, val2_type, eval_fun> expr; \
2792 public: \
2793 __gmp_expr(const val1_type &val1, const val2_type &val2) \
2794 : expr(val1, val2) { } \
2795 void eval(mpq_ptr q) const \
2796 { \
2797 mpq_class temp(expr.val2); \
2798 eval_fun::eval(q, expr.val1.get_mpz_t(), temp.get_mpq_t()); \
2799 } \
2800 const val1_type & get_val1() const { return expr.val1; } \
2801 const val2_type & get_val2() const { return expr.val2; } \
2802 mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); } \
2803 }; \
2804 \
2805 template <class T> \
2806 class __gmp_expr \
2807 <mpq_t, __gmp_binary_expr<mpq_class, __gmp_expr<mpz_t, T>, eval_fun> > \
2808 { \
2809 private: \
2810 typedef mpq_class val1_type; \
2811 typedef __gmp_expr<mpz_t, T> val2_type; \
2812 \
2813 __gmp_binary_expr<val1_type, val2_type, eval_fun> expr; \
2814 public: \
2815 __gmp_expr(const val1_type &val1, const val2_type &val2) \
2816 : expr(val1, val2) { } \
2817 void eval(mpq_ptr q) const \
2818 { \
2819 mpz_class temp(expr.val2); \
2820 eval_fun::eval(q, expr.val1.get_mpq_t(), temp.get_mpz_t()); \
2821 } \
2822 const val1_type & get_val1() const { return expr.val1; } \
2823 const val2_type & get_val2() const { return expr.val2; } \
2824 mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); } \
2825 }; \
2826 \
2827 template <class T> \
2828 class __gmp_expr \
2829 <mpq_t, __gmp_binary_expr<__gmp_expr<mpz_t, T>, mpq_class, eval_fun> > \
2830 { \
2831 private: \
2832 typedef __gmp_expr<mpz_t, T> val1_type; \
2833 typedef mpq_class val2_type; \
2834 \
2835 __gmp_binary_expr<val1_type, val2_type, eval_fun> expr; \
2836 public: \
2837 __gmp_expr(const val1_type &val1, const val2_type &val2) \
2838 : expr(val1, val2) { } \
2839 void eval(mpq_ptr q) const \
2840 { \
2841 mpz_class temp(expr.val1); \
2842 eval_fun::eval(q, temp.get_mpz_t(), expr.val2.get_mpq_t()); \
2843 } \
2844 const val1_type & get_val1() const { return expr.val1; } \
2845 const val2_type & get_val2() const { return expr.val2; } \
2846 mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); } \
2847 }; \
2848 \
2849 template <class T> \
2850 class __gmp_expr \
2851 <mpq_t, __gmp_binary_expr<__gmp_expr<mpq_t, T>, mpz_class, eval_fun> > \
2852 { \
2853 private: \
2854 typedef __gmp_expr<mpq_t, T> val1_type; \
2855 typedef mpz_class val2_type; \
2856 \
2857 __gmp_binary_expr<val1_type, val2_type, eval_fun> expr; \
2858 public: \
2859 __gmp_expr(const val1_type &val1, const val2_type &val2) \
2860 : expr(val1, val2) { } \
2861 void eval(mpq_ptr q) const \
2862 { \
2863 mpq_class temp(expr.val1); \
2864 eval_fun::eval(q, temp.get_mpq_t(), expr.val2.get_mpz_t()); \
2865 } \
2866 const val1_type & get_val1() const { return expr.val1; } \
2867 const val2_type & get_val2() const { return expr.val2; } \
2868 mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); } \
2869 }; \
2870 \
2871 template <class T, class U> \
2872 class __gmp_expr<mpq_t, __gmp_binary_expr \
2873 <__gmp_expr<mpz_t, T>, __gmp_expr<mpq_t, U>, eval_fun> > \
2874 { \
2875 private: \
2876 typedef __gmp_expr<mpz_t, T> val1_type; \
2877 typedef __gmp_expr<mpq_t, U> val2_type; \
2878 \
2879 __gmp_binary_expr<val1_type, val2_type, eval_fun> expr; \
2880 public: \
2881 __gmp_expr(const val1_type &val1, const val2_type &val2) \
2882 : expr(val1, val2) { } \
2883 void eval(mpq_ptr q) const \
2884 { \
2885 mpz_class temp1(expr.val1); \
2886 expr.val2.eval(q); \
2887 eval_fun::eval(q, temp1.get_mpz_t(), q); \
2888 } \
2889 const val1_type & get_val1() const { return expr.val1; } \
2890 const val2_type & get_val2() const { return expr.val2; } \
2891 mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); } \
2892 }; \
2893 \
2894 template <class T, class U> \
2895 class __gmp_expr<mpq_t, __gmp_binary_expr \
2896 <__gmp_expr<mpq_t, T>, __gmp_expr<mpz_t, U>, eval_fun> > \
2897 { \
2898 private: \
2899 typedef __gmp_expr<mpq_t, T> val1_type; \
2900 typedef __gmp_expr<mpz_t, U> val2_type; \
2901 \
2902 __gmp_binary_expr<val1_type, val2_type, eval_fun> expr; \
2903 public: \
2904 __gmp_expr(const val1_type &val1, const val2_type &val2) \
2905 : expr(val1, val2) { } \
2906 void eval(mpq_ptr q) const \
2907 { \
2908 mpz_class temp2(expr.val2); \
2909 expr.val1.eval(q); \
2910 eval_fun::eval(q, q, temp2.get_mpz_t()); \
2911 } \
2912 const val1_type & get_val1() const { return expr.val1; } \
2913 const val2_type & get_val2() const { return expr.val2; } \
2914 mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); } \
2915 };
2916
2917
2918 __GMPZQ_DEFINE_EXPR(__gmp_binary_plus)
2919 __GMPZQ_DEFINE_EXPR(__gmp_binary_minus)
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942 #define __GMP_DEFINE_UNARY_FUNCTION(fun, eval_fun) \
2943 \
2944 template <class T, class U> \
2945 inline __gmp_expr<T, __gmp_unary_expr<__gmp_expr<T, U>, eval_fun> > \
2946 fun(const __gmp_expr<T, U> &expr) \
2947 { \
2948 return __gmp_expr<T, __gmp_unary_expr<__gmp_expr<T, U>, eval_fun> >(expr); \
2949 }
2950
2951
2952
2953 #define __GMP_DEFINE_UNARY_FUNCTION_1(T, fun, eval_fun) \
2954 \
2955 template <class U> \
2956 inline __gmp_expr<T, __gmp_unary_expr<__gmp_expr<T, U>, eval_fun> > \
2957 fun(const __gmp_expr<T, U> &expr) \
2958 { \
2959 return __gmp_expr<T, __gmp_unary_expr<__gmp_expr<T, U>, eval_fun> >(expr); \
2960 }
2961
2962 #define __GMP_DEFINE_UNARY_TYPE_FUNCTION(type, fun, eval_fun) \
2963 \
2964 template <class T, class U> \
2965 inline type fun(const __gmp_expr<T, U> &expr) \
2966 { \
2967 __gmp_expr<T, T> const& temp(expr); \
2968 return eval_fun::eval(temp.__get_mp()); \
2969 }
2970
2971
2972
2973
2974 #define __GMPP_DEFINE_BINARY_FUNCTION(fun, eval_fun) \
2975 \
2976 template <class T, class U, class V, class W> \
2977 inline __gmp_expr<typename __gmp_resolve_expr<T, V>::value_type, \
2978 __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<V, W>, eval_fun> > \
2979 fun(const __gmp_expr<T, U> &expr1, const __gmp_expr<V, W> &expr2) \
2980 { \
2981 return __gmp_expr<typename __gmp_resolve_expr<T, V>::value_type, \
2982 __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<V, W>, eval_fun> > \
2983 (expr1, expr2); \
2984 }
2985
2986 #define __GMPNN_DEFINE_BINARY_FUNCTION(fun, eval_fun, type, bigtype) \
2987 \
2988 template <class T, class U> \
2989 inline __gmp_expr \
2990 <T, __gmp_binary_expr<__gmp_expr<T, U>, bigtype, eval_fun> > \
2991 fun(const __gmp_expr<T, U> &expr, type t) \
2992 { \
2993 return __gmp_expr \
2994 <T, __gmp_binary_expr<__gmp_expr<T, U>, bigtype, eval_fun> >(expr, t); \
2995 } \
2996 \
2997 template <class T, class U> \
2998 inline __gmp_expr \
2999 <T, __gmp_binary_expr<bigtype, __gmp_expr<T, U>, eval_fun> > \
3000 fun(type t, const __gmp_expr<T, U> &expr) \
3001 { \
3002 return __gmp_expr \
3003 <T, __gmp_binary_expr<bigtype, __gmp_expr<T, U>, eval_fun> >(t, expr); \
3004 }
3005
3006 #define __GMPNS_DEFINE_BINARY_FUNCTION(fun, eval_fun, type) \
3007 __GMPNN_DEFINE_BINARY_FUNCTION(fun, eval_fun, type, signed long int)
3008
3009 #define __GMPNU_DEFINE_BINARY_FUNCTION(fun, eval_fun, type) \
3010 __GMPNN_DEFINE_BINARY_FUNCTION(fun, eval_fun, type, unsigned long int)
3011
3012 #define __GMPND_DEFINE_BINARY_FUNCTION(fun, eval_fun, type) \
3013 __GMPNN_DEFINE_BINARY_FUNCTION(fun, eval_fun, type, double)
3014
3015 #define __GMPNLD_DEFINE_BINARY_FUNCTION(fun, eval_fun, type) \
3016 __GMPNN_DEFINE_BINARY_FUNCTION(fun, eval_fun, type, long double)
3017
3018 #define __GMPN_DEFINE_BINARY_FUNCTION(fun, eval_fun) \
3019 __GMPNS_DEFINE_BINARY_FUNCTION(fun, eval_fun, signed char) \
3020 __GMPNU_DEFINE_BINARY_FUNCTION(fun, eval_fun, unsigned char) \
3021 __GMPNS_DEFINE_BINARY_FUNCTION(fun, eval_fun, signed int) \
3022 __GMPNU_DEFINE_BINARY_FUNCTION(fun, eval_fun, unsigned int) \
3023 __GMPNS_DEFINE_BINARY_FUNCTION(fun, eval_fun, signed short int) \
3024 __GMPNU_DEFINE_BINARY_FUNCTION(fun, eval_fun, unsigned short int) \
3025 __GMPNS_DEFINE_BINARY_FUNCTION(fun, eval_fun, signed long int) \
3026 __GMPNU_DEFINE_BINARY_FUNCTION(fun, eval_fun, unsigned long int) \
3027 __GMPND_DEFINE_BINARY_FUNCTION(fun, eval_fun, float) \
3028 __GMPND_DEFINE_BINARY_FUNCTION(fun, eval_fun, double) \
3029
3030
3031 #define __GMP_DEFINE_BINARY_FUNCTION(fun, eval_fun) \
3032 __GMPP_DEFINE_BINARY_FUNCTION(fun, eval_fun) \
3033 __GMPN_DEFINE_BINARY_FUNCTION(fun, eval_fun)
3034
3035
3036
3037 #define __GMPP_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun) \
3038 \
3039 template <class U, class W> \
3040 inline __gmp_expr<T, \
3041 __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<T, W>, eval_fun> > \
3042 fun(const __gmp_expr<T, U> &expr1, const __gmp_expr<T, W> &expr2) \
3043 { \
3044 return __gmp_expr<T, \
3045 __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<T, W>, eval_fun> > \
3046 (expr1, expr2); \
3047 }
3048
3049 #define __GMPNN_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, type, bigtype) \
3050 \
3051 template <class U> \
3052 inline __gmp_expr \
3053 <T, __gmp_binary_expr<__gmp_expr<T, U>, bigtype, eval_fun> > \
3054 fun(const __gmp_expr<T, U> &expr, type t) \
3055 { \
3056 return __gmp_expr \
3057 <T, __gmp_binary_expr<__gmp_expr<T, U>, bigtype, eval_fun> >(expr, t); \
3058 } \
3059 \
3060 template <class U> \
3061 inline __gmp_expr \
3062 <T, __gmp_binary_expr<bigtype, __gmp_expr<T, U>, eval_fun> > \
3063 fun(type t, const __gmp_expr<T, U> &expr) \
3064 { \
3065 return __gmp_expr \
3066 <T, __gmp_binary_expr<bigtype, __gmp_expr<T, U>, eval_fun> >(t, expr); \
3067 }
3068
3069 #define __GMPNS_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, type) \
3070 __GMPNN_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, type, signed long int)
3071
3072 #define __GMPNU_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, type) \
3073 __GMPNN_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, type, unsigned long int)
3074
3075 #define __GMPND_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, type) \
3076 __GMPNN_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, type, double)
3077
3078 #define __GMPNLD_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, type) \
3079 __GMPNN_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, type, long double)
3080
3081 #define __GMPN_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun) \
3082 __GMPNS_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, signed char) \
3083 __GMPNU_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, unsigned char) \
3084 __GMPNS_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, signed int) \
3085 __GMPNU_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, unsigned int) \
3086 __GMPNS_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, signed short int) \
3087 __GMPNU_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, unsigned short int) \
3088 __GMPNS_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, signed long int) \
3089 __GMPNU_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, unsigned long int) \
3090 __GMPND_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, float) \
3091 __GMPND_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, double) \
3092
3093
3094 #define __GMP_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun) \
3095 __GMPP_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun) \
3096 __GMPN_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun)
3097
3098
3099 #define __GMP_DEFINE_BINARY_FUNCTION_UI(fun, eval_fun) \
3100 \
3101 template <class T, class U> \
3102 inline __gmp_expr \
3103 <T, __gmp_binary_expr<__gmp_expr<T, U>, mp_bitcnt_t, eval_fun> > \
3104 fun(const __gmp_expr<T, U> &expr, mp_bitcnt_t l) \
3105 { \
3106 return __gmp_expr<T, __gmp_binary_expr \
3107 <__gmp_expr<T, U>, mp_bitcnt_t, eval_fun> >(expr, l); \
3108 }
3109
3110
3111 #define __GMPP_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun) \
3112 \
3113 template <class T, class U, class V, class W> \
3114 inline type fun(const __gmp_expr<T, U> &expr1, \
3115 const __gmp_expr<V, W> &expr2) \
3116 { \
3117 __gmp_expr<T, T> const& temp1(expr1); \
3118 __gmp_expr<V, V> const& temp2(expr2); \
3119 return eval_fun::eval(temp1.__get_mp(), temp2.__get_mp()); \
3120 }
3121
3122 #define __GMPNN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, \
3123 type2, bigtype) \
3124 \
3125 template <class T, class U> \
3126 inline type fun(const __gmp_expr<T, U> &expr, type2 t) \
3127 { \
3128 __gmp_expr<T, T> const& temp(expr); \
3129 return eval_fun::eval(temp.__get_mp(), static_cast<bigtype>(t)); \
3130 } \
3131 \
3132 template <class T, class U> \
3133 inline type fun(type2 t, const __gmp_expr<T, U> &expr) \
3134 { \
3135 __gmp_expr<T, T> const& temp(expr); \
3136 return eval_fun::eval(static_cast<bigtype>(t), temp.__get_mp()); \
3137 }
3138
3139 #define __GMPNS_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, type2) \
3140 __GMPNN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, \
3141 type2, signed long int)
3142
3143 #define __GMPNU_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, type2) \
3144 __GMPNN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, \
3145 type2, unsigned long int)
3146
3147 #define __GMPND_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, type2) \
3148 __GMPNN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, type2, double)
3149
3150 #define __GMPNLD_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, type2) \
3151 __GMPNN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, type2, long double)
3152
3153 #define __GMPN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun) \
3154 __GMPNS_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, signed char) \
3155 __GMPNU_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, unsigned char) \
3156 __GMPNS_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, signed int) \
3157 __GMPNU_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, unsigned int) \
3158 __GMPNS_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, signed short int) \
3159 __GMPNU_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, unsigned short int) \
3160 __GMPNS_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, signed long int) \
3161 __GMPNU_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, unsigned long int) \
3162 __GMPND_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, float) \
3163 __GMPND_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, double) \
3164
3165
3166 #define __GMP_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun) \
3167 __GMPP_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun) \
3168 __GMPN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun)
3169
3170
3171
3172
3173 #define __GMPP_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun) \
3174 \
3175 template <class T, class U> \
3176 inline type##_class & type##_class::fun(const __gmp_expr<T, U> &expr) \
3177 { \
3178 __gmp_set_expr(mp, __gmp_expr<type##_t, __gmp_binary_expr \
3179 <type##_class, __gmp_expr<T, U>, eval_fun> >(*this, expr)); \
3180 return *this; \
3181 }
3182
3183 #define __GMPNN_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, \
3184 type2, bigtype) \
3185 \
3186 inline type##_class & type##_class::fun(type2 t) \
3187 { \
3188 __gmp_set_expr(mp, __gmp_expr<type##_t, __gmp_binary_expr \
3189 <type##_class, bigtype, eval_fun> >(*this, t)); \
3190 return *this; \
3191 }
3192
3193 #define __GMPNS_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, type2) \
3194 __GMPNN_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, \
3195 type2, signed long int)
3196
3197 #define __GMPNU_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, type2) \
3198 __GMPNN_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, \
3199 type2, unsigned long int)
3200
3201 #define __GMPND_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, type2) \
3202 __GMPNN_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, type2, double)
3203
3204 #define __GMPNLD_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, type2) \
3205 __GMPNN_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, type2, long double)
3206
3207 #define __GMPN_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun) \
3208 __GMPNS_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, signed char) \
3209 __GMPNU_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, unsigned char) \
3210 __GMPNS_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, signed int) \
3211 __GMPNU_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, unsigned int) \
3212 __GMPNS_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, signed short int) \
3213 __GMPNU_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, unsigned short int) \
3214 __GMPNS_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, signed long int) \
3215 __GMPNU_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, unsigned long int) \
3216 __GMPND_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, float) \
3217 __GMPND_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, double) \
3218
3219
3220 #define __GMP_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun) \
3221 __GMPP_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun) \
3222 __GMPN_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun)
3223
3224 #define __GMPZ_DEFINE_COMPOUND_OPERATOR(fun, eval_fun) \
3225 __GMP_DEFINE_COMPOUND_OPERATOR(mpz, fun, eval_fun)
3226
3227 #define __GMPQ_DEFINE_COMPOUND_OPERATOR(fun, eval_fun) \
3228 __GMP_DEFINE_COMPOUND_OPERATOR(mpq, fun, eval_fun)
3229
3230 #define __GMPF_DEFINE_COMPOUND_OPERATOR(fun, eval_fun) \
3231 __GMP_DEFINE_COMPOUND_OPERATOR(mpf, fun, eval_fun)
3232
3233
3234
3235 #define __GMP_DEFINE_COMPOUND_OPERATOR_UI(type, fun, eval_fun) \
3236 \
3237 inline type##_class & type##_class::fun(mp_bitcnt_t l) \
3238 { \
3239 __gmp_set_expr(mp, __gmp_expr<type##_t, __gmp_binary_expr \
3240 <type##_class, mp_bitcnt_t, eval_fun> >(*this, l)); \
3241 return *this; \
3242 }
3243
3244 #define __GMPZ_DEFINE_COMPOUND_OPERATOR_UI(fun, eval_fun) \
3245 __GMP_DEFINE_COMPOUND_OPERATOR_UI(mpz, fun, eval_fun)
3246
3247 #define __GMPQ_DEFINE_COMPOUND_OPERATOR_UI(fun, eval_fun) \
3248 __GMP_DEFINE_COMPOUND_OPERATOR_UI(mpq, fun, eval_fun)
3249
3250 #define __GMPF_DEFINE_COMPOUND_OPERATOR_UI(fun, eval_fun) \
3251 __GMP_DEFINE_COMPOUND_OPERATOR_UI(mpf, fun, eval_fun)
3252
3253
3254
3255 #define __GMP_DEFINE_INCREMENT_OPERATOR(type, fun, eval_fun) \
3256 \
3257 inline type##_class & type##_class::fun() \
3258 { \
3259 eval_fun::eval(mp); \
3260 return *this; \
3261 } \
3262 \
3263 inline type##_class type##_class::fun(int) \
3264 { \
3265 type##_class temp(*this); \
3266 eval_fun::eval(mp); \
3267 return temp; \
3268 }
3269
3270 #define __GMPZ_DEFINE_INCREMENT_OPERATOR(fun, eval_fun) \
3271 __GMP_DEFINE_INCREMENT_OPERATOR(mpz, fun, eval_fun)
3272
3273 #define __GMPQ_DEFINE_INCREMENT_OPERATOR(fun, eval_fun) \
3274 __GMP_DEFINE_INCREMENT_OPERATOR(mpq, fun, eval_fun)
3275
3276 #define __GMPF_DEFINE_INCREMENT_OPERATOR(fun, eval_fun) \
3277 __GMP_DEFINE_INCREMENT_OPERATOR(mpf, fun, eval_fun)
3278
3279
3280 #define __GMPP_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun) \
3281 template <class U> \
3282 __gmp_expr<T, __gmp_unary_expr<__gmp_expr<T, U>, eval_fun> > \
3283 fun(const __gmp_expr<T, U> &expr) \
3284 { \
3285 return __gmp_expr<T, __gmp_unary_expr<__gmp_expr<T, U>, eval_fun> >(expr); \
3286 }
3287
3288 #define __GMPNN_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, type, bigtype) \
3289 inline __gmp_expr<T, __gmp_unary_expr<bigtype, eval_fun> > \
3290 fun(type expr) \
3291 { \
3292 return __gmp_expr<T, __gmp_unary_expr<bigtype, eval_fun> >(expr); \
3293 }
3294
3295 #define __GMPNS_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, type) \
3296 __GMPNN_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, type, signed long)
3297 #define __GMPNU_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, type) \
3298 __GMPNN_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, type, unsigned long)
3299 #define __GMPND_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, type) \
3300 __GMPNN_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, type, double)
3301
3302 #define __GMPN_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun) \
3303 __GMPNS_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, signed char) \
3304 __GMPNU_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, unsigned char) \
3305 __GMPNS_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, signed int) \
3306 __GMPNU_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, unsigned int) \
3307 __GMPNS_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, signed short int) \
3308 __GMPNU_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, unsigned short int) \
3309 __GMPNS_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, signed long int) \
3310 __GMPNU_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, unsigned long int) \
3311 __GMPND_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, float) \
3312 __GMPND_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, double) \
3313
3314 #define __GMP_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun) \
3315 __GMPP_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun) \
3316 __GMPN_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun) \
3317
3318
3319
3320
3321
3322
3323 __GMP_DEFINE_UNARY_FUNCTION(operator+, __gmp_unary_plus)
3324 __GMP_DEFINE_UNARY_FUNCTION(operator-, __gmp_unary_minus)
3325 __GMP_DEFINE_UNARY_FUNCTION_1(mpz_t, operator~, __gmp_unary_com)
3326
3327 __GMP_DEFINE_BINARY_FUNCTION(operator+, __gmp_binary_plus)
3328 __GMP_DEFINE_BINARY_FUNCTION(operator-, __gmp_binary_minus)
3329 __GMP_DEFINE_BINARY_FUNCTION(operator*, __gmp_binary_multiplies)
3330 __GMP_DEFINE_BINARY_FUNCTION(operator/, __gmp_binary_divides)
3331 __GMP_DEFINE_BINARY_FUNCTION_1(mpz_t, operator%, __gmp_binary_modulus)
3332 __GMP_DEFINE_BINARY_FUNCTION_1(mpz_t, operator&, __gmp_binary_and)
3333 __GMP_DEFINE_BINARY_FUNCTION_1(mpz_t, operator|, __gmp_binary_ior)
3334 __GMP_DEFINE_BINARY_FUNCTION_1(mpz_t, operator^, __gmp_binary_xor)
3335
3336 __GMP_DEFINE_BINARY_FUNCTION_UI(operator<<, __gmp_binary_lshift)
3337 __GMP_DEFINE_BINARY_FUNCTION_UI(operator>>, __gmp_binary_rshift)
3338
3339 __GMP_DEFINE_BINARY_TYPE_FUNCTION(bool, operator==, __gmp_binary_equal)
3340 __GMP_DEFINE_BINARY_TYPE_FUNCTION(bool, operator!=, ! __gmp_binary_equal)
3341 __GMP_DEFINE_BINARY_TYPE_FUNCTION(bool, operator<, __gmp_binary_less)
3342 __GMP_DEFINE_BINARY_TYPE_FUNCTION(bool, operator<=, ! __gmp_binary_greater)
3343 __GMP_DEFINE_BINARY_TYPE_FUNCTION(bool, operator>, __gmp_binary_greater)
3344 __GMP_DEFINE_BINARY_TYPE_FUNCTION(bool, operator>=, ! __gmp_binary_less)
3345
3346 __GMP_DEFINE_UNARY_FUNCTION(abs, __gmp_abs_function)
3347 __GMP_DEFINE_UNARY_FUNCTION_1(mpf_t, trunc, __gmp_trunc_function)
3348 __GMP_DEFINE_UNARY_FUNCTION_1(mpf_t, floor, __gmp_floor_function)
3349 __GMP_DEFINE_UNARY_FUNCTION_1(mpf_t, ceil, __gmp_ceil_function)
3350 __GMP_DEFINE_UNARY_FUNCTION_1(mpf_t, sqrt, __gmp_sqrt_function)
3351 __GMP_DEFINE_UNARY_FUNCTION_1(mpz_t, sqrt, __gmp_sqrt_function)
3352 __GMP_DEFINE_UNARY_FUNCTION_1(mpz_t, factorial, __gmp_fac_function)
3353 __GMP_DEFINE_UNARY_FUNCTION_1(mpz_t, primorial, __gmp_primorial_function)
3354 __GMP_DEFINE_UNARY_FUNCTION_1(mpz_t, fibonacci, __gmp_fib_function)
3355 __GMP_DEFINE_BINARY_FUNCTION_1(mpf_t, hypot, __gmp_hypot_function)
3356 __GMP_DEFINE_BINARY_FUNCTION_1(mpz_t, gcd, __gmp_gcd_function)
3357 __GMP_DEFINE_BINARY_FUNCTION_1(mpz_t, lcm, __gmp_lcm_function)
3358
3359 __GMP_DEFINE_UNARY_TYPE_FUNCTION(int, sgn, __gmp_sgn_function)
3360 __GMP_DEFINE_BINARY_TYPE_FUNCTION(int, cmp, __gmp_cmp_function)
3361
3362 template <class T>
3363 void swap(__gmp_expr<T, T>& x, __gmp_expr<T, T>& y) __GMPXX_NOEXCEPT
3364 { x.swap(y); }
3365
3366
3367
3368 __GMPZ_DEFINE_COMPOUND_OPERATOR(operator+=, __gmp_binary_plus)
3369 __GMPZ_DEFINE_COMPOUND_OPERATOR(operator-=, __gmp_binary_minus)
3370 __GMPZ_DEFINE_COMPOUND_OPERATOR(operator*=, __gmp_binary_multiplies)
3371 __GMPZ_DEFINE_COMPOUND_OPERATOR(operator/=, __gmp_binary_divides)
3372 __GMPZ_DEFINE_COMPOUND_OPERATOR(operator%=, __gmp_binary_modulus)
3373
3374 __GMPZ_DEFINE_COMPOUND_OPERATOR(operator&=, __gmp_binary_and)
3375 __GMPZ_DEFINE_COMPOUND_OPERATOR(operator|=, __gmp_binary_ior)
3376 __GMPZ_DEFINE_COMPOUND_OPERATOR(operator^=, __gmp_binary_xor)
3377
3378 __GMPZ_DEFINE_COMPOUND_OPERATOR_UI(operator<<=, __gmp_binary_lshift)
3379 __GMPZ_DEFINE_COMPOUND_OPERATOR_UI(operator>>=, __gmp_binary_rshift)
3380
3381 __GMPZ_DEFINE_INCREMENT_OPERATOR(operator++, __gmp_unary_increment)
3382 __GMPZ_DEFINE_INCREMENT_OPERATOR(operator--, __gmp_unary_decrement)
3383
3384 __GMP_DEFINE_UNARY_STATIC_MEMFUN(mpz_t, mpz_class::factorial, __gmp_fac_function)
3385 __GMP_DEFINE_UNARY_STATIC_MEMFUN(mpz_t, mpz_class::primorial, __gmp_primorial_function)
3386 __GMP_DEFINE_UNARY_STATIC_MEMFUN(mpz_t, mpz_class::fibonacci, __gmp_fib_function)
3387
3388
3389
3390 __GMPQ_DEFINE_COMPOUND_OPERATOR(operator+=, __gmp_binary_plus)
3391 __GMPQ_DEFINE_COMPOUND_OPERATOR(operator-=, __gmp_binary_minus)
3392 __GMPQ_DEFINE_COMPOUND_OPERATOR(operator*=, __gmp_binary_multiplies)
3393 __GMPQ_DEFINE_COMPOUND_OPERATOR(operator/=, __gmp_binary_divides)
3394
3395 __GMPQ_DEFINE_COMPOUND_OPERATOR_UI(operator<<=, __gmp_binary_lshift)
3396 __GMPQ_DEFINE_COMPOUND_OPERATOR_UI(operator>>=, __gmp_binary_rshift)
3397
3398 __GMPQ_DEFINE_INCREMENT_OPERATOR(operator++, __gmp_unary_increment)
3399 __GMPQ_DEFINE_INCREMENT_OPERATOR(operator--, __gmp_unary_decrement)
3400
3401
3402
3403 __GMPF_DEFINE_COMPOUND_OPERATOR(operator+=, __gmp_binary_plus)
3404 __GMPF_DEFINE_COMPOUND_OPERATOR(operator-=, __gmp_binary_minus)
3405 __GMPF_DEFINE_COMPOUND_OPERATOR(operator*=, __gmp_binary_multiplies)
3406 __GMPF_DEFINE_COMPOUND_OPERATOR(operator/=, __gmp_binary_divides)
3407
3408 __GMPF_DEFINE_COMPOUND_OPERATOR_UI(operator<<=, __gmp_binary_lshift)
3409 __GMPF_DEFINE_COMPOUND_OPERATOR_UI(operator>>=, __gmp_binary_rshift)
3410
3411 __GMPF_DEFINE_INCREMENT_OPERATOR(operator++, __gmp_unary_increment)
3412 __GMPF_DEFINE_INCREMENT_OPERATOR(operator--, __gmp_unary_decrement)
3413
3414
3415
3416
3417
3418 class __gmp_urandomb_value { };
3419 class __gmp_urandomm_value { };
3420
3421 template <>
3422 class __gmp_expr<mpz_t, __gmp_urandomb_value>
3423 {
3424 private:
3425 __gmp_randstate_struct *state;
3426 mp_bitcnt_t bits;
3427 public:
3428 __gmp_expr(gmp_randstate_t s, mp_bitcnt_t l) : state(s), bits(l) { }
3429 void eval(mpz_ptr z) const { __gmp_rand_function::eval(z, state, bits); }
3430 mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); }
3431 };
3432
3433 template <>
3434 class __gmp_expr<mpz_t, __gmp_urandomm_value>
3435 {
3436 private:
3437 __gmp_randstate_struct *state;
3438 mpz_class range;
3439 public:
3440 __gmp_expr(gmp_randstate_t s, const mpz_class &z) : state(s), range(z) { }
3441 void eval(mpz_ptr z) const
3442 { __gmp_rand_function::eval(z, state, range.get_mpz_t()); }
3443 mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); }
3444 };
3445
3446 template <>
3447 class __gmp_expr<mpf_t, __gmp_urandomb_value>
3448 {
3449 private:
3450 __gmp_randstate_struct *state;
3451 mp_bitcnt_t bits;
3452 public:
3453 __gmp_expr(gmp_randstate_t s, mp_bitcnt_t l) : state(s), bits(l) { }
3454 void eval(mpf_ptr f) const
3455 {
3456 __gmp_rand_function::eval(f, state,
3457 (bits>0) ? bits : mpf_get_prec(f));
3458 }
3459 mp_bitcnt_t get_prec() const
3460 {
3461 if (bits == 0)
3462 return mpf_get_default_prec();
3463 else
3464 return bits;
3465 }
3466 };
3467
3468 extern "C" {
3469 typedef void __gmp_randinit_default_t (gmp_randstate_t);
3470 typedef void __gmp_randinit_lc_2exp_t (gmp_randstate_t, mpz_srcptr, unsigned long int, mp_bitcnt_t);
3471 typedef int __gmp_randinit_lc_2exp_size_t (gmp_randstate_t, mp_bitcnt_t);
3472 }
3473
3474 class gmp_randclass
3475 {
3476 private:
3477 gmp_randstate_t state;
3478
3479
3480 gmp_randclass(const gmp_randclass &);
3481 void operator=(const gmp_randclass &);
3482 public:
3483
3484 gmp_randclass(gmp_randalg_t alg, unsigned long int size)
3485 {
3486 switch (alg)
3487 {
3488 case GMP_RAND_ALG_LC:
3489 default:
3490 gmp_randinit(state, alg, size);
3491 break;
3492 }
3493 }
3494
3495
3496 gmp_randclass(__gmp_randinit_default_t* f) { f(state); }
3497
3498
3499 gmp_randclass(__gmp_randinit_lc_2exp_t* f,
3500 mpz_class z, unsigned long int l1, mp_bitcnt_t l2)
3501 { f(state, z.get_mpz_t(), l1, l2); }
3502
3503
3504 gmp_randclass(__gmp_randinit_lc_2exp_size_t* f,
3505 mp_bitcnt_t size)
3506 {
3507 if (f (state, size) == 0)
3508 throw std::length_error ("gmp_randinit_lc_2exp_size");
3509 }
3510
3511 ~gmp_randclass() { gmp_randclear(state); }
3512
3513
3514 void seed();
3515 void seed(unsigned long int s) { gmp_randseed_ui(state, s); }
3516 void seed(const mpz_class &z) { gmp_randseed(state, z.get_mpz_t()); }
3517
3518
3519 __gmp_expr<mpz_t, __gmp_urandomb_value> get_z_bits(mp_bitcnt_t l)
3520 { return __gmp_expr<mpz_t, __gmp_urandomb_value>(state, l); }
3521 __gmp_expr<mpz_t, __gmp_urandomb_value> get_z_bits(const mpz_class &z)
3522 { return get_z_bits(z.get_ui()); }
3523
3524
3525 __gmp_expr<mpz_t, __gmp_urandomm_value> get_z_range(const mpz_class &z)
3526 { return __gmp_expr<mpz_t, __gmp_urandomm_value>(state, z); }
3527
3528 __gmp_expr<mpf_t, __gmp_urandomb_value> get_f(mp_bitcnt_t prec = 0)
3529 { return __gmp_expr<mpf_t, __gmp_urandomb_value>(state, prec); }
3530 };
3531
3532
3533
3534
3535 namespace std {
3536 template <> class numeric_limits<mpz_class>
3537 {
3538 public:
3539 static const bool is_specialized = true;
3540 static mpz_class min() { return mpz_class(); }
3541 static mpz_class max() { return mpz_class(); }
3542 static mpz_class lowest() { return mpz_class(); }
3543 static const int digits = 0;
3544 static const int digits10 = 0;
3545 static const int max_digits10 = 0;
3546 static const bool is_signed = true;
3547 static const bool is_integer = true;
3548 static const bool is_exact = true;
3549 static const int radix = 2;
3550 static mpz_class epsilon() { return mpz_class(); }
3551 static mpz_class round_error() { return mpz_class(); }
3552 static const int min_exponent = 0;
3553 static const int min_exponent10 = 0;
3554 static const int max_exponent = 0;
3555 static const int max_exponent10 = 0;
3556 static const bool has_infinity = false;
3557 static const bool has_quiet_NaN = false;
3558 static const bool has_signaling_NaN = false;
3559 static const float_denorm_style has_denorm = denorm_absent;
3560 static const bool has_denorm_loss = false;
3561 static mpz_class infinity() { return mpz_class(); }
3562 static mpz_class quiet_NaN() { return mpz_class(); }
3563 static mpz_class signaling_NaN() { return mpz_class(); }
3564 static mpz_class denorm_min() { return mpz_class(); }
3565 static const bool is_iec559 = false;
3566 static const bool is_bounded = false;
3567 static const bool is_modulo = false;
3568 static const bool traps = false;
3569 static const bool tinyness_before = false;
3570 static const float_round_style round_style = round_toward_zero;
3571 };
3572
3573 template <> class numeric_limits<mpq_class>
3574 {
3575 public:
3576 static const bool is_specialized = true;
3577 static mpq_class min() { return mpq_class(); }
3578 static mpq_class max() { return mpq_class(); }
3579 static mpq_class lowest() { return mpq_class(); }
3580 static const int digits = 0;
3581 static const int digits10 = 0;
3582 static const int max_digits10 = 0;
3583 static const bool is_signed = true;
3584 static const bool is_integer = false;
3585 static const bool is_exact = true;
3586 static const int radix = 2;
3587 static mpq_class epsilon() { return mpq_class(); }
3588 static mpq_class round_error() { return mpq_class(); }
3589 static const int min_exponent = 0;
3590 static const int min_exponent10 = 0;
3591 static const int max_exponent = 0;
3592 static const int max_exponent10 = 0;
3593 static const bool has_infinity = false;
3594 static const bool has_quiet_NaN = false;
3595 static const bool has_signaling_NaN = false;
3596 static const float_denorm_style has_denorm = denorm_absent;
3597 static const bool has_denorm_loss = false;
3598 static mpq_class infinity() { return mpq_class(); }
3599 static mpq_class quiet_NaN() { return mpq_class(); }
3600 static mpq_class signaling_NaN() { return mpq_class(); }
3601 static mpq_class denorm_min() { return mpq_class(); }
3602 static const bool is_iec559 = false;
3603 static const bool is_bounded = false;
3604 static const bool is_modulo = false;
3605 static const bool traps = false;
3606 static const bool tinyness_before = false;
3607 static const float_round_style round_style = round_toward_zero;
3608 };
3609
3610 template <> class numeric_limits<mpf_class>
3611 {
3612 public:
3613 static const bool is_specialized = true;
3614 static mpf_class min() { return mpf_class(); }
3615 static mpf_class max() { return mpf_class(); }
3616 static mpf_class lowest() { return mpf_class(); }
3617 static const int digits = 0;
3618 static const int digits10 = 0;
3619 static const int max_digits10 = 0;
3620 static const bool is_signed = true;
3621 static const bool is_integer = false;
3622 static const bool is_exact = false;
3623 static const int radix = 2;
3624 static mpf_class epsilon() { return mpf_class(); }
3625 static mpf_class round_error() { return mpf_class(); }
3626 static const int min_exponent = 0;
3627 static const int min_exponent10 = 0;
3628 static const int max_exponent = 0;
3629 static const int max_exponent10 = 0;
3630 static const bool has_infinity = false;
3631 static const bool has_quiet_NaN = false;
3632 static const bool has_signaling_NaN = false;
3633 static const float_denorm_style has_denorm = denorm_absent;
3634 static const bool has_denorm_loss = false;
3635 static mpf_class infinity() { return mpf_class(); }
3636 static mpf_class quiet_NaN() { return mpf_class(); }
3637 static mpf_class signaling_NaN() { return mpf_class(); }
3638 static mpf_class denorm_min() { return mpf_class(); }
3639 static const bool is_iec559 = false;
3640 static const bool is_bounded = false;
3641 static const bool is_modulo = false;
3642 static const bool traps = false;
3643 static const bool tinyness_before = false;
3644 static const float_round_style round_style = round_indeterminate;
3645 };
3646 }
3647
3648
3649
3650
3651 #undef __GMPP_DECLARE_COMPOUND_OPERATOR
3652 #undef __GMPN_DECLARE_COMPOUND_OPERATOR
3653 #undef __GMP_DECLARE_COMPOUND_OPERATOR
3654 #undef __GMP_DECLARE_COMPOUND_OPERATOR_UI
3655 #undef __GMP_DECLARE_INCREMENT_OPERATOR
3656 #undef __GMPXX_DEFINE_ARITHMETIC_CONSTRUCTORS
3657 #undef __GMPXX_DEFINE_ARITHMETIC_ASSIGNMENTS
3658
3659 #undef __GMPZQ_DEFINE_EXPR
3660
3661 #undef __GMP_DEFINE_UNARY_FUNCTION_1
3662 #undef __GMP_DEFINE_UNARY_FUNCTION
3663 #undef __GMP_DEFINE_UNARY_TYPE_FUNCTION
3664
3665 #undef __GMPP_DEFINE_BINARY_FUNCTION
3666 #undef __GMPNN_DEFINE_BINARY_FUNCTION
3667 #undef __GMPNS_DEFINE_BINARY_FUNCTION
3668 #undef __GMPNU_DEFINE_BINARY_FUNCTION
3669 #undef __GMPND_DEFINE_BINARY_FUNCTION
3670 #undef __GMPNLD_DEFINE_BINARY_FUNCTION
3671 #undef __GMPN_DEFINE_BINARY_FUNCTION
3672 #undef __GMP_DEFINE_BINARY_FUNCTION
3673
3674 #undef __GMP_DEFINE_BINARY_FUNCTION_UI
3675
3676 #undef __GMPP_DEFINE_BINARY_TYPE_FUNCTION
3677 #undef __GMPNN_DEFINE_BINARY_TYPE_FUNCTION
3678 #undef __GMPNS_DEFINE_BINARY_TYPE_FUNCTION
3679 #undef __GMPNU_DEFINE_BINARY_TYPE_FUNCTION
3680 #undef __GMPND_DEFINE_BINARY_TYPE_FUNCTION
3681 #undef __GMPNLD_DEFINE_BINARY_TYPE_FUNCTION
3682 #undef __GMPN_DEFINE_BINARY_TYPE_FUNCTION
3683 #undef __GMP_DEFINE_BINARY_TYPE_FUNCTION
3684
3685 #undef __GMPZ_DEFINE_COMPOUND_OPERATOR
3686
3687 #undef __GMPP_DEFINE_COMPOUND_OPERATOR
3688 #undef __GMPNN_DEFINE_COMPOUND_OPERATOR
3689 #undef __GMPNS_DEFINE_COMPOUND_OPERATOR
3690 #undef __GMPNU_DEFINE_COMPOUND_OPERATOR
3691 #undef __GMPND_DEFINE_COMPOUND_OPERATOR
3692 #undef __GMPNLD_DEFINE_COMPOUND_OPERATOR
3693 #undef __GMPN_DEFINE_COMPOUND_OPERATOR
3694 #undef __GMP_DEFINE_COMPOUND_OPERATOR
3695
3696 #undef __GMPQ_DEFINE_COMPOUND_OPERATOR
3697 #undef __GMPF_DEFINE_COMPOUND_OPERATOR
3698
3699 #undef __GMP_DEFINE_COMPOUND_OPERATOR_UI
3700 #undef __GMPZ_DEFINE_COMPOUND_OPERATOR_UI
3701 #undef __GMPQ_DEFINE_COMPOUND_OPERATOR_UI
3702 #undef __GMPF_DEFINE_COMPOUND_OPERATOR_UI
3703
3704 #undef __GMP_DEFINE_INCREMENT_OPERATOR
3705 #undef __GMPZ_DEFINE_INCREMENT_OPERATOR
3706 #undef __GMPQ_DEFINE_INCREMENT_OPERATOR
3707 #undef __GMPF_DEFINE_INCREMENT_OPERATOR
3708
3709 #undef __GMPXX_CONSTANT_TRUE
3710 #undef __GMPXX_CONSTANT
3711
3712 #endif