264 lines
9.4 KiB
C
264 lines
9.4 KiB
C
typedef uintptr_t usize;
|
|
typedef uint64_t u64;
|
|
typedef uint32_t u32;
|
|
typedef uint16_t u16;
|
|
typedef uint8_t u8;
|
|
|
|
typedef intptr_t isize;
|
|
typedef int64_t i64;
|
|
typedef int32_t i32;
|
|
typedef int16_t i16;
|
|
typedef int8_t i8;
|
|
|
|
typedef int64_t b64;
|
|
typedef int32_t b32;
|
|
typedef int16_t b16;
|
|
typedef int8_t b8;
|
|
|
|
typedef float f32;
|
|
typedef double f64;
|
|
|
|
#ifndef true
|
|
#define true 1
|
|
#endif
|
|
#ifndef false
|
|
#define false 0
|
|
#endif
|
|
|
|
#define fn
|
|
#define gb
|
|
#define locl
|
|
|
|
#if PLATFORM_WASM
|
|
#define gb_wasm_export __attribute__((visibility("default")))
|
|
#define fn_wasm_export __attribute__((visibility("default")))
|
|
#define fn_wasm_import
|
|
#endif
|
|
|
|
#define U64_TO_F64(x) (((union { f64 f; u64 i; }) { .i = (x) }).f)
|
|
#define U32_TO_F32(x) (((union { f32 f; u32 i; }) { .i = (x) }).f)
|
|
#define F64_TO_U64(x) (((union { f64 f; u64 i; }) { .f = (x) }).i)
|
|
#define F32_TO_U32(x) (((union { f32 f; u32 i; }) { .f = (x) }).i)
|
|
|
|
#define MIN(x,y) ((x) > (y) ? (y) : (x))
|
|
#define MAX(x,y) ((x) > (y) ? (x) : (y))
|
|
|
|
#define CLAMP_TOP(A,X) MIN(A,X)
|
|
#define CLAMP_BOT(X,B) MAX(X,B)
|
|
#define CLAMP(x,a,b) (((x)<(a))?(a):((x)>(b))?(b):(x))
|
|
|
|
#define set_bit(x) (1ULL << (x))
|
|
#define lengthof(x) (sizeof((x))/sizeof((x)[0]))
|
|
#ifndef offsetof
|
|
#define offsetof(st, m) ((usize)&(((st *)0)->m))
|
|
#endif
|
|
#define expect(x) if (!(x))
|
|
#define unused(x) (void)(x)
|
|
|
|
#define kib(x) (1024ULL * (x##ULL))
|
|
#define mib(x) (1024ULL * kib(x))
|
|
#define gib(x) (1024ULL * mib(x))
|
|
#define thousand(n) ((n)*1000)
|
|
#define million(n) ((n)*1000000)
|
|
#define billion(n) ((n)*1000000000)
|
|
|
|
#define zero_struct(x) memory_zero((x), sizeof(*(x)))
|
|
|
|
|
|
#define defer_if(begin, cond_end) for (b32 PASTE(_i_, __LINE__) = !!begin; PASTE(_i_, __LINE__); PASTE(_i_, __LINE__) = (cond_end, 0))
|
|
#define defer_block(begin, end) for (i32 PASTE(_i_, __LINE__) = (begin, 0); !PASTE(_i_, __LINE__); PASTE(_i_, __LINE__) += (end, 1))
|
|
|
|
#define stack_t(type, size) struct { type data[size]; i32 len; }
|
|
#define STACK_CAP(stack) (lengthof((stack).data))
|
|
#define STACK_EMPTY(stack) ((stack).len == 0)
|
|
#define STACK_FULL(stack) ((stack).len == STACK_CAP(stack))
|
|
#define STACK_PUSH(stack, ...) (assert(!STACK_FULL(stack)), (stack).data[(stack).len++] = __VA_ARGS__)
|
|
#define STACK_POP(stack) (assert(!STACK_EMPTY(stack)), (stack).data[--(stack).len])
|
|
#define STACK_TOP(stack) (assert(!STACK_EMPTY(stack)), (stack).data[((stack).len-1)])
|
|
|
|
#define STRINGIFY_(S) #S
|
|
#define STRINGIFY(S) STRINGIFY_(S)
|
|
#define PASTE_(a, b) a##b
|
|
#define PASTE(a, b) PASTE_(a, b)
|
|
#define SWAP(t, a, b) do { t PASTE(temp__, __LINE__) = a; a = b; b = PASTE(temp__, __LINE__); } while(0)
|
|
#define CODE(...) #__VA_ARGS__
|
|
|
|
#if PLATFORM_CL || (PLATFORM_CLANG && PLATFORM_WINDOWS)
|
|
#pragma section(".rdata$", read)
|
|
#define gb_read_only __declspec(allocate(".rdata$"))
|
|
#elif PLATFORM_CLANG && PLATFORM_LINUX
|
|
#define gb_read_only __attribute__((section(".rodata")))
|
|
#else
|
|
#define gb_read_only
|
|
#endif
|
|
|
|
#if PLATFORM_CL
|
|
#define fn_inline __forceinline
|
|
#elif PLATFORM_CLANG || PLATFORM_GCC
|
|
#define fn_inline __attribute__((always_inline))
|
|
#else
|
|
#define fn_inline
|
|
#endif
|
|
|
|
#ifndef FILE_AND_LINE_GCC_FORMAT
|
|
#define FILE_AND_LINE __FILE__"("STRINGIFY(__LINE__)")"
|
|
#else
|
|
#define FILE_AND_LINE __FILE__":"STRINGIFY(__LINE__)
|
|
#endif
|
|
|
|
#if PLATFORM_CL
|
|
#define debug__break() __debugbreak()
|
|
#else
|
|
#define debug__break() __builtin_trap()
|
|
#endif
|
|
#define debug_break() (debug__break(), 0)
|
|
|
|
#if PLATFORM_WASM
|
|
#define gb_thread
|
|
#elif PLATFORM_GCC | PLATFORM_CLANG
|
|
#define gb_thread __thread
|
|
#elif PLATFORM_CL
|
|
#define gb_thread __declspec(thread)
|
|
#else
|
|
#define gb_thread _Thread_local
|
|
#endif
|
|
|
|
#if PLATFORM_CL
|
|
#pragma warning(disable: 4116)
|
|
#endif
|
|
|
|
// Single linked list Queue
|
|
#define SLLQ_APPEND_EX(f, l, n, next) \
|
|
do { \
|
|
assert((n)->next == NULL); \
|
|
if ((f) == 0) { \
|
|
(f) = (l) = (n); \
|
|
} else { \
|
|
(l) = (l)->next = (n); \
|
|
} \
|
|
} while (0)
|
|
#define SLLQ_APPEND(f, l, n) SLLQ_APPEND_EX(f, l, n, next)
|
|
|
|
#define SLLQ_PREPEND_EX(f, l, n, next) \
|
|
do { \
|
|
assert((n)->next == NULL); \
|
|
if ((f) == 0) { \
|
|
(f) = (l) = (n); \
|
|
} else { \
|
|
(n)->next = (f); \
|
|
(f) = (n); \
|
|
} \
|
|
} while (0)
|
|
#define SLLQ_PREPEND(f, l, n) SLLQ_PREPEND_EX(f, l, n, next)
|
|
|
|
#define SLLQ_REMOVE_FIRST_EX(f, l, next) \
|
|
do { \
|
|
if ((f) == (l)) { \
|
|
(f) = (l) = 0; \
|
|
} else { \
|
|
(f) = (f)->next; \
|
|
} \
|
|
} while (0)
|
|
#define SLLQ_REMOVE_FIRST(f, l) SLLQ_REMOVE_FIRST_EX(f, l, next)
|
|
|
|
// Singly linked list stack
|
|
#define SLLS_PUSH_EX(stack_base, new_stack_base, next) \
|
|
do { \
|
|
(new_stack_base)->next = (stack_base); \
|
|
(stack_base) = (new_stack_base); \
|
|
} while (0)
|
|
#define SLLS_PUSH(stack_base, new_stack_base) \
|
|
SLLS_PUSH_EX(stack_base, new_stack_base, next)
|
|
|
|
#define SLLS_POP(stack_base) ((stack_base) = (stack_base)->next)
|
|
#define SLLS_POP_AND_STORE(stack_base, out_node) \
|
|
do { \
|
|
if (stack_base) { \
|
|
(out_node) = (stack_base); \
|
|
(stack_base) = (stack_base)->next; \
|
|
(out_node)->next = 0; \
|
|
} \
|
|
} while (0)
|
|
|
|
// Doubly linked list Queue
|
|
#define DLLQ_APPEND_EX(f, l, node, next, prev) \
|
|
do { \
|
|
assert((node)->next == NULL); \
|
|
assert((node)->prev == NULL); \
|
|
if ((f) == 0) { \
|
|
(f) = (l) = (node); \
|
|
} else { \
|
|
(l)->next = (node); \
|
|
(node)->prev = (l); \
|
|
(l) = (node); \
|
|
} \
|
|
} while (0)
|
|
#define DLLQ_APPEND(f, l, node) DLLQ_APPEND_EX(f, l, node, next, prev)
|
|
|
|
#define DLLQ_PREPEND_EX(f, l, node, next, prev) \
|
|
do { \
|
|
assert((node)->next == NULL); \
|
|
assert((node)->prev == NULL); \
|
|
if ((f) == 0) { \
|
|
(f) = (l) = (node); \
|
|
} else { \
|
|
(node)->next = (f); \
|
|
(f)->prev = (node); \
|
|
(f) = (node); \
|
|
} \
|
|
} while (0)
|
|
#define DLLQ_PREPEND(f, l, node) DLLQ_PREPEND_EX(f, l, node, next, prev)
|
|
|
|
#define DLLQ_CONTAINS(f, l, n, next, prev) for (
|
|
|
|
#define DLLQ_REMOVE_EX(first, last, node, next, prev) \
|
|
do { \
|
|
if ((first) == (last)) { \
|
|
assert((node) == (first)); \
|
|
(first) = (last) = 0; \
|
|
} else if ((last) == (node)) { \
|
|
(last) = (last)->prev; \
|
|
(last)->next = 0; \
|
|
} else if ((first) == (node)) { \
|
|
(first) = (first)->next; \
|
|
(first)->prev = 0; \
|
|
} else { \
|
|
(node)->prev->next = (node)->next; \
|
|
(node)->next->prev = (node)->prev; \
|
|
} \
|
|
if (node) { \
|
|
(node)->prev = 0; \
|
|
(node)->next = 0; \
|
|
} \
|
|
} while (0)
|
|
#define DLLQ_REMOVE(first, last, node) DLLQ_REMOVE_EX(first, last, node, next, prev)
|
|
|
|
// Doubly linked list Stack
|
|
#define DLLS_PUSH_EX(first, node, next, prev) \
|
|
do { \
|
|
assert((node)->next == NULL); \
|
|
assert((node)->prev == NULL); \
|
|
(node)->next = (first); \
|
|
if ((first)) \
|
|
(first)->prev = (node); \
|
|
(first) = (node); \
|
|
} while (0)
|
|
#define DLLS_PUSH(first, node) DLLS_PUSH_EX(first, node, next, prev)
|
|
#define DLLS_REMOVE_EX(first, node, next, prev) \
|
|
do { \
|
|
if ((node) == (first)) { \
|
|
(first) = (first)->next; \
|
|
if ((first)) \
|
|
(first)->prev = 0; \
|
|
} else { \
|
|
(node)->prev->next = (node)->next; \
|
|
if ((node)->next) \
|
|
(node)->next->prev = (node)->prev; \
|
|
} \
|
|
if (node) { \
|
|
(node)->prev = 0; \
|
|
(node)->next = 0; \
|
|
} \
|
|
} while (0)
|
|
#define DLLS_REMOVE(first, node) DLLS_REMOVE_EX(first, node, next, prev)
|