#ifndef _AL_LIB_H #define _AL_LIB_H #include "types.h" #define AL_USE_STDLIB 1 #define AL_FORCE_DISABLE_OUTPUT 0 #if defined(__clang__) || defined(__GNUC__) #define AL_UNUSED_FUNCTION_PUSH \ _Pragma("GCC diagnostic push") \ _Pragma("GCC diagnostic ignored \"-Wunused-function\"") #define AL_UNUSED_FUNCTION_POP \ _Pragma("GCC diagnostic pop") #else #define AL_UNUSED_FUNCTION_PUSH #define AL_UNUSED_FUNCTION_POP #endif #if AL_USE_STDLIB #include #include #include #include #include #include #include #include void al_malloc_init(void); void al_malloc_close(void); void *al_malloc(size_t n); void *al_calloc(size_t n, size_t size); void *al_realloc(void *ptr, size_t n); void al_free(void *ptr); #ifdef AL_HAVE_POSIX_MEMALIGN int al_posix_memalign(void **ptr, size_t alignment, size_t n); #endif void al_malloc_stats(u32 *current, u32 *peak, u32 *total); void al_set_alloc(void *(*malloc_func)(size_t), void *(*calloc_func)(size_t, size_t), void *(*realloc_func)(void *, size_t), void (*free_func)(void *)); #define al_memcpy memcpy #define al_memmove memmove #define al_memchr memchr #define al_memcmp memcmp #define al_memset memset #define al_bzero bzero #define al_strlen strlen #define al_sprintf sprintf #ifdef _DEBUG_ #define al_assert assert #else #define al_assert(expr) do { (void)sizeof(expr); } while (0) // NOLINT(bugprone-sizeof-expression) #endif #define al_assert_and_return(expr) do { \ al_assert(expr); \ return false; \ } while(0) #define al_alloc_object(type) (type *)al_calloc(1, sizeof(type)) AL_UNUSED_FUNCTION_PUSH static inline s32 al_printf(const char *fmt, ...) { #if AL_FORCE_DISABLE_OUTPUT return 0; #else va_list args; va_start(args, fmt); s32 ret = vprintf(fmt, args); va_end(args); return ret; #endif } static inline s32 al_vprintf(const char *fmt, va_list args) { #if AL_FORCE_DISABLE_OUTPUT return 0; #else s32 ret = vprintf(fmt, args); return ret; #endif } static inline void *al_memrchr(const void *s, s32 c, size_t n) { const u8 *src = (const u8 *)s + n - 1; u8 d = (u8)c; while (n--) { if (*src == d) return (void *)src; src--; } return NULL; } AL_UNUSED_FUNCTION_POP #endif #ifndef LIKELY #ifdef AL_HAVE_BUILTIN_EXPECT #define LIKELY(x) __builtin_expect((x), 1) #else #define LIKELY(x) x #endif #endif #ifndef UNLIKELY #ifdef AL_HAVE_BUILTIN_EXPECT #define UNLIKELY(x) __builtin_expect((x), 0) #else #define UNLIKELY(x) x #endif #endif #if __GNUC__ >= 3 #define AL_MAX(a, b) \ ({ \ __typeof__(a) _a = a; \ __typeof__(b) _b = b; \ _a > _b ? _a : _b; \ }) #define AL_MIN(a, b) \ ({ \ __typeof__(a) _a = a; \ __typeof__(b) _b = b; \ _a < _b ? _a : _b; \ }) #else #define AL_MAX(x, y) (((x) > (y)) ? (x) : (y)) #define AL_MIN(x, y) (((x) < (y)) ? (x) : (y)) #endif #define AL_CLAMP(n, lo, hi) AL_MIN(hi, AL_MAX(lo, n)) #define AL_SWAP(a, b, type) do { \ type tmp = a; \ a = b; \ b = tmp; \ } while (0) #define AL_ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0])) #define AL_BOOLSTR(b) ((b) ? "true" : "false") #ifndef _MSVC_ #define __al_thread __thread #else #define __al_thread __declspec(thread) #endif #define __al_fallthrough __attribute__((fallthrough)) #if __has_attribute(__counted_by__) #define __al_counted_by(member) __attribute__((__counted_by__(member))) #else #define __al_counted_by(member) #endif #if __has_attribute(__sized_by__) #define __al_sized_by(member) __attribute__((__sized_by__(member))) #else #define __al_sized_by(member) #endif AL_UNUSED_FUNCTION_PUSH static inline size_t al_next_power_of_two(size_t n) { n--; n |= n >> 1; n |= n >> 2; n |= n >> 4; n |= n >> 8; return ++n; } static inline bool al_isspace(char c) { return (c == ' ' || c == '\f' || c == '\n' || c == '\r' || c == '\t' || c == '\v'); } static inline u32 al_u32_inc_wrap(u32 v) { return (v == UINT32_MAX) ? 0 : v + 1; } static inline u16 al_u16_inc_wrap(u16 v) { return (v == UINT16_MAX) ? 0 : v + 1; } static inline u32 al_u32_add_wrap(u32 v, u32 add) { return (v > UINT32_MAX - add) ? (add - (UINT32_MAX - v)) : v + add; } static inline u16 al_u16_add_wrap(u16 v, u16 add) { return (v > UINT16_MAX - add) ? (add - (UINT16_MAX - v)) : v + add; } AL_UNUSED_FUNCTION_POP extern size_t al_page_size; extern size_t al_grow_limit; void al_set_page_size(size_t size); #endif // _AL_LIB_H