Hello,I am tempted to go with something like the attached patch to support long long in gmpxx.h. (the patch is not quite ready) Essentially, it adds a way to build mpz_class from long long, and for all other operations, long long is converted to long if it fits and to mpz_class otherwise. So z+1LL is turned into z+1L on x86_64-linux and z+mpz_class(1LL) on win64.
A possible improvement would be to delay the replacement until evaluation, so we can check at runtime if the long long fits a long, instead of just checking if the 2 types have the same size. It would also allow using an mpz_t pointing to a local buffer to avoid a dynamic allocation. It is a bit more code though.
I am tempted to require a compiler that supports long long for gmpxx.h. We could require C++11 for that, but just long long is a much weaker requirement. I currently use a fake type for C++98 to avoid repeating #if all over the place.
Of course this can be updated once GMP itself adds support for long long, but I think it can be merged first without causing trouble.
-- Marc Glisse
diff -r 632506b00743 gmpxx.h --- a/gmpxx.h Sat May 08 19:34:05 2021 +0200 +++ b/gmpxx.h Sun Jun 06 23:37:17 2021 +0200 @@ -65,8 +65,18 @@ #if __GMPXX_USE_CXX11 #define __GMPXX_NOEXCEPT noexcept #include <type_traits> // for common_type +typedef signed long long int __gmp_slli; +typedef unsigned long long int __gmp_ulli; #else #define __GMPXX_NOEXCEPT +// Fake long long to avoid too many #ifdef +struct __gmp_slli { bool operator<(int) const; }; +struct __gmp_ulli { + __gmp_ulli(__gmp_slli); + operator unsigned long() const; + __gmp_ulli operator-() const; + __gmp_ulli operator>>(int) const; +}; #endif // Max allocations for plain types when converted to GMP types @@ -154,6 +164,11 @@ return l >= 0 ? static_cast<unsigned long>(l) : -static_cast<unsigned long>(l); } +inline __gmp_ulli __gmpxx_abs_ull (__gmp_slli l) +{ + return l < 0 ? -static_cast<__gmp_ulli>(l) + : static_cast<__gmp_ulli>(l); +} /**************** Function objects ****************/ /* Any evaluation of a __gmp_expr ends up calling one of these functions @@ -1333,6 +1348,9 @@ template <class T, class U> class __gmp_expr; +typedef __gmp_expr<mpz_t, mpz_t> mpz_class; +typedef __gmp_expr<mpq_t, mpq_t> mpq_class; +typedef __gmp_expr<mpf_t, mpf_t> mpf_class; // templates for resolving expression types template <class T> @@ -1411,6 +1429,27 @@ typedef mpf_t value_type; }; +// To reduce code bloat, signed char, short and int are cast to long +// internally, and similarly for unsigned types. long long is cast to long if +// that has the same size, or mpz_class otherwise. +template <class T, bool = sizeof(T) <= sizeof(long), bool = std::numeric_limits<T>::is_signed> +struct __gmpxx_int_canonical +{ + typedef mpz_class Type; +}; + +template <class T> +struct __gmpxx_int_canonical<T, true, true> +{ + typedef long Type; +}; + +template <class T> +struct __gmpxx_int_canonical<T, true, false> +{ + typedef unsigned long Type; +}; + #if __GMPXX_USE_CXX11 namespace std { template <class T, class U, class V, class W> @@ -1449,6 +1488,8 @@ __GMPXX_DECLARE_COMMON_TYPE(unsigned short int); __GMPXX_DECLARE_COMMON_TYPE(signed long int); __GMPXX_DECLARE_COMMON_TYPE(unsigned long int); + __GMPXX_DECLARE_COMMON_TYPE(__gmp_slli); + __GMPXX_DECLARE_COMMON_TYPE(__gmp_ulli); __GMPXX_DECLARE_COMMON_TYPE(float); __GMPXX_DECLARE_COMMON_TYPE(double); #undef __GMPXX_DECLARE_COMMON_TYPE @@ -1496,6 +1537,8 @@ __gmp_expr & fun(unsigned short int); \ __gmp_expr & fun(signed long int); \ __gmp_expr & fun(unsigned long int); \ + __gmp_expr & fun(__gmp_slli); \ + __gmp_expr & fun(__gmp_ulli); \ __gmp_expr & fun(float); \ __gmp_expr & fun(double); \ /* __gmp_expr & fun(long double); */ @@ -1520,6 +1563,8 @@ __gmp_expr(unsigned short int s) { init_ui(s); } \ __gmp_expr(signed long int l) { init_si(l); } \ __gmp_expr(unsigned long int l) { init_ui(l); } \ + __gmp_expr(__gmp_slli l) { init_sll(l); } \ + __gmp_expr(__gmp_ulli l) { init_ull(l); } \ __gmp_expr(float f) { init_d(f); } \ __gmp_expr(double d) { init_d(d); } @@ -1532,6 +1577,8 @@ __gmp_expr & operator=(unsigned short int s) { assign_ui(s); return *this; } \ __gmp_expr & operator=(signed long int l) { assign_si(l); return *this; } \ __gmp_expr & operator=(unsigned long int l) { assign_ui(l); return *this; } \ + __gmp_expr & operator=(__gmp_slli l) { assign_sll(l); return *this; } \ + __gmp_expr & operator=(__gmp_ulli l) { assign_ull(l); return *this; } \ __gmp_expr & operator=(float f) { assign_d(f); return *this; } \ __gmp_expr & operator=(double d) { assign_d(d); return *this; } @@ -1544,22 +1591,22 @@ static inline __gmp_expr<T, __gmp_unary_expr<bigtype, eval_fun> > \ fun(type expr); -#define __GMPNS_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, type) \ -__GMPNN_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, type, signed long) -#define __GMPNU_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, type) \ -__GMPNN_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, type, unsigned long) +#define __GMPNI_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, type) \ +__GMPNN_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, type, __gmpxx_int_canonical<type>::Type) #define __GMPND_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, type) \ __GMPNN_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, type, double) #define __GMPN_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun) \ -__GMPNS_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, signed char) \ -__GMPNU_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, unsigned char) \ -__GMPNS_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, signed int) \ -__GMPNU_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, unsigned int) \ -__GMPNS_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, signed short int) \ -__GMPNU_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, unsigned short int) \ -__GMPNS_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, signed long int) \ -__GMPNU_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, unsigned long int) \ +__GMPNI_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, signed char) \ +__GMPNI_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, unsigned char) \ +__GMPNI_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, signed int) \ +__GMPNI_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, unsigned int) \ +__GMPNI_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, signed short int) \ +__GMPNI_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, unsigned short int) \ +__GMPNI_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, signed long int) \ +__GMPNI_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, unsigned long int) \ +__GMPNI_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, __gmp_slli) \ +__GMPNI_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, __gmp_ulli)\ __GMPND_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, float) \ __GMPND_DECLARE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, double) @@ -1624,6 +1671,70 @@ { mpz_init_set_d (mp, d); } + void init_ull(__gmp_ulli l) + { + //if (sizeof(long) == sizeof(long long)) + if (l <= std::numeric_limits<unsigned long>::max()) + { + init_ui(static_cast<unsigned long>(l)); + return; + } +# ifdef INTRUSIVE + mpz_init2(mp, std::numeric_limits<__gmp_ulli>::digits); + mp_limb_t *p = mp->_mp_d; + while (l != 0) + { + *p++ = static_cast<mp_limb_t>(l & GMP_NUMB_MASK); + l >>= GMP_NUMB_BITS; + } + mp->_mp_size = p - mp->_mp_d; +# else + // avoid a warning about x >> 64 for 64-bit x in dead code. + int sizel = (sizeof(long) < sizeof(__gmp_ulli)) + ? std::numeric_limits<unsigned long>::digits : 0; + init_ull(l >> sizel); + mpz_mul_2exp(mp, mp, sizel); + mpz_add_ui(mp, mp, static_cast<unsigned long>(l)); +# endif + } + void init_sll(__gmp_slli l) + { + init_ull(__gmpxx_abs_ull(l)); + if (l < 0) + mpz_neg(mp, mp); + } + void assign_ull(__gmp_ulli l) + { + //if (sizeof(long) == sizeof(long long)) + if (l <= std::numeric_limits<unsigned long>::max()) + { + assign_ui(static_cast<unsigned long>(l)); + return; + } +# ifdef INTRUSIVE + if (mp->_mp_alloc * GMP_NUMB_BITS < std::numeric_limits<__gmp_ulli>::digits) + mpz_realloc2(mp, std::numeric_limits<__gmp_ulli>::digits); + mp_limb_t *p = mp->_mp_d; + while (l != 0) + { + *p++ = static_cast<mp_limb_t>(l & GMP_NUMB_MASK); + l >>= GMP_NUMB_BITS; + } + mp->_mp_size = p - mp->_mp_d; +# else + int sizel = (sizeof(long) < sizeof(__gmp_ulli)) + ? std::numeric_limits<unsigned long>::digits : 0; + assign_ull(l >> sizel); + mpz_mul_2exp(mp, mp, std::numeric_limits<unsigned long>::digits); + mpz_add_ui(mp, mp, static_cast<unsigned long>(l)); +# endif + } + void assign_sll(__gmp_slli l) + { + assign_ull(__gmpxx_abs_ull(l)); + if (l < 0) + mpz_neg(mp, mp); + } public: mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); } @@ -1753,8 +1864,6 @@ __GMP_DECLARE_UNARY_STATIC_MEMFUN(mpz_t, fibonacci, __gmp_fib_function) }; -typedef __gmp_expr<mpz_t, mpz_t> mpz_class; - /**************** mpq_class -- wrapper for mpq_t ****************/ @@ -1775,10 +1884,14 @@ mpq_set_si(mp, l, 1); } void assign_d (double d) { mpq_set_d (mp, d); } + void assign_ull(__gmp_ulli l) { get_num() = l; get_den() = 1; } + void assign_sll(__gmp_slli l) { get_num() = l; get_den() = 1; } void init_ui(unsigned long l) { mpq_init(mp); get_num() = l; } void init_si(signed long l) { mpq_init(mp); get_num() = l; } void init_d (double d) { mpq_init(mp); assign_d (d); } + void init_ull(__gmp_ulli l) { mpq_init(mp); get_num() = l; } + void init_sll(__gmp_slli l) { mpq_init(mp); get_num() = l; } public: mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); } @@ -1931,8 +2044,6 @@ __GMP_DECLARE_INCREMENT_OPERATOR(operator--) }; -typedef __gmp_expr<mpq_t, mpq_t> mpq_class; - /**************** mpf_class -- wrapper for mpf_t ****************/ @@ -1952,6 +2063,14 @@ else mpf_set_si(mp, l); } + void assign_sll(__gmp_slli l) + { + *this = static_cast<__gmpxx_int_canonical<__gmp_slli>::Type>(l); + } + void assign_ull(__gmp_ulli l) + { + *this = static_cast<__gmpxx_int_canonical<__gmp_ulli>::Type>(l); + } void assign_d (double d) { mpf_set_d (mp, d); } void init_ui(unsigned long l) @@ -1968,6 +2087,8 @@ else mpf_init_set_si(mp, l); } + void init_sll(__gmp_slli l) { mpf_init(mp); assign_sll(l); } + void init_ull(__gmp_ulli l) { mpf_init(mp); assign_ull(l); } void init_d (double d) { mpf_init_set_d (mp, d); } public: @@ -2016,6 +2137,11 @@ __gmp_expr(unsigned long int l, mp_bitcnt_t prec) { mpf_init2(mp, prec); mpf_set_ui(mp, l); } + __gmp_expr(__gmp_slli l, mp_bitcnt_t prec) + { mpf_init2(mp, prec); *this = mpz_class(l); } + __gmp_expr(__gmp_ulli l, mp_bitcnt_t prec) + { mpf_init2(mp, prec); *this = mpz_class(l); } + __gmp_expr(float f, mp_bitcnt_t prec) { mpf_init2(mp, prec); mpf_set_d(mp, f); } __gmp_expr(double d, mp_bitcnt_t prec) @@ -2144,8 +2270,6 @@ __GMP_DECLARE_INCREMENT_OPERATOR(operator--) }; -typedef __gmp_expr<mpf_t, mpf_t> mpf_class; - /**************** User-defined literals ****************/ @@ -2982,7 +3106,7 @@ fun(const __gmp_expr<T, U> &expr, type t) \ { \ return __gmp_expr \ - <T, __gmp_binary_expr<__gmp_expr<T, U>, bigtype, eval_fun> >(expr, t); \ + <T, __gmp_binary_expr<__gmp_expr<T, U>, bigtype, eval_fun> >(expr, static_cast<bigtype>(t)); \ } \ \ template <class T, class U> \ @@ -2991,14 +3115,11 @@ fun(type t, const __gmp_expr<T, U> &expr) \ { \ return __gmp_expr \ - <T, __gmp_binary_expr<bigtype, __gmp_expr<T, U>, eval_fun> >(t, expr); \ + <T, __gmp_binary_expr<bigtype, __gmp_expr<T, U>, eval_fun> >(static_cast<bigtype>(t), expr); \ } -#define __GMPNS_DEFINE_BINARY_FUNCTION(fun, eval_fun, type) \ -__GMPNN_DEFINE_BINARY_FUNCTION(fun, eval_fun, type, signed long int) - -#define __GMPNU_DEFINE_BINARY_FUNCTION(fun, eval_fun, type) \ -__GMPNN_DEFINE_BINARY_FUNCTION(fun, eval_fun, type, unsigned long int) +#define __GMPNI_DEFINE_BINARY_FUNCTION(fun, eval_fun, type) \ +__GMPNN_DEFINE_BINARY_FUNCTION(fun, eval_fun, type, __gmpxx_int_canonical<type>::Type) #define __GMPND_DEFINE_BINARY_FUNCTION(fun, eval_fun, type) \ __GMPNN_DEFINE_BINARY_FUNCTION(fun, eval_fun, type, double) @@ -3007,14 +3128,16 @@ __GMPNN_DEFINE_BINARY_FUNCTION(fun, eval_fun, type, long double) #define __GMPN_DEFINE_BINARY_FUNCTION(fun, eval_fun) \ -__GMPNS_DEFINE_BINARY_FUNCTION(fun, eval_fun, signed char) \ -__GMPNU_DEFINE_BINARY_FUNCTION(fun, eval_fun, unsigned char) \ -__GMPNS_DEFINE_BINARY_FUNCTION(fun, eval_fun, signed int) \ -__GMPNU_DEFINE_BINARY_FUNCTION(fun, eval_fun, unsigned int) \ -__GMPNS_DEFINE_BINARY_FUNCTION(fun, eval_fun, signed short int) \ -__GMPNU_DEFINE_BINARY_FUNCTION(fun, eval_fun, unsigned short int) \ -__GMPNS_DEFINE_BINARY_FUNCTION(fun, eval_fun, signed long int) \ -__GMPNU_DEFINE_BINARY_FUNCTION(fun, eval_fun, unsigned long int) \ +__GMPNI_DEFINE_BINARY_FUNCTION(fun, eval_fun, signed char) \ +__GMPNI_DEFINE_BINARY_FUNCTION(fun, eval_fun, unsigned char) \ +__GMPNI_DEFINE_BINARY_FUNCTION(fun, eval_fun, signed int) \ +__GMPNI_DEFINE_BINARY_FUNCTION(fun, eval_fun, unsigned int) \ +__GMPNI_DEFINE_BINARY_FUNCTION(fun, eval_fun, signed short int) \ +__GMPNI_DEFINE_BINARY_FUNCTION(fun, eval_fun, unsigned short int) \ +__GMPNI_DEFINE_BINARY_FUNCTION(fun, eval_fun, signed long int) \ +__GMPNI_DEFINE_BINARY_FUNCTION(fun, eval_fun, unsigned long int) \ +__GMPNI_DEFINE_BINARY_FUNCTION(fun, eval_fun, __gmp_slli) \ +__GMPNI_DEFINE_BINARY_FUNCTION(fun, eval_fun, __gmp_ulli) \ __GMPND_DEFINE_BINARY_FUNCTION(fun, eval_fun, float) \ __GMPND_DEFINE_BINARY_FUNCTION(fun, eval_fun, double) \ /* __GMPNLD_DEFINE_BINARY_FUNCTION(fun, eval_fun, long double) */ @@ -3045,7 +3168,7 @@ fun(const __gmp_expr<T, U> &expr, type t) \ { \ return __gmp_expr \ - <T, __gmp_binary_expr<__gmp_expr<T, U>, bigtype, eval_fun> >(expr, t); \ + <T, __gmp_binary_expr<__gmp_expr<T, U>, bigtype, eval_fun> >(expr, static_cast<bigtype>(t)); \ } \ \ template <class U> \ @@ -3054,14 +3177,11 @@ fun(type t, const __gmp_expr<T, U> &expr) \ { \ return __gmp_expr \ - <T, __gmp_binary_expr<bigtype, __gmp_expr<T, U>, eval_fun> >(t, expr); \ + <T, __gmp_binary_expr<bigtype, __gmp_expr<T, U>, eval_fun> >(static_cast<bigtype>(t), expr); \ } -#define __GMPNS_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, type) \ -__GMPNN_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, type, signed long int) - -#define __GMPNU_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, type) \ -__GMPNN_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, type, unsigned long int) +#define __GMPNI_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, type) \ +__GMPNN_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, type, __gmpxx_int_canonical<type>::Type) #define __GMPND_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, type) \ __GMPNN_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, type, double) @@ -3070,14 +3190,16 @@ __GMPNN_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, type, long double) #define __GMPN_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun) \ -__GMPNS_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, signed char) \ -__GMPNU_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, unsigned char) \ -__GMPNS_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, signed int) \ -__GMPNU_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, unsigned int) \ -__GMPNS_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, signed short int) \ -__GMPNU_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, unsigned short int) \ -__GMPNS_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, signed long int) \ -__GMPNU_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, unsigned long int) \ +__GMPNI_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, signed char) \ +__GMPNI_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, unsigned char) \ +__GMPNI_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, signed int) \ +__GMPNI_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, unsigned int) \ +__GMPNI_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, signed short int) \ +__GMPNI_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, unsigned short int) \ +__GMPNI_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, signed long int) \ +__GMPNI_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, unsigned long int) \ +__GMPNI_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, __gmp_slli) \ +__GMPNI_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, __gmp_ulli) \ __GMPND_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, float) \ __GMPND_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, double) \ /* __GMPNLD_DEFINE_BINARY_FUNCTION_1(T, fun, eval_fun, long double) */ @@ -3127,13 +3249,9 @@ return eval_fun::eval(static_cast<bigtype>(t), temp.__get_mp()); \ } -#define __GMPNS_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, type2) \ +#define __GMPNI_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, type2) \ __GMPNN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, \ - type2, signed long int) - -#define __GMPNU_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, type2) \ -__GMPNN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, \ - type2, unsigned long int) + type2, __gmpxx_int_canonical<type2>::Type) #define __GMPND_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, type2) \ __GMPNN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, type2, double) @@ -3142,14 +3260,16 @@ __GMPNN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, type2, long double) #define __GMPN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun) \ -__GMPNS_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, signed char) \ -__GMPNU_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, unsigned char) \ -__GMPNS_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, signed int) \ -__GMPNU_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, unsigned int) \ -__GMPNS_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, signed short int) \ -__GMPNU_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, unsigned short int) \ -__GMPNS_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, signed long int) \ -__GMPNU_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, unsigned long int) \ +__GMPNI_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, signed char) \ +__GMPNI_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, unsigned char) \ +__GMPNI_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, signed int) \ +__GMPNI_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, unsigned int) \ +__GMPNI_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, signed short int) \ +__GMPNI_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, unsigned short int) \ +__GMPNI_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, signed long int) \ +__GMPNI_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, unsigned long int) \ +__GMPNI_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, __gmp_slli) \ +__GMPNI_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, __gmp_ulli) \ __GMPND_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, float) \ __GMPND_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, double) \ /* __GMPNLD_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, long double) */ @@ -3177,17 +3297,13 @@ inline type##_class & type##_class::fun(type2 t) \ { \ __gmp_set_expr(mp, __gmp_expr<type##_t, __gmp_binary_expr \ - <type##_class, bigtype, eval_fun> >(*this, t)); \ + <type##_class, bigtype, eval_fun> >(*this, static_cast<bigtype>(t))); \ return *this; \ } -#define __GMPNS_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, type2) \ +#define __GMPNI_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, type2) \ __GMPNN_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, \ - type2, signed long int) - -#define __GMPNU_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, type2) \ -__GMPNN_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, \ - type2, unsigned long int) + type2, __gmpxx_int_canonical<type2>::Type) #define __GMPND_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, type2) \ __GMPNN_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, type2, double) @@ -3196,14 +3312,16 @@ __GMPNN_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, type2, long double) #define __GMPN_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun) \ -__GMPNS_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, signed char) \ -__GMPNU_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, unsigned char) \ -__GMPNS_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, signed int) \ -__GMPNU_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, unsigned int) \ -__GMPNS_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, signed short int) \ -__GMPNU_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, unsigned short int) \ -__GMPNS_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, signed long int) \ -__GMPNU_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, unsigned long int) \ +__GMPNI_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, signed char) \ +__GMPNI_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, unsigned char) \ +__GMPNI_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, signed int) \ +__GMPNI_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, unsigned int) \ +__GMPNI_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, signed short int) \ +__GMPNI_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, unsigned short int) \ +__GMPNI_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, signed long int) \ +__GMPNI_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, unsigned long int) \ +__GMPNI_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, __gmp_slli) \ +__GMPNI_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, __gmp_ulli) \ __GMPND_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, float) \ __GMPND_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, double) \ /* __GMPNLD_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, long double) */ @@ -3283,22 +3401,22 @@ return __gmp_expr<T, __gmp_unary_expr<bigtype, eval_fun> >(expr); \ } -#define __GMPNS_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, type) \ -__GMPNN_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, type, signed long) -#define __GMPNU_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, type) \ -__GMPNN_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, type, unsigned long) +#define __GMPNI_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, type) \ +__GMPNN_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, type, __gmpxx_int_canonical<type>::Type) #define __GMPND_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, type) \ __GMPNN_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, type, double) #define __GMPN_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun) \ -__GMPNS_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, signed char) \ -__GMPNU_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, unsigned char) \ -__GMPNS_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, signed int) \ -__GMPNU_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, unsigned int) \ -__GMPNS_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, signed short int) \ -__GMPNU_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, unsigned short int) \ -__GMPNS_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, signed long int) \ -__GMPNU_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, unsigned long int) \ +__GMPNI_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, signed char) \ +__GMPNI_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, unsigned char) \ +__GMPNI_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, signed int) \ +__GMPNI_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, unsigned int) \ +__GMPNI_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, signed short int) \ +__GMPNI_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, unsigned short int) \ +__GMPNI_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, signed long int) \ +__GMPNI_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, unsigned long int) \ +__GMPNI_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, __gmp_slli) \ +__GMPNI_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, __gmp_ulli) \ __GMPND_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, float) \ __GMPND_DEFINE_UNARY_STATIC_MEMFUN(T, fun, eval_fun, double) \ @@ -3659,8 +3777,18 @@ #undef __GMPNU_DEFINE_BINARY_FUNCTION #undef __GMPND_DEFINE_BINARY_FUNCTION #undef __GMPNLD_DEFINE_BINARY_FUNCTION +#undef __GMPNZ_DEFINE_BINARY_FUNCTION #undef __GMPN_DEFINE_BINARY_FUNCTION #undef __GMP_DEFINE_BINARY_FUNCTION +#undef __GMPP_DEFINE_BINARY_FUNCTION_1 +#undef __GMPNN_DEFINE_BINARY_FUNCTION_1 +#undef __GMPNS_DEFINE_BINARY_FUNCTION_1 +#undef __GMPNU_DEFINE_BINARY_FUNCTION_1 +#undef __GMPND_DEFINE_BINARY_FUNCTION_1 +#undef __GMPNLD_DEFINE_BINARY_FUNCTION_1 +#undef __GMPNZ_DEFINE_BINARY_FUNCTION_1 +#undef __GMPN_DEFINE_BINARY_FUNCTION_1 +#undef __GMP_DEFINE_BINARY_FUNCTION_1 #undef __GMP_DEFINE_BINARY_FUNCTION_UI @@ -3670,6 +3798,7 @@ #undef __GMPNU_DEFINE_BINARY_TYPE_FUNCTION #undef __GMPND_DEFINE_BINARY_TYPE_FUNCTION #undef __GMPNLD_DEFINE_BINARY_TYPE_FUNCTION +#undef __GMPNZ_DEFINE_BINARY_TYPE_FUNCTION #undef __GMPN_DEFINE_BINARY_TYPE_FUNCTION #undef __GMP_DEFINE_BINARY_TYPE_FUNCTION @@ -3681,9 +3810,20 @@ #undef __GMPNU_DEFINE_COMPOUND_OPERATOR #undef __GMPND_DEFINE_COMPOUND_OPERATOR #undef __GMPNLD_DEFINE_COMPOUND_OPERATOR +#undef __GMPNZ_DEFINE_COMPOUND_OPERATOR #undef __GMPN_DEFINE_COMPOUND_OPERATOR #undef __GMP_DEFINE_COMPOUND_OPERATOR +#undef __GMPP_DEFINE_UNARY_STATIC_MEMFUN +#undef __GMPNN_DEFINE_UNARY_STATIC_MEMFUN +#undef __GMPNS_DEFINE_UNARY_STATIC_MEMFUN +#undef __GMPNU_DEFINE_UNARY_STATIC_MEMFUN +#undef __GMPND_DEFINE_UNARY_STATIC_MEMFUN +#undef __GMPNLD_DEFINE_UNARY_STATIC_MEMFUN +#undef __GMPNZ_DEFINE_UNARY_STATIC_MEMFUN +#undef __GMPN_DEFINE_UNARY_STATIC_MEMFUN +#undef __GMP_DEFINE_UNARY_STATIC_MEMFUN + #undef __GMPQ_DEFINE_COMPOUND_OPERATOR #undef __GMPF_DEFINE_COMPOUND_OPERATOR diff -r 632506b00743 tests/cxx/t-ops2.h --- a/tests/cxx/t-ops2.h Sat May 08 19:34:05 2021 +0200 +++ b/tests/cxx/t-ops2.h Sun Jun 06 23:37:17 2021 +0200 @@ -38,6 +38,17 @@ #define CHECK_SI(Type,a,b,op) \ CHECK(Type,long,a,b,op); \ CHECK(long,Type,a,b,op) +#if __GMPXX_USE_CXX11 + #define CHECK_ULL(Type,a,b,op) \ + CHECK(Type,unsigned long long,a,b,op); \ + CHECK(unsigned long long,Type,a,b,op) + #define CHECK_SLL(Type,a,b,op) \ + CHECK(Type,long long,a,b,op); \ + CHECK(long long,Type,a,b,op) +#else + #define CHECK_ULL(Type,a,b,op) (void)0 + #define CHECK_SLL(Type,a,b,op) (void)0 +#endif #define CHECK_D(Type,a,b,op) \ CHECK(Type,double,a,b,op); \ CHECK(double,Type,a,b,op) @@ -50,6 +61,7 @@ #define CHECK_ALL_SIGNED(Type,a,b,op) \ CHECK_G(Type,a,b,op); \ CHECK_SI(Type,a,b,op); \ + CHECK_SLL(Type,a,b,op); \ CHECK_D(Type,a,b,op) #define CHECK_ALL_SIGNS(Type,a,b,op) \ CHECK_ALL_SIGNED(Type,a,b,op); \ @@ -58,7 +70,8 @@ CHECK_ALL_SIGNED(Type,-(a),-(b),op) #define CHECK_ALL(Type,a,b,op) \ CHECK_ALL_SIGNED(Type,a,b,op); \ - CHECK_UI(Type,a,b,op) + CHECK_UI(Type,a,b,op); \ + CHECK_ULL(Type,a,b,op) #define CHECK_ALL_SIGNED_COMPARISONS(Type,a,b) \ CHECK_ALL_SIGNED(Type,a,b,<); \ CHECK_ALL_SIGNED(Type,a,b,>); \ diff -r 632506b00743 tests/cxx/t-ops2z.cc --- a/tests/cxx/t-ops2z.cc Sat May 08 19:34:05 2021 +0200 +++ b/tests/cxx/t-ops2z.cc Sun Jun 06 23:37:17 2021 +0200 @@ -114,6 +114,16 @@ ASSERT_ALWAYS(mpz_class::fibonacci(-3)==2); try { ret=fibonacci(mpz_class(1)<<300); ASSERT_ALWAYS(0); } catch (std::bad_alloc&) {} +#if __GMPXX_USE_CXX11 + unsigned long long ma = std::numeric_limits<unsigned long long>::max(); + long long mi = std::numeric_limits<unsigned long long>::min(); + ASSERT_ALWAYS(mpz_class(ma) > mpz_class(ma-1)); + ASSERT_ALWAYS(mpz_class(ma) > 0); + ASSERT_ALWAYS(mpz_class(mi) < mpz_class(mi+1)); + ASSERT_ALWAYS(mpz_class(mi) < 0); + ASSERT_ALWAYS(mpz_class::factorial(3ll)==6); + ASSERT_ALWAYS(mpz_class::primorial(3ull)==6); +#endif } int
_______________________________________________ gmp-devel mailing list gmp-devel@gmplib.org https://gmplib.org/mailman/listinfo/gmp-devel