util.h (12146B)
1 /* See LICENSE for license details. */ 2 #ifndef _UTIL_H_ 3 #define _UTIL_H_ 4 5 #include "compiler.h" 6 7 #define da_count i32 8 9 #if COMPILER_MSVC 10 typedef unsigned __int64 u64; 11 typedef signed __int64 i64; 12 typedef unsigned __int32 u32; 13 typedef signed __int32 i32; 14 typedef unsigned __int16 u16; 15 typedef signed __int16 i16; 16 typedef unsigned __int8 u8; 17 typedef signed __int8 i8; 18 #else 19 typedef __UINT64_TYPE__ u64; 20 typedef __INT64_TYPE__ i64; 21 typedef __UINT32_TYPE__ u32; 22 typedef __INT32_TYPE__ i32; 23 typedef __UINT16_TYPE__ u16; 24 typedef __INT16_TYPE__ i16; 25 typedef __UINT8_TYPE__ u8; 26 typedef __INT8_TYPE__ i8; 27 #endif 28 29 typedef char c8; 30 typedef u8 b8; 31 typedef u16 b16; 32 typedef u32 b32; 33 typedef _Float16 f16; 34 typedef float f32; 35 typedef double f64; 36 typedef i64 iz; 37 typedef u64 uz; 38 typedef i64 iptr; 39 typedef u64 uptr; 40 41 #ifndef asm 42 #define asm __asm__ 43 #endif 44 45 #ifndef typeof 46 #define typeof __typeof__ 47 #endif 48 49 #if OS_WINDOWS 50 #define EXPORT __declspec(dllexport) 51 #else 52 #define EXPORT 53 #endif 54 55 #ifdef _DEBUG 56 #define DEBUG_EXPORT EXPORT 57 #ifdef _BEAMFORMER_DLL 58 #if OS_WINDOWS 59 #define DEBUG_IMPORT __declspec(dllimport) 60 #else 61 #define DEBUG_IMPORT extern 62 #endif 63 #else 64 #define DEBUG_IMPORT DEBUG_EXPORT 65 #endif 66 #define DEBUG_DECL(a) a 67 #define assert(c) do { if (!(c)) debugbreak(); } while (0) 68 #else 69 #define DEBUG_IMPORT global 70 #define DEBUG_EXPORT function 71 #define DEBUG_DECL(a) 72 #define assert(c) (void)(c) 73 #endif 74 75 #if ASAN_ACTIVE 76 void __asan_poison_memory_region(void *, i64); 77 void __asan_unpoison_memory_region(void *, i64); 78 #define asan_poison_region(region, size) __asan_poison_memory_region((region), (size)) 79 #define asan_unpoison_region(region, size) __asan_unpoison_memory_region((region), (size)) 80 #else 81 #define asan_poison_region(...) 82 #define asan_unpoison_region(...) 83 #endif 84 85 #define InvalidCodePath assert(0) 86 #define InvalidDefaultCase default: assert(0); break 87 88 #define arg_list(type, ...) (type []){__VA_ARGS__}, sizeof((type []){__VA_ARGS__}) / sizeof(type) 89 90 #define function static 91 #define global static 92 #define local_persist static 93 94 #if COMPILER_MSVC 95 #define thread_static __declspec(thread) 96 #elif COMPILER_CLANG || COMPILER_GCC 97 #define thread_static __thread 98 #else 99 #error thread_static not defined for this compiler 100 #endif 101 102 #define alignof _Alignof 103 #define static_assert _Static_assert 104 105 /* NOTE: garbage to get the prepocessor to properly stringize the value of a macro */ 106 #define str_(...) #__VA_ARGS__ 107 #define str(...) str_(__VA_ARGS__) 108 109 #define countof(a) (iz)(sizeof(a) / sizeof(*a)) 110 #define BETWEEN(x, a, b) ((x) >= (a) && (x) <= (b)) 111 #define CLAMP(x, a, b) ((x) < (a) ? (a) : (x) > (b) ? (b) : (x)) 112 #define CLAMP01(x) CLAMP(x, 0, 1) 113 #define ISPOWEROF2(a) (((a) & ((a) - 1)) == 0) 114 #define MIN(a, b) ((a) < (b) ? (a) : (b)) 115 #define MAX(a, b) ((a) > (b) ? (a) : (b)) 116 #define ORONE(x) ((x)? (x) : 1) 117 #define SIGN(x) ((x) < 0? -1 : 1) 118 #define swap(a, b) do {typeof(a) __tmp = (a); (a) = (b); (b) = __tmp;} while(0) 119 120 #define Abs(a) ((a) < 0 ? -(a) : (a)) 121 #define Sign(a) ((a) < 0 ? -1 : 1) 122 #define Between(x, a, b) ((x) >= (a) && (x) <= (b)) 123 #define Clamp(x, a, b) ((x) < (a) ? (a) : (x) > (b) ? (b) : (x)) 124 #define Clamp01(x) Clamp(x, 0, 1) 125 #define Min(a, b) ((a) < (b) ? (a) : (b)) 126 #define Max(a, b) ((a) > (b) ? (a) : (b)) 127 #define IsPowerOfTwo(a) (((a) & ((a) - 1)) == 0) 128 129 #define IsDigit(c) (Between((c), '0', '9')) 130 #define IsUpper(c) (((c) & 0x20u) == 0) 131 #define ToLower(c) (((c) | 0x20u)) 132 #define ToUpper(c) (((c) & ~(0x20u))) 133 134 #define f32_equal(x, y) (Abs((x) - (y)) <= F32_EPSILON * Max(1.0f, Max(Abs(x), Abs(y)))) 135 136 #define DeferLoop(begin, end) for (i32 _i_ = ((begin), 0); !_i_; _i_ += 1, (end)) 137 #define DeferLoopTag(begin, end, tag) for (i32 __##tag = ((begin), 0); !__##tag ; __##tag += 1, (end)) 138 139 #define EachBit(a, it) (u64 it = ctz_u64(a); it != 64; a &= ~(1u << (it)), it = ctz_u64(a)) 140 #define EachElement(array, it) (u64 it = 0; it < countof(array); it += 1) 141 #define EachEnumValue(type, it) (type it = (type)0; it < type##_Count; it = (type)(it + 1)) 142 #define EachNonZeroEnumValue(type, it) (type it = (type)1; it < type##_Count; it = (type)(it + 1)) 143 #define EachIndex(count, it) (u64 it = 0; it < count; it += 1) 144 145 #define spin_wait(c) while ((c)) cpu_yield() 146 147 // NOTE(rnp): typically for enums, wtf is wrong with modern compilers 148 #define circular_add(v, add, max) (((u64)(v) + (u64)(max) + (i64)(add)) % (u64)(max)) 149 150 #define DA_STRUCT(kind, name) typedef struct { \ 151 kind *data; \ 152 da_count count; \ 153 da_count capacity; \ 154 } name ##List; 155 156 #define SLLStackPush(list, n, next) ((n)->next = (list), (list) = (n)) 157 // TODO(rnp): clean this up 158 #define SLLPush(v, list) SLLStackPush(list, v, next) 159 160 /* NOTE(rnp): no guarantees about actually getting an element */ 161 #define SLLPop(l, next) (l); ((l) = (l) ? (l)->next : 0) 162 #define SLLStackPop(l, next) ((l) = (l)->next) 163 164 #define SLLPopFreelist(list) list; do { \ 165 asan_unpoison_region((list), sizeof(*(list))); \ 166 (void)SLLPop((list), next); \ 167 } while(0) 168 169 #define SLLPushFreelist(v, list) do { \ 170 SLLPush((v), (list)); \ 171 asan_poison_region((v), sizeof(*(v))); \ 172 } while(0) 173 174 #define DLLInsert(nil, f, l, n, next, prev) (\ 175 ((f) == 0 || (f) == nil) ? ((f) = (l) = (n), (n)->next = (n)->prev = nil) :\ 176 ((n)->next = (f), (n)->prev = (f)->prev, (f)->prev = (n), (f) = (n)),\ 177 ((n)->prev ? ((n)->prev->next = (n)) : (0))) 178 179 #define DLLInsertFirst(nil, f, l, n, next, prev) DLLInsert(nil, f, l, n, next, prev) 180 #define DLLInsertLast(nil, f, l, n, next, prev) DLLInsert(nil, l, f, n, prev, next) 181 182 #define DLLRemove(nil, f, l, n, next, prev) (\ 183 ((n) == (f) ? (f) = (n)->next : (0)),\ 184 ((n) == (l) ? (l) = (l)->prev : (0)),\ 185 (((n)->prev != nil && (n)->prev != 0) ? (n)->prev->next = (n)->next : (0)),\ 186 (((n)->next != nil && (n)->next != 0) ? (n)->next->prev = (n)->prev : (0))) 187 188 #define KB(a) ((u64)(a) << 10ULL) 189 #define MB(a) ((u64)(a) << 20ULL) 190 #define GB(a) ((u64)(a) << 30ULL) 191 192 #define I8_MAX (0x0000007FL) 193 #define I32_MAX (0x7FFFFFFFL) 194 #define U8_MAX (0x000000FFUL) 195 #define U16_MAX (0x0000FFFFUL) 196 #define U32_MAX (0xFFFFFFFFUL) 197 #define U64_MAX (0xFFFFFFFFFFFFFFFFULL) 198 #define F32_INFINITY (1e+300*1e+300) 199 #define F32_EPSILON (1e-6f) 200 #ifndef PI 201 #define PI (3.14159265358979323846f) 202 #endif 203 204 #include "intrinsics.c" 205 206 typedef alignas(16) union { 207 u8 U8[16]; 208 u16 U16[8]; 209 u32 U32[4]; 210 u64 U64[2]; 211 u32x4 U32x4; 212 } u128; 213 214 typedef struct { u8 *beg, *end; } Arena; 215 typedef struct { Arena *arena, original_arena; } TempArena; 216 217 typedef struct { i64 len; u8 *data; } s8; 218 #define s8(s) (s8){.len = countof(s) - 1, .data = (u8 *)s} 219 #define s8_comp(s) {sizeof(s) - 1, (u8 *)s} 220 221 typedef struct { i64 length; u8 *data; } str8; 222 #define str8(s) (str8){.length = countof(s) - 1, .data = (u8 *)s} 223 #define str8_comp(s) {sizeof(s) - 1, (u8 *)s} 224 #define str8_struct(v) (str8){.length = sizeof(*v), .data = (u8 *)v} 225 226 #define str8_from_s8(s) (str8){.length = (s).len, .data = (s).data} 227 #define s8_from_str8(s) (s8){.len = (s).length, .data = (s).data} 228 229 typedef struct { i64 len; u16 *data; } s16; 230 231 typedef enum { 232 StringMatchFlag_CaseInsensitive = (1 << 0), 233 StringMatchFlag_SloppySize = (1 << 1), 234 } StringMatchFlags; 235 236 typedef struct { u32 cp, consumed; } UnicodeDecode; 237 238 typedef enum { 239 NumberConversionResult_Invalid, 240 NumberConversionResult_OutOfRange, 241 NumberConversionResult_Success, 242 } NumberConversionResult; 243 244 typedef enum { 245 NumberConversionKind_Invalid, 246 NumberConversionKind_Integer, 247 NumberConversionKind_Float, 248 } NumberConversionKind; 249 250 typedef struct { 251 NumberConversionResult result; 252 NumberConversionKind kind; 253 union { 254 u64 U64; 255 i64 S64; 256 f64 F64; 257 }; 258 s8 unparsed; 259 } NumberConversion; 260 261 typedef struct { u64 start, stop; } RangeU64; 262 263 typedef union { 264 struct { i32 x, y; }; 265 struct { i32 w, h; }; 266 i32 E[2]; 267 } iv2; 268 269 typedef union { 270 struct { i32 x, y, z; }; 271 struct { i32 w, h, d; }; 272 iv2 xy; 273 i32 E[3]; 274 } iv3; 275 276 typedef union { 277 struct { i32 x, y, z, w; }; 278 struct { iv3 xyz; i32 _w; }; 279 i32 E[4]; 280 } iv4; 281 282 typedef union { 283 struct { u32 x, y; }; 284 struct { u32 w, h; }; 285 u32 E[2]; 286 } uv2; 287 288 typedef union { 289 struct { u32 x, y, z; }; 290 struct { u32 w, h, d; }; 291 uv2 xy; 292 u32 E[3]; 293 } uv3; 294 295 typedef union { 296 struct { u32 x, y, z, w; }; 297 struct { uv3 xyz; u32 _w; }; 298 u32 E[4]; 299 } uv4; 300 301 typedef union { 302 struct { b32 x, y, z; }; 303 b32 E[3]; 304 } bv3; 305 306 typedef union { 307 struct { f32 x, y; }; 308 struct { f32 w, h; }; 309 f32 E[2]; 310 } v2; 311 #define V2_INFINITY (v2){{-F32_INFINITY, F32_INFINITY}} 312 313 typedef union { 314 struct { f32 x, y, z; }; 315 struct { f32 w, h, d; }; 316 struct { v2 xy; f32 _1; }; 317 struct { f32 _2; v2 yz; }; 318 f32 E[3]; 319 } v3; 320 321 typedef union { 322 struct { f32 x, y, z, w; }; 323 struct { f32 r, g, b, a; }; 324 struct { v3 xyz; f32 _1; }; 325 struct { f32 _2; v3 yzw; }; 326 struct { v2 xy, zw; }; 327 f32 E[4]; 328 } v4; 329 330 #define XZ(v) (v2){.x = v.x, .y = v.z} 331 #define YZ(v) (v2){.x = v.y, .y = v.z} 332 #define XY(v) (v2){.x = v.x, .y = v.y} 333 334 typedef union { 335 struct { v4 x, y, z, w; }; 336 v4 c[4]; 337 f32 E[16]; 338 } m4; 339 340 /* TODO(rnp): delete raylib */ 341 typedef struct { 342 v3 origin; 343 v3 direction; 344 } ray; 345 346 typedef struct { v2 pos, size; } Rect; 347 #define INVERTED_INFINITY_RECT (Rect){.pos = {.x = -F32_INFINITY, .y = -F32_INFINITY}, \ 348 .size = {.x = -F32_INFINITY, .y = -F32_INFINITY}} 349 350 typedef struct { 351 u8 *data; 352 i32 widx; 353 i32 cap; 354 b32 errors; 355 } Stream; 356 357 #define INVALID_FILE (-1) 358 359 #ifndef OSInvalidHandleValue 360 #define OSInvalidHandleValue ((u64)-1) 361 typedef struct { u64 value[1]; } OSBarrier; 362 typedef struct { u64 value[1]; } OSHandle; 363 typedef struct { u64 value[1]; } OSLibrary; 364 typedef struct { u64 value[1]; } OSThread; 365 typedef struct { u64 value[1]; } OSW32Semaphore; 366 #endif 367 368 #define ValidHandle(h) ((h).value[0] != OSInvalidHandleValue) 369 #define InvalidHandle(h) ((h).value[0] == OSInvalidHandleValue) 370 371 typedef struct { 372 u64 index; 373 u64 count; 374 OSBarrier barrier; 375 u64 * broadcast_memory; 376 } LaneContext; 377 378 typedef struct { 379 u8 name[16]; 380 u64 name_length; 381 382 LaneContext lane_context; 383 } ThreadContext; 384 385 #define OS_ALLOC_ARENA_FN(name) Arena name(iz capacity) 386 #define OS_READ_ENTIRE_FILE_FN(name) i64 name(const char *file, void *buffer, i64 buffer_capacity) 387 #define OS_WAIT_ON_ADDRESS_FN(name) b32 name(i32 *value, i32 current, u32 timeout_ms) 388 #define OS_WAKE_ALL_WAITERS_FN(name) void name(i32 *sync) 389 #define OS_THREAD_ENTRY_POINT_FN(name) u64 name(void *user_context) 390 391 #define OS_WRITE_NEW_FILE_FN(name) b32 name(char *fname, s8 raw) 392 typedef OS_WRITE_NEW_FILE_FN(os_write_new_file_fn); 393 394 #define RENDERDOC_GET_API_FN(name) b32 name(u32 version, void **out_api) 395 typedef RENDERDOC_GET_API_FN(renderdoc_get_api_fn); 396 397 #define RENDERDOC_START_FRAME_CAPTURE_FN(name) void name(void *instance_handle, iptr window_handle) 398 typedef RENDERDOC_START_FRAME_CAPTURE_FN(renderdoc_start_frame_capture_fn); 399 400 #define RENDERDOC_END_FRAME_CAPTURE_FN(name) b32 name(void *instance_handle, iptr window_handle) 401 typedef RENDERDOC_END_FRAME_CAPTURE_FN(renderdoc_end_frame_capture_fn); 402 403 #define RENDERDOC_SET_CAPTURE_PATH_TEMPLATE_FN(name) void name(const char *template) 404 typedef RENDERDOC_SET_CAPTURE_PATH_TEMPLATE_FN(renderdoc_set_capture_path_template_fn); 405 406 typedef alignas(16) u8 RenderDocAPI[216]; 407 #define RENDERDOC_API_FN_ADDR(a, offset) (*(iptr *)((*a) + offset)) 408 #define RENDERDOC_START_FRAME_CAPTURE(a) (renderdoc_start_frame_capture_fn *) RENDERDOC_API_FN_ADDR(a, 152) 409 #define RENDERDOC_END_FRAME_CAPTURE(a) (renderdoc_end_frame_capture_fn *) RENDERDOC_API_FN_ADDR(a, 168) 410 #define RENDERDOC_SET_CAPTURE_PATH_TEMPLATE(a) (renderdoc_set_capture_path_template_fn *) RENDERDOC_API_FN_ADDR(a, 184) 411 412 #include "util.c" 413 #include "math.c" 414 415 #endif /* _UTIL_H_ */