File indexing completed on 2024-05-18 08:30:00
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 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 { *mp = *z.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 { std::swap(*mp, *z.mp); }
1670
1671
1672 __gmp_expr & operator=(const __gmp_expr &z)
1673 { mpz_set(mp, z.mp); return *this; }
1674 #if __GMPXX_USE_CXX11
1675 __gmp_expr & operator=(__gmp_expr &&z) noexcept
1676 { swap(z); return *this; }
1677 #endif
1678 template <class T, class U>
1679 __gmp_expr<value_type, value_type> & operator=(const __gmp_expr<T, U> &expr)
1680 { __gmp_set_expr(mp, expr); return *this; }
1681
1682 __GMPXX_DEFINE_ARITHMETIC_ASSIGNMENTS
1683
1684 __gmp_expr & operator=(const char *s)
1685 {
1686 if (mpz_set_str (mp, s, 0) != 0)
1687 throw std::invalid_argument ("mpz_set_str");
1688 return *this;
1689 }
1690 __gmp_expr & operator=(const std::string &s)
1691 {
1692 if (mpz_set_str(mp, s.c_str(), 0) != 0)
1693 throw std::invalid_argument ("mpz_set_str");
1694 return *this;
1695 }
1696
1697
1698 int set_str(const char *s, int base)
1699 { return mpz_set_str(mp, s, base); }
1700 int set_str(const std::string &s, int base)
1701 { return mpz_set_str(mp, s.c_str(), base); }
1702 std::string get_str(int base = 10) const
1703 {
1704 __gmp_alloc_cstring temp(mpz_get_str(0, base, mp));
1705 return std::string(temp.str);
1706 }
1707
1708
1709 mpz_srcptr __get_mp() const { return mp; }
1710 mpz_ptr __get_mp() { return mp; }
1711 mpz_srcptr get_mpz_t() const { return mp; }
1712 mpz_ptr get_mpz_t() { return mp; }
1713
1714 signed long int get_si() const { return mpz_get_si(mp); }
1715 unsigned long int get_ui() const { return mpz_get_ui(mp); }
1716 double get_d() const { return mpz_get_d(mp); }
1717
1718
1719
1720 bool fits_sint_p() const { return mpz_fits_sint_p(mp); }
1721 bool fits_uint_p() const { return mpz_fits_uint_p(mp); }
1722 bool fits_sshort_p() const { return mpz_fits_sshort_p(mp); }
1723 bool fits_ushort_p() const { return mpz_fits_ushort_p(mp); }
1724 bool fits_slong_p() const { return mpz_fits_slong_p(mp); }
1725 bool fits_ulong_p() const { return mpz_fits_ulong_p(mp); }
1726
1727
1728
1729
1730 #if __GMPXX_USE_CXX11
1731 explicit operator bool() const { return mp->_mp_size != 0; }
1732 #endif
1733
1734
1735 __GMP_DECLARE_COMPOUND_OPERATOR(operator+=)
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
1741 __GMP_DECLARE_COMPOUND_OPERATOR(operator&=)
1742 __GMP_DECLARE_COMPOUND_OPERATOR(operator|=)
1743 __GMP_DECLARE_COMPOUND_OPERATOR(operator^=)
1744
1745 __GMP_DECLARE_COMPOUND_OPERATOR_UI(operator<<=)
1746 __GMP_DECLARE_COMPOUND_OPERATOR_UI(operator>>=)
1747
1748 __GMP_DECLARE_INCREMENT_OPERATOR(operator++)
1749 __GMP_DECLARE_INCREMENT_OPERATOR(operator--)
1750
1751 __GMP_DECLARE_UNARY_STATIC_MEMFUN(mpz_t, factorial, __gmp_fac_function)
1752 __GMP_DECLARE_UNARY_STATIC_MEMFUN(mpz_t, primorial, __gmp_primorial_function)
1753 __GMP_DECLARE_UNARY_STATIC_MEMFUN(mpz_t, fibonacci, __gmp_fib_function)
1754 };
1755
1756 typedef __gmp_expr<mpz_t, mpz_t> mpz_class;
1757
1758
1759
1760
1761 template <>
1762 class __gmp_expr<mpq_t, mpq_t>
1763 {
1764 private:
1765 typedef mpq_t value_type;
1766 value_type mp;
1767
1768
1769 void assign_ui(unsigned long l) { mpq_set_ui(mp, l, 1); }
1770 void assign_si(signed long l)
1771 {
1772 if (__GMPXX_CONSTANT_TRUE(l >= 0))
1773 assign_ui(l);
1774 else
1775 mpq_set_si(mp, l, 1);
1776 }
1777 void assign_d (double d) { mpq_set_d (mp, d); }
1778
1779 void init_ui(unsigned long l) { mpq_init(mp); get_num() = l; }
1780 void init_si(signed long l) { mpq_init(mp); get_num() = l; }
1781 void init_d (double d) { mpq_init(mp); assign_d (d); }
1782
1783 public:
1784 mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); }
1785 void canonicalize() { mpq_canonicalize(mp); }
1786
1787
1788 __gmp_expr() { mpq_init(mp); }
1789
1790 __gmp_expr(const __gmp_expr &q)
1791 {
1792 mpz_init_set(mpq_numref(mp), mpq_numref(q.mp));
1793 mpz_init_set(mpq_denref(mp), mpq_denref(q.mp));
1794 }
1795 #if __GMPXX_USE_CXX11
1796 __gmp_expr(__gmp_expr &&q)
1797 { *mp = *q.mp; mpq_init(q.mp); }
1798 #endif
1799 template <class T>
1800 __gmp_expr(const __gmp_expr<mpz_t, T> &expr)
1801 { mpq_init(mp); __gmp_set_expr(mp, expr); }
1802 template <class T>
1803 __gmp_expr(const __gmp_expr<mpq_t, T> &expr)
1804 { mpq_init(mp); __gmp_set_expr(mp, expr); }
1805 template <class T, class U>
1806 explicit __gmp_expr(const __gmp_expr<T, U> &expr)
1807 { mpq_init(mp); __gmp_set_expr(mp, expr); }
1808
1809 __GMPXX_DEFINE_ARITHMETIC_CONSTRUCTORS
1810
1811 explicit __gmp_expr(const char *s, int base = 0)
1812 {
1813 mpq_init (mp);
1814
1815
1816 if (s == 0)
1817 {
1818
1819 mpz_set_si(mpq_denref(mp), base);
1820 }
1821 else if (mpq_set_str(mp, s, base) != 0)
1822 {
1823 mpq_clear (mp);
1824 throw std::invalid_argument ("mpq_set_str");
1825 }
1826 }
1827 explicit __gmp_expr(const std::string &s, int base = 0)
1828 {
1829 mpq_init(mp);
1830 if (mpq_set_str (mp, s.c_str(), base) != 0)
1831 {
1832 mpq_clear (mp);
1833 throw std::invalid_argument ("mpq_set_str");
1834 }
1835 }
1836 explicit __gmp_expr(mpq_srcptr q)
1837 {
1838 mpz_init_set(mpq_numref(mp), mpq_numref(q));
1839 mpz_init_set(mpq_denref(mp), mpq_denref(q));
1840 }
1841
1842 __gmp_expr(const mpz_class &num, const mpz_class &den)
1843 {
1844 mpz_init_set(mpq_numref(mp), num.get_mpz_t());
1845 mpz_init_set(mpq_denref(mp), den.get_mpz_t());
1846 }
1847
1848 ~__gmp_expr() { mpq_clear(mp); }
1849
1850 void swap(__gmp_expr& q) __GMPXX_NOEXCEPT { std::swap(*mp, *q.mp); }
1851
1852
1853 __gmp_expr & operator=(const __gmp_expr &q)
1854 { mpq_set(mp, q.mp); return *this; }
1855 #if __GMPXX_USE_CXX11
1856 __gmp_expr & operator=(__gmp_expr &&q) noexcept
1857 { swap(q); return *this; }
1858 __gmp_expr & operator=(mpz_class &&z) noexcept
1859 { get_num() = std::move(z); get_den() = 1u; return *this; }
1860 #endif
1861 template <class T, class U>
1862 __gmp_expr<value_type, value_type> & operator=(const __gmp_expr<T, U> &expr)
1863 { __gmp_set_expr(mp, expr); return *this; }
1864
1865 __GMPXX_DEFINE_ARITHMETIC_ASSIGNMENTS
1866
1867 __gmp_expr & operator=(const char *s)
1868 {
1869 if (mpq_set_str (mp, s, 0) != 0)
1870 throw std::invalid_argument ("mpq_set_str");
1871 return *this;
1872 }
1873 __gmp_expr & operator=(const std::string &s)
1874 {
1875 if (mpq_set_str(mp, s.c_str(), 0) != 0)
1876 throw std::invalid_argument ("mpq_set_str");
1877 return *this;
1878 }
1879
1880
1881 int set_str(const char *s, int base)
1882 { return mpq_set_str(mp, s, base); }
1883 int set_str(const std::string &s, int base)
1884 { return mpq_set_str(mp, s.c_str(), base); }
1885 std::string get_str(int base = 10) const
1886 {
1887 __gmp_alloc_cstring temp(mpq_get_str(0, base, mp));
1888 return std::string(temp.str);
1889 }
1890
1891
1892
1893
1894
1895
1896 const mpz_class & get_num() const
1897 { return reinterpret_cast<const mpz_class &>(*mpq_numref(mp)); }
1898 mpz_class & get_num()
1899 { return reinterpret_cast<mpz_class &>(*mpq_numref(mp)); }
1900 const mpz_class & get_den() const
1901 { return reinterpret_cast<const mpz_class &>(*mpq_denref(mp)); }
1902 mpz_class & get_den()
1903 { return reinterpret_cast<mpz_class &>(*mpq_denref(mp)); }
1904
1905 mpq_srcptr __get_mp() const { return mp; }
1906 mpq_ptr __get_mp() { return mp; }
1907 mpq_srcptr get_mpq_t() const { return mp; }
1908 mpq_ptr get_mpq_t() { return mp; }
1909
1910 mpz_srcptr get_num_mpz_t() const { return mpq_numref(mp); }
1911 mpz_ptr get_num_mpz_t() { return mpq_numref(mp); }
1912 mpz_srcptr get_den_mpz_t() const { return mpq_denref(mp); }
1913 mpz_ptr get_den_mpz_t() { return mpq_denref(mp); }
1914
1915 double get_d() const { return mpq_get_d(mp); }
1916
1917 #if __GMPXX_USE_CXX11
1918 explicit operator bool() const { return mpq_numref(mp)->_mp_size != 0; }
1919 #endif
1920
1921
1922 __GMP_DECLARE_COMPOUND_OPERATOR(operator+=)
1923 __GMP_DECLARE_COMPOUND_OPERATOR(operator-=)
1924 __GMP_DECLARE_COMPOUND_OPERATOR(operator*=)
1925 __GMP_DECLARE_COMPOUND_OPERATOR(operator/=)
1926
1927 __GMP_DECLARE_COMPOUND_OPERATOR_UI(operator<<=)
1928 __GMP_DECLARE_COMPOUND_OPERATOR_UI(operator>>=)
1929
1930 __GMP_DECLARE_INCREMENT_OPERATOR(operator++)
1931 __GMP_DECLARE_INCREMENT_OPERATOR(operator--)
1932 };
1933
1934 typedef __gmp_expr<mpq_t, mpq_t> mpq_class;
1935
1936
1937
1938
1939 template <>
1940 class __gmp_expr<mpf_t, mpf_t>
1941 {
1942 private:
1943 typedef mpf_t value_type;
1944 value_type mp;
1945
1946
1947 void assign_ui(unsigned long l) { mpf_set_ui(mp, l); }
1948 void assign_si(signed long l)
1949 {
1950 if (__GMPXX_CONSTANT_TRUE(l >= 0))
1951 assign_ui(l);
1952 else
1953 mpf_set_si(mp, l);
1954 }
1955 void assign_d (double d) { mpf_set_d (mp, d); }
1956
1957 void init_ui(unsigned long l)
1958 {
1959 if (__GMPXX_CONSTANT_TRUE(l == 0))
1960 mpf_init(mp);
1961 else
1962 mpf_init_set_ui(mp, l);
1963 }
1964 void init_si(signed long l)
1965 {
1966 if (__GMPXX_CONSTANT_TRUE(l >= 0))
1967 init_ui(l);
1968 else
1969 mpf_init_set_si(mp, l);
1970 }
1971 void init_d (double d) { mpf_init_set_d (mp, d); }
1972
1973 public:
1974 mp_bitcnt_t get_prec() const { return mpf_get_prec(mp); }
1975
1976 void set_prec(mp_bitcnt_t prec) { mpf_set_prec(mp, prec); }
1977 void set_prec_raw(mp_bitcnt_t prec) { mpf_set_prec_raw(mp, prec); }
1978
1979
1980 __gmp_expr() { mpf_init(mp); }
1981
1982 __gmp_expr(const __gmp_expr &f)
1983 { mpf_init2(mp, f.get_prec()); mpf_set(mp, f.mp); }
1984 #if __GMPXX_USE_CXX11
1985 __gmp_expr(__gmp_expr &&f)
1986 { *mp = *f.mp; mpf_init2(f.mp, get_prec()); }
1987 #endif
1988 __gmp_expr(const __gmp_expr &f, mp_bitcnt_t prec)
1989 { mpf_init2(mp, prec); mpf_set(mp, f.mp); }
1990 template <class T, class U>
1991 __gmp_expr(const __gmp_expr<T, U> &expr)
1992 { mpf_init2(mp, expr.get_prec()); __gmp_set_expr(mp, expr); }
1993 template <class T, class U>
1994 __gmp_expr(const __gmp_expr<T, U> &expr, mp_bitcnt_t prec)
1995 { mpf_init2(mp, prec); __gmp_set_expr(mp, expr); }
1996
1997 __GMPXX_DEFINE_ARITHMETIC_CONSTRUCTORS
1998
1999 __gmp_expr(signed char c, mp_bitcnt_t prec)
2000 { mpf_init2(mp, prec); mpf_set_si(mp, c); }
2001 __gmp_expr(unsigned char c, mp_bitcnt_t prec)
2002 { mpf_init2(mp, prec); mpf_set_ui(mp, c); }
2003
2004 __gmp_expr(signed int i, mp_bitcnt_t prec)
2005 { mpf_init2(mp, prec); mpf_set_si(mp, i); }
2006 __gmp_expr(unsigned int i, mp_bitcnt_t prec)
2007 { mpf_init2(mp, prec); mpf_set_ui(mp, i); }
2008
2009 __gmp_expr(signed short int s, mp_bitcnt_t prec)
2010 { mpf_init2(mp, prec); mpf_set_si(mp, s); }
2011 __gmp_expr(unsigned short int s, mp_bitcnt_t prec)
2012 { mpf_init2(mp, prec); mpf_set_ui(mp, s); }
2013
2014 __gmp_expr(signed long int l, mp_bitcnt_t prec)
2015 { mpf_init2(mp, prec); mpf_set_si(mp, l); }
2016 __gmp_expr(unsigned long int l, mp_bitcnt_t prec)
2017 { mpf_init2(mp, prec); mpf_set_ui(mp, l); }
2018
2019 __gmp_expr(float f, mp_bitcnt_t prec)
2020 { mpf_init2(mp, prec); mpf_set_d(mp, f); }
2021 __gmp_expr(double d, mp_bitcnt_t prec)
2022 { mpf_init2(mp, prec); mpf_set_d(mp, d); }
2023
2024
2025
2026
2027 explicit __gmp_expr(const char *s)
2028 {
2029 if (mpf_init_set_str (mp, s, 0) != 0)
2030 {
2031 mpf_clear (mp);
2032 throw std::invalid_argument ("mpf_set_str");
2033 }
2034 }
2035 __gmp_expr(const char *s, mp_bitcnt_t prec, int base = 0)
2036 {
2037 mpf_init2(mp, prec);
2038 if (mpf_set_str(mp, s, base) != 0)
2039 {
2040 mpf_clear (mp);
2041 throw std::invalid_argument ("mpf_set_str");
2042 }
2043 }
2044 explicit __gmp_expr(const std::string &s)
2045 {
2046 if (mpf_init_set_str(mp, s.c_str(), 0) != 0)
2047 {
2048 mpf_clear (mp);
2049 throw std::invalid_argument ("mpf_set_str");
2050 }
2051 }
2052 __gmp_expr(const std::string &s, mp_bitcnt_t prec, int base = 0)
2053 {
2054 mpf_init2(mp, prec);
2055 if (mpf_set_str(mp, s.c_str(), base) != 0)
2056 {
2057 mpf_clear (mp);
2058 throw std::invalid_argument ("mpf_set_str");
2059 }
2060 }
2061
2062 explicit __gmp_expr(mpf_srcptr f)
2063 { mpf_init2(mp, mpf_get_prec(f)); mpf_set(mp, f); }
2064 __gmp_expr(mpf_srcptr f, mp_bitcnt_t prec)
2065 { mpf_init2(mp, prec); mpf_set(mp, f); }
2066
2067 ~__gmp_expr() { mpf_clear(mp); }
2068
2069 void swap(__gmp_expr& f) __GMPXX_NOEXCEPT { std::swap(*mp, *f.mp); }
2070
2071
2072 __gmp_expr & operator=(const __gmp_expr &f)
2073 { mpf_set(mp, f.mp); return *this; }
2074 #if __GMPXX_USE_CXX11
2075 __gmp_expr & operator=(__gmp_expr &&f) noexcept
2076 { swap(f); return *this; }
2077 #endif
2078 template <class T, class U>
2079 __gmp_expr<value_type, value_type> & operator=(const __gmp_expr<T, U> &expr)
2080 { __gmp_set_expr(mp, expr); return *this; }
2081
2082 __GMPXX_DEFINE_ARITHMETIC_ASSIGNMENTS
2083
2084 __gmp_expr & operator=(const char *s)
2085 {
2086 if (mpf_set_str (mp, s, 0) != 0)
2087 throw std::invalid_argument ("mpf_set_str");
2088 return *this;
2089 }
2090 __gmp_expr & operator=(const std::string &s)
2091 {
2092 if (mpf_set_str(mp, s.c_str(), 0) != 0)
2093 throw std::invalid_argument ("mpf_set_str");
2094 return *this;
2095 }
2096
2097
2098 int set_str(const char *s, int base)
2099 { return mpf_set_str(mp, s, base); }
2100 int set_str(const std::string &s, int base)
2101 { return mpf_set_str(mp, s.c_str(), base); }
2102 std::string get_str(mp_exp_t &expo, int base = 10, size_t size = 0) const
2103 {
2104 __gmp_alloc_cstring temp(mpf_get_str(0, &expo, base, size, mp));
2105 return std::string(temp.str);
2106 }
2107
2108
2109 mpf_srcptr __get_mp() const { return mp; }
2110 mpf_ptr __get_mp() { return mp; }
2111 mpf_srcptr get_mpf_t() const { return mp; }
2112 mpf_ptr get_mpf_t() { return mp; }
2113
2114 signed long int get_si() const { return mpf_get_si(mp); }
2115 unsigned long int get_ui() const { return mpf_get_ui(mp); }
2116 double get_d() const { return mpf_get_d(mp); }
2117
2118
2119
2120 bool fits_sint_p() const { return mpf_fits_sint_p(mp); }
2121 bool fits_uint_p() const { return mpf_fits_uint_p(mp); }
2122 bool fits_sshort_p() const { return mpf_fits_sshort_p(mp); }
2123 bool fits_ushort_p() const { return mpf_fits_ushort_p(mp); }
2124 bool fits_slong_p() const { return mpf_fits_slong_p(mp); }
2125 bool fits_ulong_p() const { return mpf_fits_ulong_p(mp); }
2126
2127
2128
2129
2130 #if __GMPXX_USE_CXX11
2131 explicit operator bool() const { return mpf_sgn(mp) != 0; }
2132 #endif
2133
2134
2135 __GMP_DECLARE_COMPOUND_OPERATOR(operator+=)
2136 __GMP_DECLARE_COMPOUND_OPERATOR(operator-=)
2137 __GMP_DECLARE_COMPOUND_OPERATOR(operator*=)
2138 __GMP_DECLARE_COMPOUND_OPERATOR(operator/=)
2139
2140 __GMP_DECLARE_COMPOUND_OPERATOR_UI(operator<<=)
2141 __GMP_DECLARE_COMPOUND_OPERATOR_UI(operator>>=)
2142
2143 __GMP_DECLARE_INCREMENT_OPERATOR(operator++)
2144 __GMP_DECLARE_INCREMENT_OPERATOR(operator--)
2145 };
2146
2147 typedef __gmp_expr<mpf_t, mpf_t> mpf_class;
2148
2149
2150
2151
2152
2153 #if __GMPXX_USE_CXX11
2154 inline mpz_class operator"" _mpz(const char* s)
2155 {
2156 return mpz_class(s);
2157 }
2158
2159 inline mpq_class operator"" _mpq(const char* s)
2160 {
2161 mpq_class q;
2162 q.get_num() = s;
2163 return q;
2164 }
2165
2166 inline mpf_class operator"" _mpf(const char* s)
2167 {
2168 return mpf_class(s);
2169 }
2170 #endif
2171
2172
2173
2174
2175
2176 template <class T, class U>
2177 inline std::ostream & operator<<
2178 (std::ostream &o, const __gmp_expr<T, U> &expr)
2179 {
2180 __gmp_expr<T, T> const& temp(expr);
2181 return o << temp.__get_mp();
2182 }
2183
2184 template <class T>
2185 inline std::istream & operator>>(std::istream &i, __gmp_expr<T, T> &expr)
2186 {
2187 return i >> expr.__get_mp();
2188 }
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203 inline void __gmp_set_expr(mpz_ptr z, const mpz_class &w)
2204 {
2205 mpz_set(z, w.get_mpz_t());
2206 }
2207
2208 template <class T>
2209 inline void __gmp_set_expr(mpz_ptr z, const __gmp_expr<mpz_t, T> &expr)
2210 {
2211 expr.eval(z);
2212 }
2213
2214 template <class T>
2215 inline void __gmp_set_expr(mpz_ptr z, const __gmp_expr<mpq_t, T> &expr)
2216 {
2217 mpq_class const& temp(expr);
2218 mpz_set_q(z, temp.get_mpq_t());
2219 }
2220
2221 template <class T>
2222 inline void __gmp_set_expr(mpz_ptr z, const __gmp_expr<mpf_t, T> &expr)
2223 {
2224 mpf_class const& temp(expr);
2225 mpz_set_f(z, temp.get_mpf_t());
2226 }
2227
2228 inline void __gmp_set_expr(mpq_ptr q, const mpz_class &z)
2229 {
2230 mpq_set_z(q, z.get_mpz_t());
2231 }
2232
2233 template <class T>
2234 inline void __gmp_set_expr(mpq_ptr q, const __gmp_expr<mpz_t, T> &expr)
2235 {
2236 __gmp_set_expr(mpq_numref(q), expr);
2237 mpz_set_ui(mpq_denref(q), 1);
2238 }
2239
2240 inline void __gmp_set_expr(mpq_ptr q, const mpq_class &r)
2241 {
2242 mpq_set(q, r.get_mpq_t());
2243 }
2244
2245 template <class T>
2246 inline void __gmp_set_expr(mpq_ptr q, const __gmp_expr<mpq_t, T> &expr)
2247 {
2248 expr.eval(q);
2249 }
2250
2251 template <class T>
2252 inline void __gmp_set_expr(mpq_ptr q, const __gmp_expr<mpf_t, T> &expr)
2253 {
2254 mpf_class const& temp(expr);
2255 mpq_set_f(q, temp.get_mpf_t());
2256 }
2257
2258 template <class T>
2259 inline void __gmp_set_expr(mpf_ptr f, const __gmp_expr<mpz_t, T> &expr)
2260 {
2261 mpz_class const& temp(expr);
2262 mpf_set_z(f, temp.get_mpz_t());
2263 }
2264
2265 template <class T>
2266 inline void __gmp_set_expr(mpf_ptr f, const __gmp_expr<mpq_t, T> &expr)
2267 {
2268 mpq_class const& temp(expr);
2269 mpf_set_q(f, temp.get_mpq_t());
2270 }
2271
2272 inline void __gmp_set_expr(mpf_ptr f, const mpf_class &g)
2273 {
2274 mpf_set(f, g.get_mpf_t());
2275 }
2276
2277 template <class T>
2278 inline void __gmp_set_expr(mpf_ptr f, const __gmp_expr<mpf_t, T> &expr)
2279 {
2280 expr.eval(f);
2281 }
2282
2283
2284
2285
2286 template <class T>
2287 class __gmp_temp
2288 {
2289 __gmp_expr<T, T> val;
2290 public:
2291 template<class U, class V>
2292 __gmp_temp(U const& u, V) : val (u) {}
2293 typename __gmp_resolve_expr<T>::srcptr_type
2294 __get_mp() const { return val.__get_mp(); }
2295 };
2296
2297 template <>
2298 class __gmp_temp <mpf_t>
2299 {
2300 mpf_class val;
2301 public:
2302 template<class U>
2303 __gmp_temp(U const& u, mpf_ptr res) : val (u, mpf_get_prec(res)) {}
2304 mpf_srcptr __get_mp() const { return val.__get_mp(); }
2305 };
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326 template <class T, class Op>
2327 class __gmp_expr<T, __gmp_unary_expr<__gmp_expr<T, T>, Op> >
2328 {
2329 private:
2330 typedef __gmp_expr<T, T> val_type;
2331
2332 __gmp_unary_expr<val_type, Op> expr;
2333 public:
2334 explicit __gmp_expr(const val_type &val) : expr(val) { }
2335 void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
2336 { Op::eval(p, expr.val.__get_mp()); }
2337 const val_type & get_val() const { return expr.val; }
2338 mp_bitcnt_t get_prec() const { return expr.val.get_prec(); }
2339 };
2340
2341
2342
2343
2344 template <class T, class U, class Op>
2345 class __gmp_expr<T, __gmp_unary_expr<U, Op> >
2346 {
2347 private:
2348 typedef U val_type;
2349
2350 __gmp_unary_expr<val_type, Op> expr;
2351 public:
2352 explicit __gmp_expr(const val_type &val) : expr(val) { }
2353 void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
2354 { Op::eval(p, expr.val); }
2355 const val_type & get_val() const { return expr.val; }
2356 mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); }
2357 };
2358
2359
2360
2361
2362 template <class T, class U, class Op>
2363 class __gmp_expr<T, __gmp_unary_expr<__gmp_expr<T, U>, Op> >
2364 {
2365 private:
2366 typedef __gmp_expr<T, U> val_type;
2367
2368 __gmp_unary_expr<val_type, Op> expr;
2369 public:
2370 explicit __gmp_expr(const val_type &val) : expr(val) { }
2371 void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
2372 { expr.val.eval(p); Op::eval(p, p); }
2373 const val_type & get_val() const { return expr.val; }
2374 mp_bitcnt_t get_prec() const { return expr.val.get_prec(); }
2375 };
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390 template <class T, class Op>
2391 class __gmp_expr
2392 <T, __gmp_binary_expr<__gmp_expr<T, T>, __gmp_expr<T, T>, Op> >
2393 {
2394 private:
2395 typedef __gmp_expr<T, T> val1_type;
2396 typedef __gmp_expr<T, T> val2_type;
2397
2398 __gmp_binary_expr<val1_type, val2_type, Op> expr;
2399 public:
2400 __gmp_expr(const val1_type &val1, const val2_type &val2)
2401 : expr(val1, val2) { }
2402 void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
2403 { Op::eval(p, expr.val1.__get_mp(), expr.val2.__get_mp()); }
2404 const val1_type & get_val1() const { return expr.val1; }
2405 const val2_type & get_val2() const { return expr.val2; }
2406 mp_bitcnt_t get_prec() const
2407 {
2408 mp_bitcnt_t prec1 = expr.val1.get_prec(),
2409 prec2 = expr.val2.get_prec();
2410 return (prec1 > prec2) ? prec1 : prec2;
2411 }
2412 };
2413
2414
2415
2416
2417 template <class T, class U, class Op>
2418 class __gmp_expr<T, __gmp_binary_expr<__gmp_expr<T, T>, U, Op> >
2419 {
2420 private:
2421 typedef __gmp_expr<T, T> val1_type;
2422 typedef U val2_type;
2423
2424 __gmp_binary_expr<val1_type, val2_type, Op> expr;
2425 public:
2426 __gmp_expr(const val1_type &val1, const val2_type &val2)
2427 : expr(val1, val2) { }
2428 void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
2429 { Op::eval(p, expr.val1.__get_mp(), expr.val2); }
2430 const val1_type & get_val1() const { return expr.val1; }
2431 const val2_type & get_val2() const { return expr.val2; }
2432 mp_bitcnt_t get_prec() const { return expr.val1.get_prec(); }
2433 };
2434
2435 template <class T, class U, class Op>
2436 class __gmp_expr<T, __gmp_binary_expr<U, __gmp_expr<T, T>, Op> >
2437 {
2438 private:
2439 typedef U val1_type;
2440 typedef __gmp_expr<T, T> val2_type;
2441
2442 __gmp_binary_expr<val1_type, val2_type, Op> expr;
2443 public:
2444 __gmp_expr(const val1_type &val1, const val2_type &val2)
2445 : expr(val1, val2) { }
2446 void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
2447 { Op::eval(p, expr.val1, expr.val2.__get_mp()); }
2448 const val1_type & get_val1() const { return expr.val1; }
2449 const val2_type & get_val2() const { return expr.val2; }
2450 mp_bitcnt_t get_prec() const { return expr.val2.get_prec(); }
2451 };
2452
2453
2454
2455
2456 template <class T, class U, class V, class Op>
2457 class __gmp_expr
2458 <T, __gmp_binary_expr<__gmp_expr<T, T>, __gmp_expr<U, V>, Op> >
2459 {
2460 private:
2461 typedef __gmp_expr<T, T> val1_type;
2462 typedef __gmp_expr<U, V> val2_type;
2463
2464 __gmp_binary_expr<val1_type, val2_type, Op> expr;
2465 public:
2466 __gmp_expr(const val1_type &val1, const val2_type &val2)
2467 : expr(val1, val2) { }
2468 void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
2469 {
2470 if(p != expr.val1.__get_mp())
2471 {
2472 __gmp_set_expr(p, expr.val2);
2473 Op::eval(p, expr.val1.__get_mp(), p);
2474 }
2475 else
2476 {
2477 __gmp_temp<T> temp(expr.val2, p);
2478 Op::eval(p, expr.val1.__get_mp(), temp.__get_mp());
2479 }
2480 }
2481 const val1_type & get_val1() const { return expr.val1; }
2482 const val2_type & get_val2() const { return expr.val2; }
2483 mp_bitcnt_t get_prec() const
2484 {
2485 mp_bitcnt_t prec1 = expr.val1.get_prec(),
2486 prec2 = expr.val2.get_prec();
2487 return (prec1 > prec2) ? prec1 : prec2;
2488 }
2489 };
2490
2491 template <class T, class U, class V, class Op>
2492 class __gmp_expr
2493 <T, __gmp_binary_expr<__gmp_expr<U, V>, __gmp_expr<T, T>, Op> >
2494 {
2495 private:
2496 typedef __gmp_expr<U, V> val1_type;
2497 typedef __gmp_expr<T, T> val2_type;
2498
2499 __gmp_binary_expr<val1_type, val2_type, Op> expr;
2500 public:
2501 __gmp_expr(const val1_type &val1, const val2_type &val2)
2502 : expr(val1, val2) { }
2503 void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
2504 {
2505 if(p != expr.val2.__get_mp())
2506 {
2507 __gmp_set_expr(p, expr.val1);
2508 Op::eval(p, p, expr.val2.__get_mp());
2509 }
2510 else
2511 {
2512 __gmp_temp<T> temp(expr.val1, p);
2513 Op::eval(p, temp.__get_mp(), expr.val2.__get_mp());
2514 }
2515 }
2516 const val1_type & get_val1() const { return expr.val1; }
2517 const val2_type & get_val2() const { return expr.val2; }
2518 mp_bitcnt_t get_prec() const
2519 {
2520 mp_bitcnt_t prec1 = expr.val1.get_prec(),
2521 prec2 = expr.val2.get_prec();
2522 return (prec1 > prec2) ? prec1 : prec2;
2523 }
2524 };
2525
2526 template <class T, class U, class Op>
2527 class __gmp_expr
2528 <T, __gmp_binary_expr<__gmp_expr<T, T>, __gmp_expr<T, U>, Op> >
2529 {
2530 private:
2531 typedef __gmp_expr<T, T> val1_type;
2532 typedef __gmp_expr<T, U> val2_type;
2533
2534 __gmp_binary_expr<val1_type, val2_type, Op> expr;
2535 public:
2536 __gmp_expr(const val1_type &val1, const val2_type &val2)
2537 : expr(val1, val2) { }
2538 void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
2539 {
2540 if(p != expr.val1.__get_mp())
2541 {
2542 __gmp_set_expr(p, expr.val2);
2543 Op::eval(p, expr.val1.__get_mp(), p);
2544 }
2545 else
2546 {
2547 __gmp_temp<T> temp(expr.val2, p);
2548 Op::eval(p, expr.val1.__get_mp(), temp.__get_mp());
2549 }
2550 }
2551 const val1_type & get_val1() const { return expr.val1; }
2552 const val2_type & get_val2() const { return expr.val2; }
2553 mp_bitcnt_t get_prec() const
2554 {
2555 mp_bitcnt_t prec1 = expr.val1.get_prec(),
2556 prec2 = expr.val2.get_prec();
2557 return (prec1 > prec2) ? prec1 : prec2;
2558 }
2559 };
2560
2561 template <class T, class U, class Op>
2562 class __gmp_expr
2563 <T, __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<T, T>, Op> >
2564 {
2565 private:
2566 typedef __gmp_expr<T, U> val1_type;
2567 typedef __gmp_expr<T, T> val2_type;
2568
2569 __gmp_binary_expr<val1_type, val2_type, Op> expr;
2570 public:
2571 __gmp_expr(const val1_type &val1, const val2_type &val2)
2572 : expr(val1, val2) { }
2573 void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
2574 {
2575 if(p != expr.val2.__get_mp())
2576 {
2577 __gmp_set_expr(p, expr.val1);
2578 Op::eval(p, p, expr.val2.__get_mp());
2579 }
2580 else
2581 {
2582 __gmp_temp<T> temp(expr.val1, p);
2583 Op::eval(p, temp.__get_mp(), expr.val2.__get_mp());
2584 }
2585 }
2586 const val1_type & get_val1() const { return expr.val1; }
2587 const val2_type & get_val2() const { return expr.val2; }
2588 mp_bitcnt_t get_prec() const
2589 {
2590 mp_bitcnt_t prec1 = expr.val1.get_prec(),
2591 prec2 = expr.val2.get_prec();
2592 return (prec1 > prec2) ? prec1 : prec2;
2593 }
2594 };
2595
2596
2597
2598
2599 template <class T, class U, class V, class Op>
2600 class __gmp_expr<T, __gmp_binary_expr<__gmp_expr<T, U>, V, Op> >
2601 {
2602 private:
2603 typedef __gmp_expr<T, U> val1_type;
2604 typedef V val2_type;
2605
2606 __gmp_binary_expr<val1_type, val2_type, Op> expr;
2607 public:
2608 __gmp_expr(const val1_type &val1, const val2_type &val2)
2609 : expr(val1, val2) { }
2610 void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
2611 {
2612 expr.val1.eval(p);
2613 Op::eval(p, p, expr.val2);
2614 }
2615 const val1_type & get_val1() const { return expr.val1; }
2616 const val2_type & get_val2() const { return expr.val2; }
2617 mp_bitcnt_t get_prec() const { return expr.val1.get_prec(); }
2618 };
2619
2620 template <class T, class U, class V, class Op>
2621 class __gmp_expr<T, __gmp_binary_expr<U, __gmp_expr<T, V>, Op> >
2622 {
2623 private:
2624 typedef U val1_type;
2625 typedef __gmp_expr<T, V> val2_type;
2626
2627 __gmp_binary_expr<val1_type, val2_type, Op> expr;
2628 public:
2629 __gmp_expr(const val1_type &val1, const val2_type &val2)
2630 : expr(val1, val2) { }
2631 void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
2632 {
2633 expr.val2.eval(p);
2634 Op::eval(p, expr.val1, p);
2635 }
2636 const val1_type & get_val1() const { return expr.val1; }
2637 const val2_type & get_val2() const { return expr.val2; }
2638 mp_bitcnt_t get_prec() const { return expr.val2.get_prec(); }
2639 };
2640
2641
2642
2643
2644 template <class T, class U, class V, class W, class Op>
2645 class __gmp_expr
2646 <T, __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<V, W>, Op> >
2647 {
2648 private:
2649 typedef __gmp_expr<T, U> val1_type;
2650 typedef __gmp_expr<V, W> val2_type;
2651
2652 __gmp_binary_expr<val1_type, val2_type, Op> expr;
2653 public:
2654 __gmp_expr(const val1_type &val1, const val2_type &val2)
2655 : expr(val1, val2) { }
2656 void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
2657 {
2658 __gmp_temp<T> temp2(expr.val2, p);
2659 expr.val1.eval(p);
2660 Op::eval(p, p, temp2.__get_mp());
2661 }
2662 const val1_type & get_val1() const { return expr.val1; }
2663 const val2_type & get_val2() const { return expr.val2; }
2664 mp_bitcnt_t get_prec() const
2665 {
2666 mp_bitcnt_t prec1 = expr.val1.get_prec(),
2667 prec2 = expr.val2.get_prec();
2668 return (prec1 > prec2) ? prec1 : prec2;
2669 }
2670 };
2671
2672 template <class T, class U, class V, class W, class Op>
2673 class __gmp_expr
2674 <T, __gmp_binary_expr<__gmp_expr<U, V>, __gmp_expr<T, W>, Op> >
2675 {
2676 private:
2677 typedef __gmp_expr<U, V> val1_type;
2678 typedef __gmp_expr<T, W> val2_type;
2679
2680 __gmp_binary_expr<val1_type, val2_type, Op> expr;
2681 public:
2682 __gmp_expr(const val1_type &val1, const val2_type &val2)
2683 : expr(val1, val2) { }
2684 void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
2685 {
2686 __gmp_temp<T> temp1(expr.val1, p);
2687 expr.val2.eval(p);
2688 Op::eval(p, temp1.__get_mp(), p);
2689 }
2690 const val1_type & get_val1() const { return expr.val1; }
2691 const val2_type & get_val2() const { return expr.val2; }
2692 mp_bitcnt_t get_prec() const
2693 {
2694 mp_bitcnt_t prec1 = expr.val1.get_prec(),
2695 prec2 = expr.val2.get_prec();
2696 return (prec1 > prec2) ? prec1 : prec2;
2697 }
2698 };
2699
2700 template <class T, class U, class V, class Op>
2701 class __gmp_expr
2702 <T, __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<T, V>, Op> >
2703 {
2704 private:
2705 typedef __gmp_expr<T, U> val1_type;
2706 typedef __gmp_expr<T, V> val2_type;
2707
2708 __gmp_binary_expr<val1_type, val2_type, Op> expr;
2709 public:
2710 __gmp_expr(const val1_type &val1, const val2_type &val2)
2711 : expr(val1, val2) { }
2712 void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
2713 {
2714 __gmp_temp<T> temp2(expr.val2, p);
2715 expr.val1.eval(p);
2716 Op::eval(p, p, temp2.__get_mp());
2717 }
2718 const val1_type & get_val1() const { return expr.val1; }
2719 const val2_type & get_val2() const { return expr.val2; }
2720 mp_bitcnt_t get_prec() const
2721 {
2722 mp_bitcnt_t prec1 = expr.val1.get_prec(),
2723 prec2 = expr.val2.get_prec();
2724 return (prec1 > prec2) ? prec1 : prec2;
2725 }
2726 };
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736 #define __GMPZQ_DEFINE_EXPR(eval_fun) \
2737 \
2738 template <> \
2739 class __gmp_expr<mpq_t, __gmp_binary_expr<mpz_class, mpq_class, eval_fun> > \
2740 { \
2741 private: \
2742 typedef mpz_class val1_type; \
2743 typedef mpq_class val2_type; \
2744 \
2745 __gmp_binary_expr<val1_type, val2_type, eval_fun> expr; \
2746 public: \
2747 __gmp_expr(const val1_type &val1, const val2_type &val2) \
2748 : expr(val1, val2) { } \
2749 void eval(mpq_ptr q) const \
2750 { eval_fun::eval(q, expr.val1.get_mpz_t(), expr.val2.get_mpq_t()); } \
2751 const val1_type & get_val1() const { return expr.val1; } \
2752 const val2_type & get_val2() const { return expr.val2; } \
2753 mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); } \
2754 }; \
2755 \
2756 template <> \
2757 class __gmp_expr<mpq_t, __gmp_binary_expr<mpq_class, mpz_class, eval_fun> > \
2758 { \
2759 private: \
2760 typedef mpq_class val1_type; \
2761 typedef mpz_class val2_type; \
2762 \
2763 __gmp_binary_expr<val1_type, val2_type, eval_fun> expr; \
2764 public: \
2765 __gmp_expr(const val1_type &val1, const val2_type &val2) \
2766 : expr(val1, val2) { } \
2767 void eval(mpq_ptr q) const \
2768 { eval_fun::eval(q, expr.val1.get_mpq_t(), expr.val2.get_mpz_t()); } \
2769 const val1_type & get_val1() const { return expr.val1; } \
2770 const val2_type & get_val2() const { return expr.val2; } \
2771 mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); } \
2772 }; \
2773 \
2774 template <class T> \
2775 class __gmp_expr \
2776 <mpq_t, __gmp_binary_expr<mpz_class, __gmp_expr<mpq_t, T>, eval_fun> > \
2777 { \
2778 private: \
2779 typedef mpz_class val1_type; \
2780 typedef __gmp_expr<mpq_t, T> val2_type; \
2781 \
2782 __gmp_binary_expr<val1_type, val2_type, eval_fun> expr; \
2783 public: \
2784 __gmp_expr(const val1_type &val1, const val2_type &val2) \
2785 : expr(val1, val2) { } \
2786 void eval(mpq_ptr q) const \
2787 { \
2788 mpq_class temp(expr.val2); \
2789 eval_fun::eval(q, expr.val1.get_mpz_t(), temp.get_mpq_t()); \
2790 } \
2791 const val1_type & get_val1() const { return expr.val1; } \
2792 const val2_type & get_val2() const { return expr.val2; } \
2793 mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); } \
2794 }; \
2795 \
2796 template <class T> \
2797 class __gmp_expr \
2798 <mpq_t, __gmp_binary_expr<mpq_class, __gmp_expr<mpz_t, T>, eval_fun> > \
2799 { \
2800 private: \
2801 typedef mpq_class val1_type; \
2802 typedef __gmp_expr<mpz_t, T> val2_type; \
2803 \
2804 __gmp_binary_expr<val1_type, val2_type, eval_fun> expr; \
2805 public: \
2806 __gmp_expr(const val1_type &val1, const val2_type &val2) \
2807 : expr(val1, val2) { } \
2808 void eval(mpq_ptr q) const \
2809 { \
2810 mpz_class temp(expr.val2); \
2811 eval_fun::eval(q, expr.val1.get_mpq_t(), temp.get_mpz_t()); \
2812 } \
2813 const val1_type & get_val1() const { return expr.val1; } \
2814 const val2_type & get_val2() const { return expr.val2; } \
2815 mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); } \
2816 }; \
2817 \
2818 template <class T> \
2819 class __gmp_expr \
2820 <mpq_t, __gmp_binary_expr<__gmp_expr<mpz_t, T>, mpq_class, eval_fun> > \
2821 { \
2822 private: \
2823 typedef __gmp_expr<mpz_t, T> val1_type; \
2824 typedef mpq_class val2_type; \
2825 \
2826 __gmp_binary_expr<val1_type, val2_type, eval_fun> expr; \
2827 public: \
2828 __gmp_expr(const val1_type &val1, const val2_type &val2) \
2829 : expr(val1, val2) { } \
2830 void eval(mpq_ptr q) const \
2831 { \
2832 mpz_class temp(expr.val1); \
2833 eval_fun::eval(q, temp.get_mpz_t(), expr.val2.get_mpq_t()); \
2834 } \
2835 const val1_type & get_val1() const { return expr.val1; } \
2836 const val2_type & get_val2() const { return expr.val2; } \
2837 mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); } \
2838 }; \
2839 \
2840 template <class T> \
2841 class __gmp_expr \
2842 <mpq_t, __gmp_binary_expr<__gmp_expr<mpq_t, T>, mpz_class, eval_fun> > \
2843 { \
2844 private: \
2845 typedef __gmp_expr<mpq_t, T> val1_type; \
2846 typedef mpz_class val2_type; \
2847 \
2848 __gmp_binary_expr<val1_type, val2_type, eval_fun> expr; \
2849 public: \
2850 __gmp_expr(const val1_type &val1, const val2_type &val2) \
2851 : expr(val1, val2) { } \
2852 void eval(mpq_ptr q) const \
2853 { \
2854 mpq_class temp(expr.val1); \
2855 eval_fun::eval(q, temp.get_mpq_t(), expr.val2.get_mpz_t()); \
2856 } \
2857 const val1_type & get_val1() const { return expr.val1; } \
2858 const val2_type & get_val2() const { return expr.val2; } \
2859 mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); } \
2860 }; \
2861 \
2862 template <class T, class U> \
2863 class __gmp_expr<mpq_t, __gmp_binary_expr \
2864 <__gmp_expr<mpz_t, T>, __gmp_expr<mpq_t, U>, eval_fun> > \
2865 { \
2866 private: \
2867 typedef __gmp_expr<mpz_t, T> val1_type; \
2868 typedef __gmp_expr<mpq_t, U> val2_type; \
2869 \
2870 __gmp_binary_expr<val1_type, val2_type, eval_fun> expr; \
2871 public: \
2872 __gmp_expr(const val1_type &val1, const val2_type &val2) \
2873 : expr(val1, val2) { } \
2874 void eval(mpq_ptr q) const \
2875 { \
2876 mpz_class temp1(expr.val1); \
2877 expr.val2.eval(q); \
2878 eval_fun::eval(q, temp1.get_mpz_t(), q); \
2879 } \
2880 const val1_type & get_val1() const { return expr.val1; } \
2881 const val2_type & get_val2() const { return expr.val2; } \
2882 mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); } \
2883 }; \
2884 \
2885 template <class T, class U> \
2886 class __gmp_expr<mpq_t, __gmp_binary_expr \
2887 <__gmp_expr<mpq_t, T>, __gmp_expr<mpz_t, U>, eval_fun> > \
2888 { \
2889 private: \
2890 typedef __gmp_expr<mpq_t, T> val1_type; \
2891 typedef __gmp_expr<mpz_t, U> val2_type; \
2892 \
2893 __gmp_binary_expr<val1_type, val2_type, eval_fun> expr; \
2894 public: \
2895 __gmp_expr(const val1_type &val1, const val2_type &val2) \
2896 : expr(val1, val2) { } \
2897 void eval(mpq_ptr q) const \
2898 { \
2899 mpz_class temp2(expr.val2); \
2900 expr.val1.eval(q); \
2901 eval_fun::eval(q, q, temp2.get_mpz_t()); \
2902 } \
2903 const val1_type & get_val1() const { return expr.val1; } \
2904 const val2_type & get_val2() const { return expr.val2; } \
2905 mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); } \
2906 };
2907
2908
2909 __GMPZQ_DEFINE_EXPR(__gmp_binary_plus)
2910 __GMPZQ_DEFINE_EXPR(__gmp_binary_minus)
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933 #define __GMP_DEFINE_UNARY_FUNCTION(fun, eval_fun) \
2934 \
2935 template <class T, class U> \
2936 inline __gmp_expr<T, __gmp_unary_expr<__gmp_expr<T, U>, eval_fun> > \
2937 fun(const __gmp_expr<T, U> &expr) \
2938 { \
2939 return __gmp_expr<T, __gmp_unary_expr<__gmp_expr<T, U>, eval_fun> >(expr); \
2940 }
2941
2942
2943
2944 #define __GMP_DEFINE_UNARY_FUNCTION_1(T, fun, eval_fun) \
2945 \
2946 template <class U> \
2947 inline __gmp_expr<T, __gmp_unary_expr<__gmp_expr<T, U>, eval_fun> > \
2948 fun(const __gmp_expr<T, U> &expr) \
2949 { \
2950 return __gmp_expr<T, __gmp_unary_expr<__gmp_expr<T, U>, eval_fun> >(expr); \
2951 }
2952
2953 #define __GMP_DEFINE_UNARY_TYPE_FUNCTION(type, fun, eval_fun) \
2954 \
2955 template <class T, class U> \
2956 inline type fun(const __gmp_expr<T, U> &expr) \
2957 { \
2958 __gmp_expr<T, T> const& temp(expr); \
2959 return eval_fun::eval(temp.__get_mp()); \
2960 }
2961
2962
2963
2964
2965 #define __GMPP_DEFINE_BINARY_FUNCTION(fun, eval_fun) \
2966 \
2967 template <class T, class U, class V, class W> \
2968 inline __gmp_expr<typename __gmp_resolve_expr<T, V>::value_type, \
2969 __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<V, W>, eval_fun> > \
2970 fun(const __gmp_expr<T, U> &expr1, const __gmp_expr<V, W> &expr2) \
2971 { \
2972 return __gmp_expr<typename __gmp_resolve_expr<T, V>::value_type, \
2973 __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<V, W>, eval_fun> > \
2974 (expr1, expr2); \
2975 }
2976
2977 #define __GMPNN_DEFINE_BINARY_FUNCTION(fun, eval_fun, type, bigtype) \
2978 \
2979 template <class T, class U> \
2980 inline __gmp_expr \
2981 <T, __gmp_binary_expr<__gmp_expr<T, U>, bigtype, eval_fun> > \
2982 fun(const __gmp_expr<T, U> &expr, type t) \
2983 { \
2984 return __gmp_expr \
2985 <T, __gmp_binary_expr<__gmp_expr<T, U>, bigtype, eval_fun> >(expr, t); \
2986 } \
2987 \
2988 template <class T, class U> \
2989 inline __gmp_expr \
2990 <T, __gmp_binary_expr<bigtype, __gmp_expr<T, U>, eval_fun> > \
2991 fun(type t, const __gmp_expr<T, U> &expr) \
2992 { \
2993 return __gmp_expr \
2994 <T, __gmp_binary_expr<bigtype, __gmp_expr<T, U>, eval_fun> >(t, expr); \
2995 }
2996
2997 #define __GMPNS_DEFINE_BINARY_FUNCTION(fun, eval_fun, type) \
2998 __GMPNN_DEFINE_BINARY_FUNCTION(fun, eval_fun, type, signed long int)
2999
3000 #define __GMPNU_DEFINE_BINARY_FUNCTION(fun, eval_fun, type) \
3001 __GMPNN_DEFINE_BINARY_FUNCTION(fun, eval_fun, type, unsigned long int)
3002
3003 #define __GMPND_DEFINE_BINARY_FUNCTION(fun, eval_fun, type) \
3004 __GMPNN_DEFINE_BINARY_FUNCTION(fun, eval_fun, type, double)
3005
3006 #define __GMPNLD_DEFINE_BINARY_FUNCTION(fun, eval_fun, type) \
3007 __GMPNN_DEFINE_BINARY_FUNCTION(fun, eval_fun, type, long double)
3008
3009 #define __GMPN_DEFINE_BINARY_FUNCTION(fun, eval_fun) \
3010 __GMPNS_DEFINE_BINARY_FUNCTION(fun, eval_fun, signed char) \
3011 __GMPNU_DEFINE_BINARY_FUNCTION(fun, eval_fun, unsigned char) \
3012 __GMPNS_DEFINE_BINARY_FUNCTION(fun, eval_fun, signed int) \
3013 __GMPNU_DEFINE_BINARY_FUNCTION(fun, eval_fun, unsigned int) \
3014 __GMPNS_DEFINE_BINARY_FUNCTION(fun, eval_fun, signed short int) \
3015 __GMPNU_DEFINE_BINARY_FUNCTION(fun, eval_fun, unsigned short int) \
3016 __GMPNS_DEFINE_BINARY_FUNCTION(fun, eval_fun, signed long int) \
3017 __GMPNU_DEFINE_BINARY_FUNCTION(fun, eval_fun, unsigned long int) \
3018 __GMPND_DEFINE_BINARY_FUNCTION(fun, eval_fun, float) \
3019 __GMPND_DEFINE_BINARY_FUNCTION(fun, eval_fun, double) \
3020
3021
3022 #define __GMP_DEFINE_BINARY_FUNCTION(fun, eval_fun) \
3023 __GMPP_DEFINE_BINARY_FUNCTION(fun, eval_fun) \
3024 __GMPN_DEFINE_BINARY_FUNCTION(fun, eval_fun)
3025
3026
3027
3028 #define __GMPP_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun) \
3029 \
3030 template <class U, class W> \
3031 inline __gmp_expr<T, \
3032 __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<T, W>, eval_fun> > \
3033 fun(const __gmp_expr<T, U> &expr1, const __gmp_expr<T, W> &expr2) \
3034 { \
3035 return __gmp_expr<T, \
3036 __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<T, W>, eval_fun> > \
3037 (expr1, expr2); \
3038 }
3039
3040 #define __GMPNN_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, type, bigtype) \
3041 \
3042 template <class U> \
3043 inline __gmp_expr \
3044 <T, __gmp_binary_expr<__gmp_expr<T, U>, bigtype, eval_fun> > \
3045 fun(const __gmp_expr<T, U> &expr, type t) \
3046 { \
3047 return __gmp_expr \
3048 <T, __gmp_binary_expr<__gmp_expr<T, U>, bigtype, eval_fun> >(expr, t); \
3049 } \
3050 \
3051 template <class U> \
3052 inline __gmp_expr \
3053 <T, __gmp_binary_expr<bigtype, __gmp_expr<T, U>, eval_fun> > \
3054 fun(type t, const __gmp_expr<T, U> &expr) \
3055 { \
3056 return __gmp_expr \
3057 <T, __gmp_binary_expr<bigtype, __gmp_expr<T, U>, eval_fun> >(t, expr); \
3058 }
3059
3060 #define __GMPNS_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, type) \
3061 __GMPNN_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, type, signed long int)
3062
3063 #define __GMPNU_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, type) \
3064 __GMPNN_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, type, unsigned long int)
3065
3066 #define __GMPND_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, type) \
3067 __GMPNN_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, type, double)
3068
3069 #define __GMPNLD_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, type) \
3070 __GMPNN_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, type, long double)
3071
3072 #define __GMPN_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun) \
3073 __GMPNS_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, signed char) \
3074 __GMPNU_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, unsigned char) \
3075 __GMPNS_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, signed int) \
3076 __GMPNU_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, unsigned int) \
3077 __GMPNS_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, signed short int) \
3078 __GMPNU_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, unsigned short int) \
3079 __GMPNS_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, signed long int) \
3080 __GMPNU_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, unsigned long int) \
3081 __GMPND_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, float) \
3082 __GMPND_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, double) \
3083
3084
3085 #define __GMP_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun) \
3086 __GMPP_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun) \
3087 __GMPN_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun)
3088
3089
3090 #define __GMP_DEFINE_BINARY_FUNCTION_UI(fun, eval_fun) \
3091 \
3092 template <class T, class U> \
3093 inline __gmp_expr \
3094 <T, __gmp_binary_expr<__gmp_expr<T, U>, mp_bitcnt_t, eval_fun> > \
3095 fun(const __gmp_expr<T, U> &expr, mp_bitcnt_t l) \
3096 { \
3097 return __gmp_expr<T, __gmp_binary_expr \
3098 <__gmp_expr<T, U>, mp_bitcnt_t, eval_fun> >(expr, l); \
3099 }
3100
3101
3102 #define __GMPP_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun) \
3103 \
3104 template <class T, class U, class V, class W> \
3105 inline type fun(const __gmp_expr<T, U> &expr1, \
3106 const __gmp_expr<V, W> &expr2) \
3107 { \
3108 __gmp_expr<T, T> const& temp1(expr1); \
3109 __gmp_expr<V, V> const& temp2(expr2); \
3110 return eval_fun::eval(temp1.__get_mp(), temp2.__get_mp()); \
3111 }
3112
3113 #define __GMPNN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, \
3114 type2, bigtype) \
3115 \
3116 template <class T, class U> \
3117 inline type fun(const __gmp_expr<T, U> &expr, type2 t) \
3118 { \
3119 __gmp_expr<T, T> const& temp(expr); \
3120 return eval_fun::eval(temp.__get_mp(), static_cast<bigtype>(t)); \
3121 } \
3122 \
3123 template <class T, class U> \
3124 inline type fun(type2 t, const __gmp_expr<T, U> &expr) \
3125 { \
3126 __gmp_expr<T, T> const& temp(expr); \
3127 return eval_fun::eval(static_cast<bigtype>(t), temp.__get_mp()); \
3128 }
3129
3130 #define __GMPNS_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, type2) \
3131 __GMPNN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, \
3132 type2, signed long int)
3133
3134 #define __GMPNU_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, type2) \
3135 __GMPNN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, \
3136 type2, unsigned long int)
3137
3138 #define __GMPND_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, type2) \
3139 __GMPNN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, type2, double)
3140
3141 #define __GMPNLD_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, type2) \
3142 __GMPNN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, type2, long double)
3143
3144 #define __GMPN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun) \
3145 __GMPNS_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, signed char) \
3146 __GMPNU_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, unsigned char) \
3147 __GMPNS_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, signed int) \
3148 __GMPNU_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, unsigned int) \
3149 __GMPNS_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, signed short int) \
3150 __GMPNU_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, unsigned short int) \
3151 __GMPNS_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, signed long int) \
3152 __GMPNU_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, unsigned long int) \
3153 __GMPND_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, float) \
3154 __GMPND_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, double) \
3155
3156
3157 #define __GMP_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun) \
3158 __GMPP_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun) \
3159 __GMPN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun)
3160
3161
3162
3163
3164 #define __GMPP_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun) \
3165 \
3166 template <class T, class U> \
3167 inline type##_class & type##_class::fun(const __gmp_expr<T, U> &expr) \
3168 { \
3169 __gmp_set_expr(mp, __gmp_expr<type##_t, __gmp_binary_expr \
3170 <type##_class, __gmp_expr<T, U>, eval_fun> >(*this, expr)); \
3171 return *this; \
3172 }
3173
3174 #define __GMPNN_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, \
3175 type2, bigtype) \
3176 \
3177 inline type##_class & type##_class::fun(type2 t) \
3178 { \
3179 __gmp_set_expr(mp, __gmp_expr<type##_t, __gmp_binary_expr \
3180 <type##_class, bigtype, eval_fun> >(*this, t)); \
3181 return *this; \
3182 }
3183
3184 #define __GMPNS_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, type2) \
3185 __GMPNN_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, \
3186 type2, signed long int)
3187
3188 #define __GMPNU_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, type2) \
3189 __GMPNN_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, \
3190 type2, unsigned long int)
3191
3192 #define __GMPND_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, type2) \
3193 __GMPNN_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, type2, double)
3194
3195 #define __GMPNLD_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, type2) \
3196 __GMPNN_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, type2, long double)
3197
3198 #define __GMPN_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun) \
3199 __GMPNS_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, signed char) \
3200 __GMPNU_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, unsigned char) \
3201 __GMPNS_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, signed int) \
3202 __GMPNU_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, unsigned int) \
3203 __GMPNS_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, signed short int) \
3204 __GMPNU_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, unsigned short int) \
3205 __GMPNS_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, signed long int) \
3206 __GMPNU_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, unsigned long int) \
3207 __GMPND_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, float) \
3208 __GMPND_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, double) \
3209
3210
3211 #define __GMP_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun) \
3212 __GMPP_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun) \
3213 __GMPN_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun)
3214
3215 #define __GMPZ_DEFINE_COMPOUND_OPERATOR(fun, eval_fun) \
3216 __GMP_DEFINE_COMPOUND_OPERATOR(mpz, fun, eval_fun)
3217
3218 #define __GMPQ_DEFINE_COMPOUND_OPERATOR(fun, eval_fun) \
3219 __GMP_DEFINE_COMPOUND_OPERATOR(mpq, fun, eval_fun)
3220
3221 #define __GMPF_DEFINE_COMPOUND_OPERATOR(fun, eval_fun) \
3222 __GMP_DEFINE_COMPOUND_OPERATOR(mpf, fun, eval_fun)
3223
3224
3225
3226 #define __GMP_DEFINE_COMPOUND_OPERATOR_UI(type, fun, eval_fun) \
3227 \
3228 inline type##_class & type##_class::fun(mp_bitcnt_t l) \
3229 { \
3230 __gmp_set_expr(mp, __gmp_expr<type##_t, __gmp_binary_expr \
3231 <type##_class, mp_bitcnt_t, eval_fun> >(*this, l)); \
3232 return *this; \
3233 }
3234
3235 #define __GMPZ_DEFINE_COMPOUND_OPERATOR_UI(fun, eval_fun) \
3236 __GMP_DEFINE_COMPOUND_OPERATOR_UI(mpz, fun, eval_fun)
3237
3238 #define __GMPQ_DEFINE_COMPOUND_OPERATOR_UI(fun, eval_fun) \
3239 __GMP_DEFINE_COMPOUND_OPERATOR_UI(mpq, fun, eval_fun)
3240
3241 #define __GMPF_DEFINE_COMPOUND_OPERATOR_UI(fun, eval_fun) \
3242 __GMP_DEFINE_COMPOUND_OPERATOR_UI(mpf, fun, eval_fun)
3243
3244
3245
3246 #define __GMP_DEFINE_INCREMENT_OPERATOR(type, fun, eval_fun) \
3247 \
3248 inline type##_class & type##_class::fun() \
3249 { \
3250 eval_fun::eval(mp); \
3251 return *this; \
3252 } \
3253 \
3254 inline type##_class type##_class::fun(int) \
3255 { \
3256 type##_class temp(*this); \
3257 eval_fun::eval(mp); \
3258 return temp; \
3259 }
3260
3261 #define __GMPZ_DEFINE_INCREMENT_OPERATOR(fun, eval_fun) \
3262 __GMP_DEFINE_INCREMENT_OPERATOR(mpz, fun, eval_fun)
3263
3264 #define __GMPQ_DEFINE_INCREMENT_OPERATOR(fun, eval_fun) \
3265 __GMP_DEFINE_INCREMENT_OPERATOR(mpq, fun, eval_fun)
3266
3267 #define __GMPF_DEFINE_INCREMENT_OPERATOR(fun, eval_fun) \
3268 __GMP_DEFINE_INCREMENT_OPERATOR(mpf, fun, eval_fun)
3269
3270
3271 #define __GMPP_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun) \
3272 template <class U> \
3273 __gmp_expr<T, __gmp_unary_expr<__gmp_expr<T, U>, eval_fun> > \
3274 fun(const __gmp_expr<T, U> &expr) \
3275 { \
3276 return __gmp_expr<T, __gmp_unary_expr<__gmp_expr<T, U>, eval_fun> >(expr); \
3277 }
3278
3279 #define __GMPNN_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, type, bigtype) \
3280 inline __gmp_expr<T, __gmp_unary_expr<bigtype, eval_fun> > \
3281 fun(type expr) \
3282 { \
3283 return __gmp_expr<T, __gmp_unary_expr<bigtype, eval_fun> >(expr); \
3284 }
3285
3286 #define __GMPNS_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, type) \
3287 __GMPNN_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, type, signed long)
3288 #define __GMPNU_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, type) \
3289 __GMPNN_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, type, unsigned long)
3290 #define __GMPND_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, type) \
3291 __GMPNN_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, type, double)
3292
3293 #define __GMPN_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun) \
3294 __GMPNS_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, signed char) \
3295 __GMPNU_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, unsigned char) \
3296 __GMPNS_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, signed int) \
3297 __GMPNU_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, unsigned int) \
3298 __GMPNS_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, signed short int) \
3299 __GMPNU_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, unsigned short int) \
3300 __GMPNS_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, signed long int) \
3301 __GMPNU_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, unsigned long int) \
3302 __GMPND_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, float) \
3303 __GMPND_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, double) \
3304
3305 #define __GMP_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun) \
3306 __GMPP_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun) \
3307 __GMPN_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun) \
3308
3309
3310
3311
3312
3313
3314 __GMP_DEFINE_UNARY_FUNCTION(operator+, __gmp_unary_plus)
3315 __GMP_DEFINE_UNARY_FUNCTION(operator-, __gmp_unary_minus)
3316 __GMP_DEFINE_UNARY_FUNCTION_1(mpz_t, operator~, __gmp_unary_com)
3317
3318 __GMP_DEFINE_BINARY_FUNCTION(operator+, __gmp_binary_plus)
3319 __GMP_DEFINE_BINARY_FUNCTION(operator-, __gmp_binary_minus)
3320 __GMP_DEFINE_BINARY_FUNCTION(operator*, __gmp_binary_multiplies)
3321 __GMP_DEFINE_BINARY_FUNCTION(operator/, __gmp_binary_divides)
3322 __GMP_DEFINE_BINARY_FUNCTION_1(mpz_t, operator%, __gmp_binary_modulus)
3323 __GMP_DEFINE_BINARY_FUNCTION_1(mpz_t, operator&, __gmp_binary_and)
3324 __GMP_DEFINE_BINARY_FUNCTION_1(mpz_t, operator|, __gmp_binary_ior)
3325 __GMP_DEFINE_BINARY_FUNCTION_1(mpz_t, operator^, __gmp_binary_xor)
3326
3327 __GMP_DEFINE_BINARY_FUNCTION_UI(operator<<, __gmp_binary_lshift)
3328 __GMP_DEFINE_BINARY_FUNCTION_UI(operator>>, __gmp_binary_rshift)
3329
3330 __GMP_DEFINE_BINARY_TYPE_FUNCTION(bool, operator==, __gmp_binary_equal)
3331 __GMP_DEFINE_BINARY_TYPE_FUNCTION(bool, operator!=, ! __gmp_binary_equal)
3332 __GMP_DEFINE_BINARY_TYPE_FUNCTION(bool, operator<, __gmp_binary_less)
3333 __GMP_DEFINE_BINARY_TYPE_FUNCTION(bool, operator<=, ! __gmp_binary_greater)
3334 __GMP_DEFINE_BINARY_TYPE_FUNCTION(bool, operator>, __gmp_binary_greater)
3335 __GMP_DEFINE_BINARY_TYPE_FUNCTION(bool, operator>=, ! __gmp_binary_less)
3336
3337 __GMP_DEFINE_UNARY_FUNCTION(abs, __gmp_abs_function)
3338 __GMP_DEFINE_UNARY_FUNCTION_1(mpf_t, trunc, __gmp_trunc_function)
3339 __GMP_DEFINE_UNARY_FUNCTION_1(mpf_t, floor, __gmp_floor_function)
3340 __GMP_DEFINE_UNARY_FUNCTION_1(mpf_t, ceil, __gmp_ceil_function)
3341 __GMP_DEFINE_UNARY_FUNCTION_1(mpf_t, sqrt, __gmp_sqrt_function)
3342 __GMP_DEFINE_UNARY_FUNCTION_1(mpz_t, sqrt, __gmp_sqrt_function)
3343 __GMP_DEFINE_UNARY_FUNCTION_1(mpz_t, factorial, __gmp_fac_function)
3344 __GMP_DEFINE_UNARY_FUNCTION_1(mpz_t, primorial, __gmp_primorial_function)
3345 __GMP_DEFINE_UNARY_FUNCTION_1(mpz_t, fibonacci, __gmp_fib_function)
3346 __GMP_DEFINE_BINARY_FUNCTION_1(mpf_t, hypot, __gmp_hypot_function)
3347 __GMP_DEFINE_BINARY_FUNCTION_1(mpz_t, gcd, __gmp_gcd_function)
3348 __GMP_DEFINE_BINARY_FUNCTION_1(mpz_t, lcm, __gmp_lcm_function)
3349
3350 __GMP_DEFINE_UNARY_TYPE_FUNCTION(int, sgn, __gmp_sgn_function)
3351 __GMP_DEFINE_BINARY_TYPE_FUNCTION(int, cmp, __gmp_cmp_function)
3352
3353 template <class T>
3354 void swap(__gmp_expr<T, T>& x, __gmp_expr<T, T>& y) __GMPXX_NOEXCEPT
3355 { x.swap(y); }
3356
3357
3358
3359 __GMPZ_DEFINE_COMPOUND_OPERATOR(operator+=, __gmp_binary_plus)
3360 __GMPZ_DEFINE_COMPOUND_OPERATOR(operator-=, __gmp_binary_minus)
3361 __GMPZ_DEFINE_COMPOUND_OPERATOR(operator*=, __gmp_binary_multiplies)
3362 __GMPZ_DEFINE_COMPOUND_OPERATOR(operator/=, __gmp_binary_divides)
3363 __GMPZ_DEFINE_COMPOUND_OPERATOR(operator%=, __gmp_binary_modulus)
3364
3365 __GMPZ_DEFINE_COMPOUND_OPERATOR(operator&=, __gmp_binary_and)
3366 __GMPZ_DEFINE_COMPOUND_OPERATOR(operator|=, __gmp_binary_ior)
3367 __GMPZ_DEFINE_COMPOUND_OPERATOR(operator^=, __gmp_binary_xor)
3368
3369 __GMPZ_DEFINE_COMPOUND_OPERATOR_UI(operator<<=, __gmp_binary_lshift)
3370 __GMPZ_DEFINE_COMPOUND_OPERATOR_UI(operator>>=, __gmp_binary_rshift)
3371
3372 __GMPZ_DEFINE_INCREMENT_OPERATOR(operator++, __gmp_unary_increment)
3373 __GMPZ_DEFINE_INCREMENT_OPERATOR(operator--, __gmp_unary_decrement)
3374
3375 __GMP_DEFINE_UNARY_STATIC_MEMFUN(mpz_t, mpz_class::factorial, __gmp_fac_function)
3376 __GMP_DEFINE_UNARY_STATIC_MEMFUN(mpz_t, mpz_class::primorial, __gmp_primorial_function)
3377 __GMP_DEFINE_UNARY_STATIC_MEMFUN(mpz_t, mpz_class::fibonacci, __gmp_fib_function)
3378
3379
3380
3381 __GMPQ_DEFINE_COMPOUND_OPERATOR(operator+=, __gmp_binary_plus)
3382 __GMPQ_DEFINE_COMPOUND_OPERATOR(operator-=, __gmp_binary_minus)
3383 __GMPQ_DEFINE_COMPOUND_OPERATOR(operator*=, __gmp_binary_multiplies)
3384 __GMPQ_DEFINE_COMPOUND_OPERATOR(operator/=, __gmp_binary_divides)
3385
3386 __GMPQ_DEFINE_COMPOUND_OPERATOR_UI(operator<<=, __gmp_binary_lshift)
3387 __GMPQ_DEFINE_COMPOUND_OPERATOR_UI(operator>>=, __gmp_binary_rshift)
3388
3389 __GMPQ_DEFINE_INCREMENT_OPERATOR(operator++, __gmp_unary_increment)
3390 __GMPQ_DEFINE_INCREMENT_OPERATOR(operator--, __gmp_unary_decrement)
3391
3392
3393
3394 __GMPF_DEFINE_COMPOUND_OPERATOR(operator+=, __gmp_binary_plus)
3395 __GMPF_DEFINE_COMPOUND_OPERATOR(operator-=, __gmp_binary_minus)
3396 __GMPF_DEFINE_COMPOUND_OPERATOR(operator*=, __gmp_binary_multiplies)
3397 __GMPF_DEFINE_COMPOUND_OPERATOR(operator/=, __gmp_binary_divides)
3398
3399 __GMPF_DEFINE_COMPOUND_OPERATOR_UI(operator<<=, __gmp_binary_lshift)
3400 __GMPF_DEFINE_COMPOUND_OPERATOR_UI(operator>>=, __gmp_binary_rshift)
3401
3402 __GMPF_DEFINE_INCREMENT_OPERATOR(operator++, __gmp_unary_increment)
3403 __GMPF_DEFINE_INCREMENT_OPERATOR(operator--, __gmp_unary_decrement)
3404
3405
3406
3407
3408
3409 class __gmp_urandomb_value { };
3410 class __gmp_urandomm_value { };
3411
3412 template <>
3413 class __gmp_expr<mpz_t, __gmp_urandomb_value>
3414 {
3415 private:
3416 __gmp_randstate_struct *state;
3417 mp_bitcnt_t bits;
3418 public:
3419 __gmp_expr(gmp_randstate_t s, mp_bitcnt_t l) : state(s), bits(l) { }
3420 void eval(mpz_ptr z) const { __gmp_rand_function::eval(z, state, bits); }
3421 mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); }
3422 };
3423
3424 template <>
3425 class __gmp_expr<mpz_t, __gmp_urandomm_value>
3426 {
3427 private:
3428 __gmp_randstate_struct *state;
3429 mpz_class range;
3430 public:
3431 __gmp_expr(gmp_randstate_t s, const mpz_class &z) : state(s), range(z) { }
3432 void eval(mpz_ptr z) const
3433 { __gmp_rand_function::eval(z, state, range.get_mpz_t()); }
3434 mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); }
3435 };
3436
3437 template <>
3438 class __gmp_expr<mpf_t, __gmp_urandomb_value>
3439 {
3440 private:
3441 __gmp_randstate_struct *state;
3442 mp_bitcnt_t bits;
3443 public:
3444 __gmp_expr(gmp_randstate_t s, mp_bitcnt_t l) : state(s), bits(l) { }
3445 void eval(mpf_ptr f) const
3446 {
3447 __gmp_rand_function::eval(f, state,
3448 (bits>0) ? bits : mpf_get_prec(f));
3449 }
3450 mp_bitcnt_t get_prec() const
3451 {
3452 if (bits == 0)
3453 return mpf_get_default_prec();
3454 else
3455 return bits;
3456 }
3457 };
3458
3459 extern "C" {
3460 typedef void __gmp_randinit_default_t (gmp_randstate_t);
3461 typedef void __gmp_randinit_lc_2exp_t (gmp_randstate_t, mpz_srcptr, unsigned long int, mp_bitcnt_t);
3462 typedef int __gmp_randinit_lc_2exp_size_t (gmp_randstate_t, mp_bitcnt_t);
3463 }
3464
3465 class gmp_randclass
3466 {
3467 private:
3468 gmp_randstate_t state;
3469
3470
3471 gmp_randclass(const gmp_randclass &);
3472 void operator=(const gmp_randclass &);
3473 public:
3474
3475 gmp_randclass(gmp_randalg_t alg, unsigned long int size)
3476 {
3477 switch (alg)
3478 {
3479 case GMP_RAND_ALG_LC:
3480 default:
3481 gmp_randinit(state, alg, size);
3482 break;
3483 }
3484 }
3485
3486
3487 gmp_randclass(__gmp_randinit_default_t* f) { f(state); }
3488
3489
3490 gmp_randclass(__gmp_randinit_lc_2exp_t* f,
3491 mpz_class z, unsigned long int l1, mp_bitcnt_t l2)
3492 { f(state, z.get_mpz_t(), l1, l2); }
3493
3494
3495 gmp_randclass(__gmp_randinit_lc_2exp_size_t* f,
3496 mp_bitcnt_t size)
3497 {
3498 if (f (state, size) == 0)
3499 throw std::length_error ("gmp_randinit_lc_2exp_size");
3500 }
3501
3502 ~gmp_randclass() { gmp_randclear(state); }
3503
3504
3505 void seed();
3506 void seed(unsigned long int s) { gmp_randseed_ui(state, s); }
3507 void seed(const mpz_class &z) { gmp_randseed(state, z.get_mpz_t()); }
3508
3509
3510 __gmp_expr<mpz_t, __gmp_urandomb_value> get_z_bits(mp_bitcnt_t l)
3511 { return __gmp_expr<mpz_t, __gmp_urandomb_value>(state, l); }
3512 __gmp_expr<mpz_t, __gmp_urandomb_value> get_z_bits(const mpz_class &z)
3513 { return get_z_bits(z.get_ui()); }
3514
3515
3516 __gmp_expr<mpz_t, __gmp_urandomm_value> get_z_range(const mpz_class &z)
3517 { return __gmp_expr<mpz_t, __gmp_urandomm_value>(state, z); }
3518
3519 __gmp_expr<mpf_t, __gmp_urandomb_value> get_f(mp_bitcnt_t prec = 0)
3520 { return __gmp_expr<mpf_t, __gmp_urandomb_value>(state, prec); }
3521 };
3522
3523
3524
3525
3526 namespace std {
3527 template <> class numeric_limits<mpz_class>
3528 {
3529 public:
3530 static const bool is_specialized = true;
3531 static mpz_class min() { return mpz_class(); }
3532 static mpz_class max() { return mpz_class(); }
3533 static mpz_class lowest() { return mpz_class(); }
3534 static const int digits = 0;
3535 static const int digits10 = 0;
3536 static const int max_digits10 = 0;
3537 static const bool is_signed = true;
3538 static const bool is_integer = true;
3539 static const bool is_exact = true;
3540 static const int radix = 2;
3541 static mpz_class epsilon() { return mpz_class(); }
3542 static mpz_class round_error() { return mpz_class(); }
3543 static const int min_exponent = 0;
3544 static const int min_exponent10 = 0;
3545 static const int max_exponent = 0;
3546 static const int max_exponent10 = 0;
3547 static const bool has_infinity = false;
3548 static const bool has_quiet_NaN = false;
3549 static const bool has_signaling_NaN = false;
3550 static const float_denorm_style has_denorm = denorm_absent;
3551 static const bool has_denorm_loss = false;
3552 static mpz_class infinity() { return mpz_class(); }
3553 static mpz_class quiet_NaN() { return mpz_class(); }
3554 static mpz_class signaling_NaN() { return mpz_class(); }
3555 static mpz_class denorm_min() { return mpz_class(); }
3556 static const bool is_iec559 = false;
3557 static const bool is_bounded = false;
3558 static const bool is_modulo = false;
3559 static const bool traps = false;
3560 static const bool tinyness_before = false;
3561 static const float_round_style round_style = round_toward_zero;
3562 };
3563
3564 template <> class numeric_limits<mpq_class>
3565 {
3566 public:
3567 static const bool is_specialized = true;
3568 static mpq_class min() { return mpq_class(); }
3569 static mpq_class max() { return mpq_class(); }
3570 static mpq_class lowest() { return mpq_class(); }
3571 static const int digits = 0;
3572 static const int digits10 = 0;
3573 static const int max_digits10 = 0;
3574 static const bool is_signed = true;
3575 static const bool is_integer = false;
3576 static const bool is_exact = true;
3577 static const int radix = 2;
3578 static mpq_class epsilon() { return mpq_class(); }
3579 static mpq_class round_error() { return mpq_class(); }
3580 static const int min_exponent = 0;
3581 static const int min_exponent10 = 0;
3582 static const int max_exponent = 0;
3583 static const int max_exponent10 = 0;
3584 static const bool has_infinity = false;
3585 static const bool has_quiet_NaN = false;
3586 static const bool has_signaling_NaN = false;
3587 static const float_denorm_style has_denorm = denorm_absent;
3588 static const bool has_denorm_loss = false;
3589 static mpq_class infinity() { return mpq_class(); }
3590 static mpq_class quiet_NaN() { return mpq_class(); }
3591 static mpq_class signaling_NaN() { return mpq_class(); }
3592 static mpq_class denorm_min() { return mpq_class(); }
3593 static const bool is_iec559 = false;
3594 static const bool is_bounded = false;
3595 static const bool is_modulo = false;
3596 static const bool traps = false;
3597 static const bool tinyness_before = false;
3598 static const float_round_style round_style = round_toward_zero;
3599 };
3600
3601 template <> class numeric_limits<mpf_class>
3602 {
3603 public:
3604 static const bool is_specialized = true;
3605 static mpf_class min() { return mpf_class(); }
3606 static mpf_class max() { return mpf_class(); }
3607 static mpf_class lowest() { return mpf_class(); }
3608 static const int digits = 0;
3609 static const int digits10 = 0;
3610 static const int max_digits10 = 0;
3611 static const bool is_signed = true;
3612 static const bool is_integer = false;
3613 static const bool is_exact = false;
3614 static const int radix = 2;
3615 static mpf_class epsilon() { return mpf_class(); }
3616 static mpf_class round_error() { return mpf_class(); }
3617 static const int min_exponent = 0;
3618 static const int min_exponent10 = 0;
3619 static const int max_exponent = 0;
3620 static const int max_exponent10 = 0;
3621 static const bool has_infinity = false;
3622 static const bool has_quiet_NaN = false;
3623 static const bool has_signaling_NaN = false;
3624 static const float_denorm_style has_denorm = denorm_absent;
3625 static const bool has_denorm_loss = false;
3626 static mpf_class infinity() { return mpf_class(); }
3627 static mpf_class quiet_NaN() { return mpf_class(); }
3628 static mpf_class signaling_NaN() { return mpf_class(); }
3629 static mpf_class denorm_min() { return mpf_class(); }
3630 static const bool is_iec559 = false;
3631 static const bool is_bounded = false;
3632 static const bool is_modulo = false;
3633 static const bool traps = false;
3634 static const bool tinyness_before = false;
3635 static const float_round_style round_style = round_indeterminate;
3636 };
3637 }
3638
3639
3640
3641
3642 #undef __GMPP_DECLARE_COMPOUND_OPERATOR
3643 #undef __GMPN_DECLARE_COMPOUND_OPERATOR
3644 #undef __GMP_DECLARE_COMPOUND_OPERATOR
3645 #undef __GMP_DECLARE_COMPOUND_OPERATOR_UI
3646 #undef __GMP_DECLARE_INCREMENT_OPERATOR
3647 #undef __GMPXX_DEFINE_ARITHMETIC_CONSTRUCTORS
3648 #undef __GMPXX_DEFINE_ARITHMETIC_ASSIGNMENTS
3649
3650 #undef __GMPZQ_DEFINE_EXPR
3651
3652 #undef __GMP_DEFINE_UNARY_FUNCTION_1
3653 #undef __GMP_DEFINE_UNARY_FUNCTION
3654 #undef __GMP_DEFINE_UNARY_TYPE_FUNCTION
3655
3656 #undef __GMPP_DEFINE_BINARY_FUNCTION
3657 #undef __GMPNN_DEFINE_BINARY_FUNCTION
3658 #undef __GMPNS_DEFINE_BINARY_FUNCTION
3659 #undef __GMPNU_DEFINE_BINARY_FUNCTION
3660 #undef __GMPND_DEFINE_BINARY_FUNCTION
3661 #undef __GMPNLD_DEFINE_BINARY_FUNCTION
3662 #undef __GMPN_DEFINE_BINARY_FUNCTION
3663 #undef __GMP_DEFINE_BINARY_FUNCTION
3664
3665 #undef __GMP_DEFINE_BINARY_FUNCTION_UI
3666
3667 #undef __GMPP_DEFINE_BINARY_TYPE_FUNCTION
3668 #undef __GMPNN_DEFINE_BINARY_TYPE_FUNCTION
3669 #undef __GMPNS_DEFINE_BINARY_TYPE_FUNCTION
3670 #undef __GMPNU_DEFINE_BINARY_TYPE_FUNCTION
3671 #undef __GMPND_DEFINE_BINARY_TYPE_FUNCTION
3672 #undef __GMPNLD_DEFINE_BINARY_TYPE_FUNCTION
3673 #undef __GMPN_DEFINE_BINARY_TYPE_FUNCTION
3674 #undef __GMP_DEFINE_BINARY_TYPE_FUNCTION
3675
3676 #undef __GMPZ_DEFINE_COMPOUND_OPERATOR
3677
3678 #undef __GMPP_DEFINE_COMPOUND_OPERATOR
3679 #undef __GMPNN_DEFINE_COMPOUND_OPERATOR
3680 #undef __GMPNS_DEFINE_COMPOUND_OPERATOR
3681 #undef __GMPNU_DEFINE_COMPOUND_OPERATOR
3682 #undef __GMPND_DEFINE_COMPOUND_OPERATOR
3683 #undef __GMPNLD_DEFINE_COMPOUND_OPERATOR
3684 #undef __GMPN_DEFINE_COMPOUND_OPERATOR
3685 #undef __GMP_DEFINE_COMPOUND_OPERATOR
3686
3687 #undef __GMPQ_DEFINE_COMPOUND_OPERATOR
3688 #undef __GMPF_DEFINE_COMPOUND_OPERATOR
3689
3690 #undef __GMP_DEFINE_COMPOUND_OPERATOR_UI
3691 #undef __GMPZ_DEFINE_COMPOUND_OPERATOR_UI
3692 #undef __GMPQ_DEFINE_COMPOUND_OPERATOR_UI
3693 #undef __GMPF_DEFINE_COMPOUND_OPERATOR_UI
3694
3695 #undef __GMP_DEFINE_INCREMENT_OPERATOR
3696 #undef __GMPZ_DEFINE_INCREMENT_OPERATOR
3697 #undef __GMPQ_DEFINE_INCREMENT_OPERATOR
3698 #undef __GMPF_DEFINE_INCREMENT_OPERATOR
3699
3700 #undef __GMPXX_CONSTANT_TRUE
3701 #undef __GMPXX_CONSTANT
3702
3703 #endif