1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
|
#if !defined(BASE_CORE_H)
#define BASE_CORE_H
// detect OS
#if ANDROID
# define OS_ANDROID 1
#elif __linux__
# define OS_LINUX 1
#elif _WIN32
# define OS_WINDOWS 1
#endif
// Detect compiler
#if __clang__
# define COMPILER_CLANG 1
#elif _MSC_VER
# define COMPILER_MSVC 1
#elif __GNUC__
# define COMPILER_GNU 1
#endif
// Detect language
#if defined(__cplusplus)
# define LANG_CPP 1
#else
# define LANG_C 1
#endif
// Zero undefined
#if !defined(OS_LINUX)
# define OS_LINUX 0
#endif
#if !defined(OS_WINDOWS)
# define OS_WINDOWS 0
#endif
#if !defined(OS_ANDROID)
# define OS_ANDROID 0
#endif
#if !defined(COMPILER_MSVC)
# define COMPILER_MSVC 0
#endif
#if !defined(COMPILER_LLVM)
# define COMPILER_LLVM 0
#endif
#if !defined(COMPILER_GNU)
# define COMPILER_GNU 0
#endif
#if !defined(LANG_C)
# define LANG_C 0
#endif
#if !defined(LANG_CPP)
# define LANG_CPP 0
#endif
#if !defined(BASE_CONSOLE_APPLICATION)
# define BASE_CONSOLE_APPLICATION 0
#endif
#if !defined(BASE_FORCE_THREADS_COUNT)
# define BASE_FORCE_THREADS_COUNT 0
#endif
#if !defined(BASE_PROFILE)
# define BASE_PROFILE 0
#endif
//~ OS
#include <stdint.h>
#include <stddef.h>
#include <string.h> // memset
#if OS_WINDOWS
# define _CRT_SECURE_NO_WARNINGS 1
# define WIN32_LEAN_AND_MEAN 1
# include <windows.h>
# include <stdio.h>
# define RADDBG_MARKUP_IMPLEMENTATION
# define ssize_t SSIZE_T
#else
# define RADDBG_MARKUP_STUBS
# include <sys/types.h>
#endif
#if defined(COMPILER_MSVC)
# if defined(__cplusplus)
// NOTE(luca): Decay to numeric type.
# define TypeOf(x) decltype((x)+0)
# else
# define TypeOf(x) __typeof__(x)
# endif
#elif defined(COMPILER_GNU) || defined(COMPILER_CLANG)
# define TypeOf(x) typeof(x)
#else
# error "Unsupported compiler"
#endif
//~ Macros
#define ERROR_FMT "%s(%d): ERROR: "
#define ERROR_ARG __FILE__, __LINE__
//-
#define ArrayCount(Array) (sizeof(Array) / sizeof((Array)[0]))
#define CeilIntegerDiv(A,B) (((A) + (B) - 1)/(B))
//-
#define Stringify_(S) #S
#define Stringify(S) Stringify_(S)
#define Glue_(A,B) A##B
#define Glue(A,B) Glue_(A,B)
//-
#define Min(A, B) (((A) < (B)) ? (A) : (B))
#define Max(A, B) (((A) > (B)) ? (A) : (B))
#define ClampTop(A, X) Min(A,X)
#define ClampBot(X, B) Max(X,B)
#define Clamp(A, X, B) (((X) < (A)) ? (A) : ((X) > (B)) ? (B) : (X))
#if LANG_C
# define Swap(A, B) do { TypeOf((A)) (temp) = (TypeOf((A)))(A); (A) = (B); (B) = (temp); } while(0)
#else
template <typename t> inline void
Swap(t& A, t& B) { t T = A; A = B; B = T; }
#endif
//-
#define NoOp ((void)0)
#if LANG_C
# define ZeroStruct {0}
#elif LANG_CPP
# define ZeroStruct {0}
#endif
#if OS_LINUX || OS_ANDROID
# define OS_SlashChar '/'
# define SLASH "/"
#elif OS_WINDOWS
# define OS_SlashChar '\\'
# define SLASH "\\"
#endif
#if (COMPILER_CLANG || COMPILER_GNU)
# if defined(__arm__) || defined(__aarch64__)
# define Trap() __asm__ volatile("brk #0");
# elif defined(__i386__) || defined(__x86_64__)
# define Trap() __asm__ volatile("int3");
# endif
#elif COMPILER_MSVC
# define Trap() (__debugbreak());
#else
# define Trap() *(int *)0 = 0;
#endif
#if COMPILER_MSVC
# define ReadWriteBarrier _ReadBarrier(); _WriteBarrier();
#elif COMPILER_GNU || COMPILER_CLANG
# define ReadWriteBarrier __asm__ __volatile__ ("" : : : "memory")
#endif
#define DebugBreak() do { if(GlobalDebuggerIsAttached) { Trap(); } } while(0)
#define Var(Name) Glue(Name, __LINE__)
#define DoOnce local_persist s32 Var(X) = 0; Var(X) += 1; if(Var(X) < 2)
#define DebugBreakOnce() do { DoOnce { DebugBreak(); }; } while(0);
#define DebugBreakMsg(Format, ...) do { ErrorLog(Format, ##__VA_ARGS__); DebugBreak(); } while(0)
#define TrapMsg(Format, ...) do { ErrorLog(Format, ##__VA_ARGS__); Trap(); } while(0)
#define AssertMsg(Expression, Format, ...) \
do { if(!(Expression)) TrapMsg(Format, ##__VA_ARGS__); } while(0)
#define Assert(Expression) AssertMsg(Expression, "Hit assertion")
#define NotImplemented() DebugBreakMsg("Not Implemented!")
#define InvalidPath() TrapMsg("Invalid Path!")
#define StaticAssert(C, ID) global_variable u8 Glue(ID, __LINE__)[(C)?1:-1]
//~ Loop macros
#define DeferLoop(Begin, End) for(int _i_ = ((Begin), 0); !_i_; _i_ += 1, (End))
#define EachIndexType(t, Index, Count) (t Index = 0; Index < (Count); Index += 1)
#define EachIndex(Index, Count) EachIndexType(TypeOf((Count)), Index, Count)
#define EachElement(Index, Array) EachIndexType(umm, Index, ArrayCount(Array))
#define EachInRange(Index, Range) (TypeOf((Range).Min) Index = (Range).Min; Index < (Range).Max; Index += 1)
#define EachNode(Index, t, First) (t *Index = First; Index != 0; Index = Index->Next)
#define MemoryCopy(Dest, Source, Count) memmove(Dest, Source, Count)
#define MemorySet(Dest, Value, Count) memset(Dest, Value, Count)
#define MemoryZero(Value) MemorySet((Value), 0, sizeof((*Value)));
#define MemoryCopyArray(Dest, Source) MemoryCopy((Dest), (Source), sizeof((Dest)))
#define MemoryCopyStruct(Dest, Source) MemoryCopy((Dest), (Source), sizeof(*(Dest)))
//~ Attributes
#define internal static
#define local_persist static
#define global_variable static
#if COMPILER_MSVC
# define thread_static __declspec(thread)
#else
# define thread_static __thread
#endif
#if COMPILER_MSVC || (COMPILER_CLANG && OS_WINDOWS)
# pragma section(".rdata$", read)
# define read_only __declspec(allocate(".rdata$"))
#elif (COMPILER_CLANG && OS_LINUX)
# define read_only __attribute__((section(".rodata")))
#else
// NOTE(rjf): I don't know of a useful way to do this in GCC land.
// __attribute__((section(".rodata"))) looked promising, but it introduces a
// strange warning about malformed section attributes, and it doesn't look
// like writing to that section reliably produces access violations, strangely
// enough. (It does on Clang)
# define read_only
#endif
#if COMPILER_MSVC
# define PrintfFunc(FormatIdx, FirstArgIdx)
#elif COMPILER_CLANG || COMPILER_GNU
# define PrintfFunc(FormatIdx, FirstArgIdx) __attribute__((format(printf, FormatIdx, FirstArgIdx)))
#endif
#if COMPILER_MSVC
# define force_inline __forceinline
#elif COMPILER_CLANG || COMPILER_GNU
# define force_inline __attribute__((always_inline)
#else
# error force_inline not defined for this compiler.
#endif
#if COMPILER_MSVC
# define no_inline __declspec(noinline)
#elif COMPILER_CLANG || COMPILER_GNU
# define no_inline __attribute__((noinline))
#else
# error no_inline not defined for this compiler.
#endif
#if LANG_CPP
# define C_LINKAGE extern "C"
# define C_LINKAGE_BEGIN C_LINKAGE {
# define C_LINKAGE_END }
#else
# define C_LINKAGE
# define C_LINKAGE_BEGIN
# define C_LINKAGE_END
#endif
#define NO_STRUCT_PADDING_BEGIN _Pragma("pack(push, 1)")
#define NO_STRUCT_PADDING_END _Pragma("pack(pop)")
#if COMPILER_MSVC && !BUILD_DEBUG
# define NO_OPTIMIZE_BEGIN _Pragma("optimize(\"\", off)")
# define NO_OPTIMIZE_END _Pragma("optimize(\"\", on)")
#elif COMPILER_CLANG && !BUILD_DEBUG
# define NO_OPTIMIZE_BEGIN _Pragma("clang optimize off")
# define NO_OPTIMIZE_END _Pragma("clang optimize on")
#elif COMPILER_GNU && !BUILD_DEBUG
# define NO_OPTIMIZE_BEGIN _Pragma("GCC push_options") _Pragma("GCC optimize(\"O0\")")
# define NO_OPTIMIZE_END _Pragma("GCC pop_options")
#else
# define NO_OPTIMIZE_BEGIN
# define NO_OPTIMIZE_END
#endif
#if COMPILER_MSVC
# if defined(__SANITIZE_ADDRESS__)
# define ASAN_ENABLED 1
# define NO_ASAN __declspec(no_sanitize_address)
# else
# define NO_ASAN
# endif
#elif COMPILER_CLANG
# if defined(__has_feature)
# if __has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__)
# define ASAN_ENABLED 1
# endif
# endif
# define NO_ASAN __attribute__((no_sanitize("address")))
#else
# define NO_ASAN
#endif
#if ASAN_ENABLED
C_LINKAGE void __asan_poison_memory_region(void const volatile *Address, size_t Size);
C_LINKAGE void __asan_unpoison_memory_region(void const volatile *Address, size_t Size);
# define AsanPoisonMemoryRegion(Address, Size) \
__asan_poison_memory_region((Address), (Size))
# define AsanUnpoisonMemoryRegion(Address, Size) \
__asan_unpoison_memory_region((Address), (Size))
#else
# define AsanPoisonMemoryRegion(Address, Size) ((void)(Address), (void)(Size))
# define AsanUnpoisonMemoryRegion(Address, Size) ((void)(Address), (void)(Size))
#endif
// Alignment
#if COMPILER_MSVC
# define AlignOf(T) __alignof(T)
#elif COMPILER_CLANG
# define AlignOf(T) __alignof(T)
#elif COMPILER_GNU
# define AlignOf(T) __alignof__(T)
#else
# error AlignOf not defined for this compiler.
#endif
#define AlignPow2(x,b) (((x) + (b) - 1)&(~((b) - 1)))
// Push/Pop warnings
#if COMPILER_GNU
# define NO_WARNINGS_BEGIN \
_Pragma("GCC diagnostic push") \
_Pragma("GCC diagnostic ignored \"-Wall\"") \
_Pragma("GCC diagnostic ignored \"-Wextra\"") \
_Pragma("GCC diagnostic ignored \"-Wconversion\"") \
_Pragma("GCC diagnostic ignored \"-Wfloat-conversion\"") \
_Pragma("GCC diagnostic ignored \"-Wsign-conversion\"") \
_Pragma("GCC diagnostic ignored \"-Wsign-compare\"") \
_Pragma("GCC diagnostic ignored \"-Wdouble-promotion\"") \
_Pragma("GCC diagnostic ignored \"-Wimplicit-fallthrough\"")
# define NO_WARNINGS_END _Pragma("GCC diagnostic pop")
#elif COMPILER_CLANG
# define NO_WARNINGS_BEGIN \
_Pragma("clang diagnostic push") \
_Pragma("clang diagnostic ignored \"-Weverything\"")
# define NO_WARNINGS_END _Pragma("clang diagnostic pop")
#elif COMPILER_MSVC
# define NO_WARNINGS_BEGIN \
__pragma(warning(push)) \
__pragma(warning(disable: 4267 4996)) // NOTE: Add specific warning numbers to disable as needed
# define NO_WARNINGS_END __pragma(warning(pop))
#else
# error "No compatible compiler found"
#endif
#define Pi32 3.14159265359f
#define KB(n) (((u64 )(n)) << 10)
#define MB(n) (((u64 )(n)) << 20)
#define GB(n) (((u64 )(n)) << 30)
#define TB(n) (((u64 )(n)) << 40)
#define Thousand(n) ((n)*1000)
#define Million(n) ((n)*1000000)
#define Billion(n) ((n)*1000000000)
//~ Types
typedef int8_t s8;
typedef int16_t s16;
typedef int32_t s32;
typedef int64_t s64;
typedef s32 b32;
typedef uint8_t u8;
typedef uint16_t u16;
typedef uint32_t u32;
typedef uint64_t u64;
typedef size_t umm ;
typedef ssize_t smm;
typedef s32 rune; // utf8 codepoint
typedef float f32;
typedef double f64;
#define U8Max 0xff
#define U16Max 0xffff
#define S32Min ((s32)0x80000000)
#define S32Max ((s32)0x7fffffff)
#define U32Min 0
#define U32Max ((u32)-1)
#define U64Max ((u64)-1)
#define false 0
#define true 1
//~ Globals
global_variable b32 GlobalDebuggerIsAttached;
#endif // BASE_CORE_H
|