typedef unsigned _BitInt(1) bool1; typedef unsigned _BitInt(2) bool2; typedef unsigned _BitInt(4) bool4; typedef unsigned _BitInt(8) bool8; typedef unsigned _BitInt(1) u1; typedef unsigned _BitInt(2) u2; typedef unsigned _BitInt(4) u4; typedef unsigned _BitInt(8) u8; typedef unsigned _BitInt(16) u16; typedef unsigned _BitInt(32) u32; typedef unsigned _BitInt(64) u64; typedef unsigned _BitInt(128) u128; typedef signed _BitInt(2) s2; typedef signed _BitInt(4) s4; typedef signed _BitInt(8) s8; typedef signed _BitInt(16) s16; typedef signed _BitInt(32) s32; typedef signed _BitInt(64) s64; typedef signed _BitInt(128) s128; typedef float f32; typedef double f64; #if POINTER_32 typedef u32 uaddr; typedef s32 saddr; typedef u32 uword; typedef s32 sword; #else typedef u64 uaddr; typedef s64 saddr; typedef u64 uword; typedef s64 sword; #endif static_assert(sizeof(uaddr) == sizeof(void*), "uaddr was not equal to a pointer"); #define auto __auto_type typedef struct { u8* data; uword count; } string; #define string_const(S) (string){ .data = (S), .count = count_of((S)) } #define string_from(P) (string){ .data = (P), .count = cast(uword, strlen((P))) } #define string_from_count(P, C) (string){ .data = (P), .count = (C) } #define size_of(T) cast(uword, sizeof(T)) #define ssize_of(T) cast(sword, sizeof(T)) #define align_of(T) cast(uword, alignof(T)) #define salign_of(T) cast(sword, alignof(T)) #define count_of(P) (size_of(P) / size_of((P)[0])) // Thanks azmr #define cast(to_type, expr) ((to_type)(expr)) #define chkcast(to_type, from_type, expr) _Generic(expr, from_type: (to_type)(expr)) #define ptrcast(to_type, from_type, expr) _Generic(expr, from_type: (to_type)(uintptr_t)(expr)) #define bitcast(to_type, from_type, expr) (((union { from_type from; to_type to; }){_Generic(expr, from_type: expr)}).to) #define procedure(ret_type, ...) typeof(ret_type(__VA_ARGS__))* #define closure(ret_type, ...) typeof(ret_type(__VA_ARGS__))^ #include #define capture __block // allows a variable to be mutably captured by a closure (will be moved to the heap if needed) #define persist Block_copy // moves a closure to the heap (reference counted) so it can persist outside of its local stack frame #define unpersist Block_release // frees a closure (or decrements its reference count) typedef closure(void, void) __scope_exit; static inline void __scope_exit_run(__scope_exit *blk) { (*blk)(); } #define __concat__2(a, b) a##b #define __concat(a, b) __concat__2(a, b) #define scope_exit \ __attribute__((cleanup(__scope_exit_run), unused)) \ __scope_exit __concat(_defer_, __LINE__) = ^void(void)