#ifndef _pre_h_ #define _pre_h_ /* Prelude file, containing some useful macros and types. */ #include #include #include typedef int8_t i8; typedef uint8_t u8; typedef int16_t i16; typedef uint16_t u16; typedef int32_t i32; typedef uint32_t u32; typedef int64_t i64; typedef uint64_t u64; typedef float f32; typedef double f64; typedef uintptr_t uptr; typedef ptrdiff_t isize; typedef size_t usize; typedef _Bool bool; typedef struct { u8 *s; isize len; } Str; #define true ((bool)1) #define false ((bool)0) #define nil ((void *)0) #define U64_MAX ((u64)-1) #define Optional(T) struct {T val; bool ok;} #define Some(T, v) (T){v, true} #define None(T) (T){.ok = false} /* Meant for use with stb_ds */ #define Vec(T) T * #define HashMap(K, V) struct { K key; V value; } #define HashMapStr(V) struct { char *key; V value; } /* Length of an array */ #define countof(arr) (isize)(sizeof(arr) / sizeof(*(arr))) /* Length of string literal */ #define lengthof(s) (countof(s) - 1) #define foreach(val, arr) for(__typeof__(*(arr)) *__p = (arr), (val) = *__p; __p < (arr)+(arrlen((arr))); (val) = *(__p++)) #define foreach_getindex(val, arr) (&(val) - (arr)) /* Useful integer operations good to have. */ #define max(x, y) ((x) > (y) ? (x) : (y)) #define min(x, y) ((x) < (y) ? (x) : (y)) #define clamp(x, lo, hi) max(lo, min(x, hi)) #define BitPos(pos) (1 << (pos)) #if defined(__GNUC__) || defined(__clang__) # define debugtrap() __builtin_trap() # define unreachable() __builtin_unreachable() #else /* not optimal... */ # define debugtrap() abort() # define unreachable() abort() #endif #ifndef NDEBUG # if defined (__GNUC__) || defined(__clang__) # define Assert(pred) if (!(pred)) { __builtin_trap(); } # else # define Assert(pred) if (!(pred)) { *(volatile int *)0 = 0; } # endif # define trace(...) do { \ fprintf(stderr, "%s:%-5i", __FILE__, __LINE__); \ fprintf(stderr, __VA_ARGS__); \ } while (0) #else # define Assert(pred) # define trace(...) #endif /* Creates a `Str` from a string literal */ #define Sl(s) ((Str){ (u8 *)s, (isize)lengthof(s) }) /* Creates a `Str` from a C string. */ #define Str_from_c(s) ((Str){ (u8 *)s, (isize)(s != nil ? strlen(s) : 0) }) #define Str_empty(s) ((s).len == 0) #define Str_default(s, sor) (!Str_empty(s) ? (s) : (sor)) Str Str_from_buf(u8 *buf, isize len); char * Str_to_c(Str s); bool Str_equal(Str s1, Str s2); Str Str_new(const u8 *data, isize len); Str Strafmt(const char *fmt, ...); #endif