util.h (8168B)
1 /* See LICENSE for license details. */ 2 #ifndef _UTIL_H_ 3 #define _UTIL_H_ 4 5 #include "base_platform.h" 6 7 #define da_count i32 8 9 #if OS_WINDOWS 10 #define EXPORT __declspec(dllexport) 11 #else 12 #define EXPORT 13 #endif 14 15 #ifdef _DEBUG 16 #define DEBUG_EXPORT EXPORT 17 #ifdef _BEAMFORMER_DLL 18 #if OS_WINDOWS 19 #define DEBUG_IMPORT __declspec(dllimport) 20 #else 21 #define DEBUG_IMPORT extern 22 #endif 23 #else 24 #define DEBUG_IMPORT DEBUG_EXPORT 25 #endif 26 #define DEBUG_DECL(a) a 27 #define assert(c) do { if (!(c)) debugbreak(); } while (0) 28 #else 29 #define DEBUG_IMPORT global 30 #define DEBUG_EXPORT function 31 #define DEBUG_DECL(a) 32 #define assert(c) (void)(c) 33 #endif 34 35 #if ASAN_ACTIVE 36 void __asan_poison_memory_region(void *, i64); 37 void __asan_unpoison_memory_region(void *, i64); 38 #define asan_poison_region(region, size) __asan_poison_memory_region((region), (size)) 39 #define asan_unpoison_region(region, size) __asan_unpoison_memory_region((region), (size)) 40 #else 41 #define asan_poison_region(...) 42 #define asan_unpoison_region(...) 43 #endif 44 45 #define InvalidCodePath assert(0) 46 #define InvalidDefaultCase default: assert(0); break 47 48 #define arg_list(type, ...) (type []){__VA_ARGS__}, sizeof((type []){__VA_ARGS__}) / sizeof(type) 49 50 #if COMPILER_MSVC 51 #define thread_static __declspec(thread) 52 #elif COMPILER_CLANG || COMPILER_GCC 53 #define thread_static __thread 54 #else 55 #error thread_static not defined for this compiler 56 #endif 57 58 #define alignof _Alignof 59 #define static_assert _Static_assert 60 61 /* NOTE: garbage to get the prepocessor to properly stringize the value of a macro */ 62 #define str_(...) #__VA_ARGS__ 63 #define str(...) str_(__VA_ARGS__) 64 65 #define swap(a, b) do {typeof(a) __tmp = (a); (a) = (b); (b) = __tmp;} while(0) 66 67 #define Abs(a) ((a) < 0 ? -(a) : (a)) 68 #define Sign(a) ((a) < 0 ? -1 : 1) 69 #define Between(x, a, b) ((x) >= (a) && (x) <= (b)) 70 #define Clamp(x, a, b) ((x) < (a) ? (a) : (x) > (b) ? (b) : (x)) 71 #define Clamp01(x) Clamp(x, 0, 1) 72 #define Min(a, b) ((a) < (b) ? (a) : (b)) 73 #define Max(a, b) ((a) > (b) ? (a) : (b)) 74 75 #define IsPowerOfTwo(a) (((a) & ((a) - 1)) == 0) 76 #define AlignUpPowerOfTwo(v, a) (((v) + (a) - 1) & (~((a) - 1))) 77 78 #define IsDigit(c) (Between((c), '0', '9')) 79 #define IsUpper(c) (((c) & 0x20u) == 0) 80 #define ToLower(c) (((c) | 0x20u)) 81 #define ToUpper(c) (((c) & ~(0x20u))) 82 83 #define IsPunctuation(c) (Between(c, '!', '/') || Between(c, ':', '@') || Between(c, '[', '`') || Between(c, '{', '~')) 84 #define IsWordBoundary(c) (((c) == ' ') || IsPunctuation(c)) 85 86 #define f32_equal(x, y) (Abs((x) - (y)) <= F32_EPSILON * Max(1.0f, Max(Abs(x), Abs(y)))) 87 88 #define DeferLoop(begin, end) for (i32 _i_ = ((begin), 0); !_i_; _i_ += 1, (end)) 89 90 #define EachBit(a, it) (u64 _##it = a, it = ctz_u64( _##it ); it != 64; _##it &= ~(1u << (it)), it = ctz_u64( _##it )) 91 #define EachElement(array, it) (u64 it = 0; it < countof(array); it += 1) 92 #define EachEnumValue(type, it) (type it = (type)0; it < type##_Count; it = (type)(it + 1)) 93 #define EachNonZeroEnumValue(type, it) (type it = (type)1; it < type##_Count; it = (type)(it + 1)) 94 #define EachIndex(count, it) (u64 it = 0; it < count; it += 1) 95 96 #define spin_wait(c) while ((c)) cpu_yield() 97 98 // NOTE(rnp): typically for enums, wtf is wrong with modern compilers 99 #define circular_add(v, add, max) (((u64)(v) + (u64)(max) + (i64)(add)) % (u64)(max)) 100 101 #define DA_STRUCT(kind, name) typedef struct { \ 102 kind *data; \ 103 da_count count; \ 104 da_count capacity; \ 105 } name ##List; 106 107 #define SLLStackPush(list, n, next) ((n)->next = (list), (list) = (n)) 108 // TODO(rnp): clean this up 109 #define SLLPush(v, list) SLLStackPush(list, v, next) 110 111 /* NOTE(rnp): no guarantees about actually getting an element */ 112 #define SLLPop(l, next) (l); ((l) = (l) ? (l)->next : 0) 113 #define SLLStackPop(l, next) ((l) = (l)->next) 114 115 #define SLLPopFreelist(list) list; do { \ 116 asan_unpoison_region((list), sizeof(*(list))); \ 117 (void)SLLPop((list), next); \ 118 } while(0) 119 120 #define SLLPushFreelist(v, list) do { \ 121 SLLPush((v), (list)); \ 122 asan_poison_region((v), sizeof(*(v))); \ 123 } while(0) 124 125 #define DLLInsert(nil, f, l, n, next, prev) (\ 126 ((f) == 0 || (f) == nil) ? ((f) = (l) = (n), (n)->next = (n)->prev = nil) :\ 127 ((n)->next = (f), (n)->prev = (f)->prev, (f)->prev = (n), (f) = (n)),\ 128 (((n)->prev && (n)->prev != nil) ? ((n)->prev->next = (n)) : (0))) 129 130 #define DLLInsertFirst(nil, f, l, n, next, prev) DLLInsert(nil, f, l, n, next, prev) 131 #define DLLInsertLast(nil, f, l, n, next, prev) DLLInsert(nil, l, f, n, prev, next) 132 133 #define DLLRemove(nil, f, l, n, next, prev) (\ 134 ((n) == (f) ? (f) = (n)->next : (0)),\ 135 ((n) == (l) ? (l) = (n)->prev : (0)),\ 136 (((n)->prev != nil && (n)->prev != 0) ? (n)->prev->next = (n)->next : (0)),\ 137 (((n)->next != nil && (n)->next != 0) ? (n)->next->prev = (n)->prev : (0)),\ 138 (!(f) && (l) ? (f) = (l) : (0)),\ 139 (!(l) && (f) ? (l) = (f) : (0))) 140 141 typedef enum { 142 Axis2_X = 0, 143 Axis2_Y = 1, 144 Axis2_Count, 145 } Axis2; 146 #define axis2_flip(v) (!(v)) 147 148 typedef alignas(16) union { 149 u8 U8[16]; 150 u16 U16[8]; 151 u32 U32[4]; 152 u64 U64[2]; 153 u32x4 U32x4; 154 } u128; 155 156 typedef enum { 157 StringMatchFlag_CaseInsensitive = (1 << 0), 158 StringMatchFlag_SloppySize = (1 << 1), 159 } StringMatchFlags; 160 161 typedef struct { u32 cp, consumed; } UnicodeDecode; 162 163 typedef enum { 164 NumberConversionResult_Invalid, 165 NumberConversionResult_OutOfRange, 166 NumberConversionResult_Success, 167 } NumberConversionResult; 168 169 typedef enum { 170 NumberConversionKind_Invalid, 171 NumberConversionKind_Integer, 172 NumberConversionKind_Float, 173 } NumberConversionKind; 174 175 typedef struct { 176 NumberConversionResult result; 177 NumberConversionKind kind; 178 union { 179 u64 U64; 180 i64 S64; 181 f64 F64; 182 }; 183 str8 unparsed; 184 } NumberConversion; 185 186 #define XZ(v) (v2){.x = v.x, .y = v.z} 187 #define YZ(v) (v2){.x = v.y, .y = v.z} 188 #define XY(v) (v2){.x = v.x, .y = v.y} 189 190 /* TODO(rnp): delete raylib */ 191 typedef struct { 192 v3 origin; 193 v3 direction; 194 } ray; 195 196 typedef struct { v2 pos, size; } Rect; 197 198 typedef struct { 199 u8 *data; 200 i32 widx; 201 i32 cap; 202 b32 errors; 203 } Stream; 204 205 #define INVALID_FILE (-1) 206 207 #ifndef OSInvalidHandleValue 208 #define OSInvalidHandleValue ((u64)-1) 209 typedef struct { u64 value[1]; } OSBarrier; 210 typedef struct { u64 value[1]; } OSHandle; 211 typedef struct { u64 value[1]; } OSLibrary; 212 typedef struct { u64 value[1]; } OSThread; 213 typedef struct { u64 value[1]; } OSW32Semaphore; 214 #endif 215 216 #define ValidHandle(h) ((h).value[0] != OSInvalidHandleValue) 217 #define InvalidHandle(h) ((h).value[0] == OSInvalidHandleValue) 218 219 typedef struct { 220 u64 index; 221 u64 count; 222 OSBarrier barrier; 223 u64 * broadcast_memory; 224 } LaneContext; 225 226 typedef struct { 227 u8 name[16]; 228 u64 name_length; 229 230 LaneContext lane_context; 231 } ThreadContext; 232 233 #define OS_THREAD_ENTRY_POINT_FN(name) u64 name(void *user_context) 234 235 #define OS_WRITE_NEW_FILE_FN(name) b32 name(char *fname, str8 raw) 236 237 #define RENDERDOC_GET_API_FN(name) b32 name(u32 version, void **out_api) 238 typedef RENDERDOC_GET_API_FN(renderdoc_get_api_fn); 239 240 #define RENDERDOC_START_FRAME_CAPTURE_FN(name) void name(void *instance_handle, iptr window_handle) 241 typedef RENDERDOC_START_FRAME_CAPTURE_FN(renderdoc_start_frame_capture_fn); 242 243 #define RENDERDOC_END_FRAME_CAPTURE_FN(name) b32 name(void *instance_handle, iptr window_handle) 244 typedef RENDERDOC_END_FRAME_CAPTURE_FN(renderdoc_end_frame_capture_fn); 245 246 #define RENDERDOC_SET_CAPTURE_PATH_TEMPLATE_FN(name) void name(const char *template) 247 typedef RENDERDOC_SET_CAPTURE_PATH_TEMPLATE_FN(renderdoc_set_capture_path_template_fn); 248 249 typedef alignas(16) u8 RenderDocAPI[216]; 250 #define RENDERDOC_API_FN_ADDR(a, offset) (*(iptr *)((*a) + offset)) 251 #define RENDERDOC_START_FRAME_CAPTURE(a) (renderdoc_start_frame_capture_fn *) RENDERDOC_API_FN_ADDR(a, 152) 252 #define RENDERDOC_END_FRAME_CAPTURE(a) (renderdoc_end_frame_capture_fn *) RENDERDOC_API_FN_ADDR(a, 168) 253 #define RENDERDOC_SET_CAPTURE_PATH_TEMPLATE(a) (renderdoc_set_capture_path_template_fn *) RENDERDOC_API_FN_ADDR(a, 184) 254 255 #include "meta.h" 256 #include "util.c" 257 #include "math.c" 258 259 #endif /* _UTIL_H_ */