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