diff options
Diffstat (limited to 'stdlib/integers.h')
| -rw-r--r-- | stdlib/integers.h | 63 |
1 files changed, 28 insertions, 35 deletions
diff --git a/stdlib/integers.h b/stdlib/integers.h index ebbe7bb0..4214c2fa 100644 --- a/stdlib/integers.h +++ b/stdlib/integers.h @@ -37,12 +37,12 @@ c_type type_name ## $random(c_type min, c_type max); \ to_attr Range_t type_name ## $to(c_type from, c_type to); \ PUREFUNC Optional ## type_name ## _t type_name ## $from_text(Text_t text); \ - PUREFUNC static INLINE c_type type_name ## $clamped(c_type x, c_type min, c_type max) { \ + MACROLIKE PUREFUNC c_type type_name ## $clamped(c_type x, c_type min, c_type max) { \ return x < min ? min : (x > max ? max : x); \ } \ extern const c_type type_name ## $min, type_name##$max; \ extern const TypeInfo_t type_name ## $info; \ - static INLINE c_type type_name ## $divided_by(c_type D, c_type d) { \ + MACROLIKE c_type type_name ## $divided_by(c_type D, c_type d) { \ c_type q = D/d, r = D%d; \ if (r < 0) { \ if (d > 0) q = q-1; \ @@ -50,7 +50,7 @@ } \ return q; \ } \ - static INLINE c_type type_name ## $modulo(c_type D, c_type d) { \ + MACROLIKE c_type type_name ## $modulo(c_type D, c_type d) { \ c_type r = D%d; \ if (r < 0) { \ if (d > 0) r = r + d; \ @@ -58,7 +58,7 @@ } \ return r; \ } \ - static INLINE c_type type_name ## $modulo1(c_type D, c_type d) { \ + MACROLIKE c_type type_name ## $modulo1(c_type D, c_type d) { \ return type_name ## $modulo(D-1, d) + 1; \ } @@ -136,29 +136,28 @@ Int_t Int$prev_prime(Int_t x); extern const TypeInfo_t Int$info; -static INLINE Int_t Int$clamped(Int_t x, Int_t low, Int_t high) -{ +MACROLIKE PUREFUNC Int_t Int$clamped(Int_t x, Int_t low, Int_t high) { return (Int$compare(&x, &low, &Int$info) <= 0) ? low : (Int$compare(&x, &high, &Int$info) >= 0 ? high : x); } // Fast-path inline versions for the common case where integer arithmetic is // between two small ints. -static INLINE Int_t Int$plus(Int_t x, Int_t y) { +MACROLIKE Int_t Int$plus(Int_t x, Int_t y) { const int64_t z = (int64_t)((uint64_t)x.small + (uint64_t)y.small); if (__builtin_expect(((z|2) == (int32_t)z), 1)) return (Int_t){.small=(z-1)}; return Int$slow_plus(x, y); } -static INLINE Int_t Int$minus(Int_t x, Int_t y) { +MACROLIKE Int_t Int$minus(Int_t x, Int_t y) { const int64_t z = (int64_t)(((uint64_t)x.small ^ 3) - (uint64_t)y.small); if (__builtin_expect(((z & ~2) == (int32_t)z), 1)) return (Int_t){.small=z}; return Int$slow_minus(x, y); } -static INLINE Int_t Int$times(Int_t x, Int_t y) { +MACROLIKE Int_t Int$times(Int_t x, Int_t y) { if (__builtin_expect(((x.small & y.small) & 1) != 0, 1)) { const int64_t z = (x.small>>1) * (y.small>>1); if (__builtin_expect(z == (int32_t)z, 1)) @@ -167,7 +166,7 @@ static INLINE Int_t Int$times(Int_t x, Int_t y) { return Int$slow_times(x, y); } -static INLINE Int_t Int$divided_by(Int_t x, Int_t y) { +MACROLIKE Int_t Int$divided_by(Int_t x, Int_t y) { if (__builtin_expect(((x.small & y.small) & 1) != 0, 1)) { // Euclidean division, see: https://www.microsoft.com/en-us/research/wp-content/uploads/2016/02/divmodnote-letter.pdf const int64_t D = (x.small>>2); @@ -184,7 +183,7 @@ static INLINE Int_t Int$divided_by(Int_t x, Int_t y) { return Int$slow_divided_by(x, y); } -static INLINE Int_t Int$modulo(Int_t x, Int_t y) { +MACROLIKE Int_t Int$modulo(Int_t x, Int_t y) { if (__builtin_expect(((x.small & y.small) & 1) != 0, 1)) { // Euclidean modulus, see: https://www.microsoft.com/en-us/research/wp-content/uploads/2016/02/divmodnote-letter.pdf const int64_t D = (x.small>>2); @@ -199,7 +198,7 @@ static INLINE Int_t Int$modulo(Int_t x, Int_t y) { return Int$slow_modulo(x, y); } -static INLINE Int_t Int$modulo1(Int_t x, Int_t y) { +MACROLIKE Int_t Int$modulo1(Int_t x, Int_t y) { if (__builtin_expect(((x.small & y.small) & 1) != 0, 1)) { // Euclidean modulus, see: https://www.microsoft.com/en-us/research/wp-content/uploads/2016/02/divmodnote-letter.pdf const int64_t D = (x.small>>2)-1; @@ -214,7 +213,7 @@ static INLINE Int_t Int$modulo1(Int_t x, Int_t y) { return Int$slow_modulo1(x, y); } -static INLINE Int_t Int$left_shifted(Int_t x, Int_t y) { +MACROLIKE Int_t Int$left_shifted(Int_t x, Int_t y) { if (__builtin_expect(((x.small & y.small) & 1) != 0, 1)) { const int64_t z = ((x.small>>2) << (y.small>>2))<<2; if (__builtin_expect(z == (int32_t)z, 1)) @@ -223,7 +222,7 @@ static INLINE Int_t Int$left_shifted(Int_t x, Int_t y) { return Int$slow_left_shifted(x, y); } -static INLINE Int_t Int$right_shifted(Int_t x, Int_t y) { +MACROLIKE Int_t Int$right_shifted(Int_t x, Int_t y) { if (__builtin_expect(((x.small & y.small) & 1) != 0, 1)) { const int64_t z = ((x.small>>2) >> (y.small>>2))<<2; if (__builtin_expect(z == (int32_t)z, 1)) @@ -232,41 +231,38 @@ static INLINE Int_t Int$right_shifted(Int_t x, Int_t y) { return Int$slow_right_shifted(x, y); } -static INLINE Int_t Int$bit_and(Int_t x, Int_t y) { +MACROLIKE Int_t Int$bit_and(Int_t x, Int_t y) { const int64_t z = x.small & y.small; if (__builtin_expect((z & 1) == 1, 1)) return (Int_t){.small=z}; return Int$slow_bit_and(x, y); } -static INLINE Int_t Int$bit_or(Int_t x, Int_t y) { +MACROLIKE Int_t Int$bit_or(Int_t x, Int_t y) { if (__builtin_expect(((x.small & y.small) & 1) == 1, 1)) return (Int_t){.small=(x.small | y.small)}; return Int$slow_bit_or(x, y); } -static INLINE Int_t Int$bit_xor(Int_t x, Int_t y) { +MACROLIKE Int_t Int$bit_xor(Int_t x, Int_t y) { if (__builtin_expect(((x.small & y.small) & 1) == 1, 1)) return (Int_t){.small=(x.small ^ y.small) | 1}; return Int$slow_bit_xor(x, y); } -static INLINE Int_t Int$negated(Int_t x) -{ +MACROLIKE Int_t Int$negated(Int_t x) { if (__builtin_expect((x.small & 1), 1)) return (Int_t){.small=(~x.small) ^ 3}; return Int$slow_negated(x); } -static INLINE Int_t Int$negative(Int_t x) -{ +MACROLIKE Int_t Int$negative(Int_t x) { if (__builtin_expect((x.small & 1), 1)) return (Int_t){.small=((-((x.small)>>2))<<2) | 1}; return Int$slow_negative(x); } -static INLINE bool Int$is_negative(Int_t x) -{ +MACROLIKE PUREFUNC bool Int$is_negative(Int_t x) { if (__builtin_expect((x.small & 1), 1)) return x.small < 0; return Int$compare_value(x, I_small(0)) < 0; @@ -274,7 +270,7 @@ static INLINE bool Int$is_negative(Int_t x) // Conversion functions: -static INLINE Int_t Int64_to_Int(int64_t i) +MACROLIKE Int_t Int64_to_Int(int64_t i) { int64_t z = i<<2; if (__builtin_expect(z == (int32_t)z, 1)) @@ -288,18 +284,15 @@ static INLINE Int_t Int64_to_Int(int64_t i) #define Int16_to_Int(i) Int64_to_Int(i) #define Int8_to_Int(i) Int64_to_Int(i) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Winline" -PUREFUNC static INLINE Int64_t Int_to_Int64(Int_t i, bool truncate) { +MACROLIKE PUREFUNC Int64_t Int_to_Int64(Int_t i, bool truncate) { if (__builtin_expect(i.small & 1, 1)) return (int64_t)(i.small >> 2); if (__builtin_expect(!truncate && !mpz_fits_slong_p(*i.big), 0)) fail("Integer is too big to fit in a 64-bit integer!"); return mpz_get_si(*i.big); } -#pragma GCC diagnostic pop -PUREFUNC static INLINE Int32_t Int_to_Int32(Int_t i, bool truncate) { +MACROLIKE PUREFUNC Int32_t Int_to_Int32(Int_t i, bool truncate) { int64_t i64 = Int_to_Int64(i, truncate); int32_t i32 = (int32_t)i64; if (__builtin_expect(i64 != i32 && !truncate, 0)) @@ -307,7 +300,7 @@ PUREFUNC static INLINE Int32_t Int_to_Int32(Int_t i, bool truncate) { return i32; } -PUREFUNC static INLINE Int16_t Int_to_Int16(Int_t i, bool truncate) { +MACROLIKE PUREFUNC Int16_t Int_to_Int16(Int_t i, bool truncate) { int64_t i64 = Int_to_Int64(i, truncate); int16_t i16 = (int16_t)i64; if (__builtin_expect(i64 != i16 && !truncate, 0)) @@ -315,7 +308,7 @@ PUREFUNC static INLINE Int16_t Int_to_Int16(Int_t i, bool truncate) { return i16; } -PUREFUNC static INLINE Int8_t Int_to_Int8(Int_t i, bool truncate) { +MACROLIKE PUREFUNC Int8_t Int_to_Int8(Int_t i, bool truncate) { int64_t i64 = Int_to_Int64(i, truncate); int8_t i8 = (int8_t)i64; if (__builtin_expect(i64 != i8 && !truncate, 0)) @@ -323,14 +316,14 @@ PUREFUNC static INLINE Int8_t Int_to_Int8(Int_t i, bool truncate) { return i8; } -PUREFUNC static INLINE Int_t Num_to_Int(double n) +MACROLIKE PUREFUNC Int_t Num_to_Int(double n) { mpz_t result; mpz_init_set_d(result, n); return Int$from_mpz(result); } -PUREFUNC static INLINE double Int_to_Num(Int_t i) +MACROLIKE PUREFUNC double Int_to_Num(Int_t i) { if (__builtin_expect(i.small & 1, 1)) return (double)(i.small >> 2); @@ -341,7 +334,7 @@ PUREFUNC static INLINE double Int_to_Num(Int_t i) #define Int_to_Num32(i) (Num32_t)Int_to_Num(i) #define CONVERSION_FUNC(hi, lo) \ - PUREFUNC static INLINE int##lo##_t Int##hi##_to_Int##lo(int##hi##_t i, bool truncate) { \ + MACROLIKE PUREFUNC int##lo##_t Int##hi##_to_Int##lo(int##hi##_t i, bool truncate) { \ if (__builtin_expect(!truncate && (i != (int##lo##_t)i), 0)) \ fail("Cannot truncate the Int" #hi " %ld to an Int" #lo, (int64_t)i); \ return (int##lo##_t)i; \ @@ -358,7 +351,7 @@ CONVERSION_FUNC(16, 8) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wfloat-equal" #define CONVERSION_FUNC(num, int_type) \ - PUREFUNC static INLINE int_type##_t num##_to_##int_type(num##_t n, bool truncate) { \ + MACROLIKE PUREFUNC int_type##_t num##_to_##int_type(num##_t n, bool truncate) { \ num##_t rounded = (num##_t)round((double)n); \ if (__builtin_expect(!truncate && (num##_t)(int_type##_t)rounded != rounded, 0)) \ fail("Cannot truncate the " #num " %g to an " #int_type, (double)rounded); \ |
