#ifndef GUF_COMMON_UTILS_H #define GUF_COMMON_UTILS_H #include "guf_assert.h" #include // The GUFCAT/GUF_TOK_CAT indirection is necessary because the ## operation alone does not evaluate the macro arguments. #define GUF_TOK_CAT(a, b) a##b #define GUFCAT(a, b) GUF_TOK_CAT(a, b) #define GUF_FOREACH(CNT_PTR, CNT_TYPE, IT_NAME) for (GUFCAT(CNT_TYPE, _iter) IT_NAME = GUFCAT(CNT_TYPE, _begin)(CNT_PTR); IT_NAME.cur != IT_NAME.end; IT_NAME = IT_NAME.next(&IT_NAME, 1)) #define GUF_STATIC_BUF_SIZE(BUF) (sizeof((BUF)) / (sizeof((BUF)[0]))) #define GUF_ABS(X) ((X) >= 0 ? (X) : -(X)) #define GUF_MIN(X, Y) ((X) <= (Y) ? (X) : (Y)) #define GUF_MAX(X, Y) ((X) >= (Y) ? (X) : (Y)) #define GUF_CLAMP(X, MIN, MAX) GUF_MAX(GUF_MIN((X), (MAX)), (MIN)) static inline int guf_abs_int(int x) {if (x >= 0) {return x;} GUF_ASSERT_RELEASE(x > INT_MIN ); return -x;} static inline long guf_abs_lng(long x) {if (x >= 0) {return x;} GUF_ASSERT_RELEASE(x > LONG_MIN ); return -x;} static inline int8_t guf_abs_i8 (int8_t x) {if (x >= 0) {return x;} GUF_ASSERT_RELEASE(x > INT8_MIN ); return -x;} static inline int16_t guf_abs_i16(int16_t x) {if (x >= 0) {return x;} GUF_ASSERT_RELEASE(x > INT16_MIN); return -x;} static inline int32_t guf_abs_i32(int32_t x) {if (x >= 0) {return x;} GUF_ASSERT_RELEASE(x > INT32_MIN); return -x;} static inline int64_t guf_abs_i64(int64_t x) {if (x >= 0) {return x;} GUF_ASSERT_RELEASE(x > INT64_MIN); return -x;} static inline bool guf_is_mul_overflow_size_t(size_t a, size_t b) { size_t c = a * b; return a != 0 && ((c / a) != b); } static inline size_t guf_safe_mul_size_t(size_t a, size_t b) { GUF_ASSERT_RELEASE(!guf_is_mul_overflow_size_t(a, b)); return a * b; } static inline bool guf_is_safe_size_calc(ptrdiff_t count, ptrdiff_t sizeof_elem) { if (count < 0 || sizeof_elem <= 0) { return false; } size_t size = guf_safe_mul_size_t(count, sizeof_elem); return size <= PTRDIFF_MAX; } static inline ptrdiff_t guf_safe_size_calc(ptrdiff_t count, ptrdiff_t sizeof_elem) { GUF_ASSERT_RELEASE(count >= 0); GUF_ASSERT_RELEASE(sizeof_elem > 0); size_t size = guf_safe_mul_size_t(count, sizeof_elem); GUF_ASSERT_RELEASE(size <= PTRDIFF_MAX); return size; } static inline bool guf_is_big_endian(void) { unsigned i = 1; const char *bytes = (const char*)&i; return bytes[0] != 1; } #endif