X-Git-Url: https://git.distorted.org.uk/~mdw/catacomb/blobdiff_plain/0f00dc4c8eb47e67bc0f148c2dd109f73a451e0a..HEAD:/math/mpint.h diff --git a/math/mpint.h b/math/mpint.h index 7867f6a4..a5ab3dfe 100644 --- a/math/mpint.h +++ b/math/mpint.h @@ -36,12 +36,21 @@ #include +#include + #ifndef CATACOMB_MP_H # include "mp.h" #endif /*----- Generic translation macros ----------------------------------------*/ +/* --- Warning damage control --- * + * + * GCC (at least) isn't clever enough to work out that the division in + * @MP_FROMINT@ is actually safe (since it will only be executed if @_i > + * MPW_MAX@, which would prove that @(type)MPW_MAX + 1 != 0@). + */ + /* --- @MP_FROMINT@ --- * * * Arguments: @d@ = destination multiprecision integer @@ -68,10 +77,15 @@ MP_ENSURE(_d, _sz); \ } \ _d->v[_o++] = MPW(_i); \ - if (_i <= MPW_MAX) \ + if (MUFFLE_WARNINGS_EXPR( \ + CLANG_WARNING("-Wtautological-constant-out-of-range-compare"), \ + _i <= MPW_MAX)) \ break; \ else \ - _i /= (type)MPW_MAX + 1; \ + MUFFLE_WARNINGS_STMT(GCC_WARNING("-Wdiv-by-zero") \ + CLANG_WARNING("-Wdivision-by-zero"), { \ + _i /= (type)MPW_MAX + 1; \ + }); \ } \ } else { \ _d->f |= MP_NEG; \ @@ -81,10 +95,15 @@ MP_ENSURE(_d, _sz); \ } \ _d->v[_o++] = MPW(-_i); \ - if (_i >= -MPW_MAX) \ + if (MUFFLE_WARNINGS_EXPR( \ + CLANG_WARNING("-Wtautological-constant-out-of-range-compare"), \ + _i >= -MPW_MAX)) \ break; \ else \ - _i /= (type)MPW_MAX + 1; \ + MUFFLE_WARNINGS_STMT(GCC_WARNING("-Wdiv-by-zero") \ + CLANG_WARNING("-Wdivision-by-zero"), { \ + _i /= (type)MPW_MAX + 1; \ + }); \ } \ } \ \ @@ -120,7 +139,7 @@ /* --- Do all the arithmetic in negative numbers --- */ \ \ while (_v < _vl && _max > 0) { \ - _i -= *_v << _s; \ + _i -= (type)*_v << _s; \ _s += MPW_BITS; \ _v++; \ _max /= (mpd)MPW_MAX + 1; \ @@ -132,6 +151,49 @@ /*----- Functions provided ------------------------------------------------*/ +/* --- Build up the list of conversions to be supplied --- */ + +#ifdef ULLONG_MAX +# ifndef LLONG_MAX +# define LLONG_MAX LONG_LONG_MAX +# endif +# define MPINT_CONV_LLONG(_) \ + _(llong, long long, LLONG_MAX) \ + _(ullong, unsigned long long, ULLONG_MAX) +#else +# define MPINT_CONV_LLONG(_) +#endif + +#ifdef INTMAX_MAX +# define MPINT_CONV_INTMAX(_) \ + _(intmax, intmax_t, INTMAX_MAX) \ + _(uintmax, uintmax_t, UINTMAX_MAX) +#else +# define MPINT_CONV_INTMAX(_) +#endif + +#ifdef HAVE_UINT64 +# define MPINT_CONV_U64(_) _(uint64, uint64, MASK64) +#else +# define MPINT_CONV_U64(_) +#endif + +#define MPINT_CONVERSIONS(_) \ + _(short, short, SHRT_MAX) \ + _(ushort, unsigned short, USHRT_MAX) \ + _(int, int, INT_MAX) \ + _(uint, unsigned, UINT_MAX) \ + _(long, long, LONG_MAX) \ + _(ulong, unsigned long, ULONG_MAX) \ + MPINT_CONV_LLONG(_) \ + _(uint8, uint8, MASK8) \ + _(uint16, uint16, MASK16) \ + _(uint24, uint24, MASK24) \ + _(uint32, uint32, MASK32) \ + MPINT_CONV_U64(_) \ + MPINT_CONV_INTMAX(_) \ + _(sizet, size_t, (size_t)-1) + /* --- @mp_fromINT@ --- * * * Arguments: @mp *d@ = pointer to destination multiprecision integer @@ -142,17 +204,9 @@ * Use: Converts a standard C integer to a multiprecision integer. */ -#define mp_fromINT(name, type) \ - extern mp *mp_from##name(mp */*d*/, type /*i*/) - -mp_fromINT(short, short); -mp_fromINT(ushort, unsigned short); -mp_fromINT(int, int); -mp_fromINT(uint, unsigned); -mp_fromINT(uint32, uint32); -mp_fromINT(long, long); -mp_fromINT(ulong, unsigned long); - +#define mp_fromINT(name, type, max) \ + extern mp *mp_from##name(mp */*d*/, type /*i*/); +MPINT_CONVERSIONS(mp_fromINT) #undef mp_fromINT /* --- @mp_toINT@ --- * @@ -168,17 +222,9 @@ mp_fromINT(ulong, unsigned long); * type is signed, the behaviour is undefined. */ -#define mp_toINT(name, type) \ - extern type mp_to##name(const mp */*m*/) - -mp_toINT(short, short); -mp_toINT(ushort, unsigned short); -mp_toINT(int, int); -mp_toINT(uint, unsigned); -mp_toINT(uint32, uint32); -mp_toINT(long, long); -mp_toINT(ulong, unsigned long); - +#define mp_toINT(name, type, max) \ + extern type mp_to##name(const mp */*m*/); +MPINT_CONVERSIONS(mp_toINT) #undef mp_toINT /*----- That's all, folks -------------------------------------------------*/