Fix header inline functions to use extern inline
and some GCC magic
This commit is contained in:
parent
a0178a1e0c
commit
bdca4fc6e1
@ -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); \
|
||||
|
@ -30,7 +30,7 @@ double Num$nan(Text_t tag);
|
||||
double Num$random(void);
|
||||
CONSTFUNC double Num$mix(double amount, double x, double y);
|
||||
OptionalNum_t Num$from_text(Text_t text);
|
||||
CONSTFUNC static inline double Num$clamped(double x, double low, double high) {
|
||||
MACROLIKE CONSTFUNC double Num$clamped(double x, double low, double high) {
|
||||
return (x <= low) ? low : (x >= high ? high : x);
|
||||
}
|
||||
extern const TypeInfo_t Num$info;
|
||||
@ -49,7 +49,7 @@ float Num32$random(void);
|
||||
CONSTFUNC float Num32$mix(float amount, float x, float y);
|
||||
OptionalNum32_t Num32$from_text(Text_t text);
|
||||
float Num32$nan(Text_t tag);
|
||||
CONSTFUNC static inline float Num32$clamped(float x, float low, float high) {
|
||||
MACROLIKE CONSTFUNC float Num32$clamped(float x, float low, float high) {
|
||||
return (x <= low) ? low : (x >= high ? high : x);
|
||||
}
|
||||
extern const TypeInfo_t Num32$info;
|
||||
|
@ -68,7 +68,7 @@ typedef struct siphash siphash;
|
||||
HALF_ROUND(v0,v1,v2,v3,13,16); \
|
||||
HALF_ROUND(v2,v1,v0,v3,17,21);
|
||||
|
||||
static INLINE void siphashinit (siphash *sh, size_t src_sz) {
|
||||
MACROLIKE void siphashinit (siphash *sh, size_t src_sz) {
|
||||
const uint64_t k0 = TOMO_HASH_KEY[0];
|
||||
const uint64_t k1 = TOMO_HASH_KEY[1];
|
||||
sh->b = (uint64_t)src_sz << 56;
|
||||
@ -77,13 +77,13 @@ static INLINE void siphashinit (siphash *sh, size_t src_sz) {
|
||||
sh->v2 = k0 ^ 0x6c7967656e657261ULL;
|
||||
sh->v3 = k1 ^ 0x7465646279746573ULL;
|
||||
}
|
||||
static INLINE void siphashadd64bits (siphash *sh, const uint64_t in) {
|
||||
MACROLIKE void siphashadd64bits (siphash *sh, const uint64_t in) {
|
||||
const uint64_t mi = in;
|
||||
sh->v3 ^= mi;
|
||||
DOUBLE_ROUND(sh->v0,sh->v1,sh->v2,sh->v3);
|
||||
sh->v0 ^= mi;
|
||||
}
|
||||
static INLINE uint64_t siphashfinish_last_part (siphash *sh, uint64_t t) {
|
||||
MACROLIKE uint64_t siphashfinish_last_part (siphash *sh, uint64_t t) {
|
||||
sh->b |= t;
|
||||
sh->v3 ^= sh->b;
|
||||
DOUBLE_ROUND(sh->v0,sh->v1,sh->v2,sh->v3);
|
||||
@ -101,7 +101,7 @@ union SipHash64_union {
|
||||
uint32_t u32;
|
||||
uint8_t u8[8];
|
||||
};
|
||||
static INLINE uint64_t siphashfinish (siphash *sh, const uint8_t *src, size_t src_sz) {
|
||||
MACROLIKE uint64_t siphashfinish (siphash *sh, const uint8_t *src, size_t src_sz) {
|
||||
union SipHash64_union t = { 0 };
|
||||
switch (src_sz) {
|
||||
/* Falls through */
|
||||
|
@ -9,6 +9,7 @@
|
||||
|
||||
#include "datatypes.h"
|
||||
#include "integers.h"
|
||||
#include "util.h"
|
||||
|
||||
typedef struct {
|
||||
Text_t text;
|
||||
@ -56,7 +57,7 @@ Text_t Text$repeat(Text_t text, Int_t count);
|
||||
int32_t Text$get_grapheme_fast(TextIter_t *state, int64_t index);
|
||||
uint32_t Text$get_main_grapheme_fast(TextIter_t *state, int64_t index);
|
||||
|
||||
static INLINE int32_t Text$get_grapheme(Text_t text, int64_t index)
|
||||
MACROLIKE int32_t Text$get_grapheme(Text_t text, int64_t index)
|
||||
{
|
||||
TextIter_t state = {text, 0, 0};
|
||||
return Text$get_grapheme_fast(&state, index);
|
||||
|
@ -37,6 +37,12 @@
|
||||
#define INLINE inline __attribute__ ((always_inline))
|
||||
#endif
|
||||
|
||||
// GCC lets you define macro-like functions which are always inlined and never
|
||||
// compiled using this combination of flags. See: https://gcc.gnu.org/onlinedocs/gcc/Inline.html
|
||||
#ifndef MACROLIKE
|
||||
#define MACROLIKE extern inline __attribute__((gnu_inline, always_inline))
|
||||
#endif
|
||||
|
||||
__attribute__((format(printf, 1, 2)))
|
||||
char *heap_strf(const char *fmt, ...);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user