cbase
1.46.11
C/C++ Static Template
Loading...
Searching...
No Matches
base_macros.h
Go to the documentation of this file.
1
11
12
#ifndef BASE_MACROS_H
13
#define BASE_MACROS_H
14
15
#if defined(_WIN32)
16
# ifndef WIN32_LEAN_AND_MEAN
18
# define WIN32_LEAN_AND_MEAN
19
# endif
20
// Note: We don't include <windows.h> here to prevent namespace pollution.
21
// Include it manually in the specific .c files that need it.
22
#elif defined(__linux__) || (defined(__APPLE__) && defined(__MACH__))
24
# include <unistd.h>
25
#endif
26
27
#if defined(__clang__)
29
# define COMPILER_CLANG 1
31
# define COMPILER_NAME "Clang"
32
#elif defined(__GNUC__)
34
# define COMPILER_GCC 1
36
# define COMPILER_NAME "GCC"
37
#elif defined(_MSC_VER)
39
# define COMPILER_MSVC 1
41
# define COMPILER_NAME "MSVC"
42
#else
43
# error "Compiler not supported"
44
#endif
45
46
#if defined(_WIN32)
48
# define OS_WINDOWS 1
50
# define OS_NAME "Windows"
51
#elif defined(__linux__)
53
# define OS_LINUX 1
55
# define OS_NAME "Linux"
56
#elif defined(__APPLE__) && defined(__MACH__)
58
# define OS_MAC 1
60
# define OS_NAME "macOS"
61
#else
62
# error "Operating system not supported"
63
#endif
64
65
#if defined(_M_X64) || defined(__x86_64__)
67
# define ARCH_X64 1
69
# define ARCH_NAME "x86_64"
70
#elif defined(_M_IX86) || defined(__i386__)
72
# define ARCH_X86 1
74
# define ARCH_NAME "x86"
75
#elif defined(_M_ARM64) || defined(__aarch64__)
77
# define ARCH_ARM64 1
79
# define ARCH_NAME "ARM64"
80
#elif defined(_M_ARM) || defined(__arm__)
82
# define ARCH_ARM 1
84
# define ARCH_NAME "ARM"
85
#else
86
# error "Architecture not supported"
87
#endif
88
89
#if defined(NDEBUG)
91
# define BUILD_RELEASE 1
93
# define BUILD_NAME "Release"
94
#else
96
# define BUILD_DEBUG 1
98
# define BUILD_NAME "Debug"
99
#endif
100
101
#if (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) || defined(_M_IX86) || \
102
defined(_M_X64) || defined(__i386__) || defined(__x86_64__) || defined(_M_ARM) || \
103
defined(_M_ARM64)
105
# define ENDIAN_LITTLE 1
107
# define ENDIAN_NAME "Little Endian"
108
#elif (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) || defined(__BIG_ENDIAN__)
110
# define ENDIAN_BIG 1
112
# define ENDIAN_NAME "Big Endian"
113
#else
114
# error "Could not determine endianness"
115
#endif
116
117
#if defined(__STDC_VERSION__)
118
# if __STDC_VERSION__ >= 202311L
120
# define C_STANDARD 23
122
# define C_STANDARD_NAME "C23"
123
# elif __STDC_VERSION__ >= 201710L
124
# define C_STANDARD 17
125
# define C_STANDARD_NAME "C17"
126
# elif __STDC_VERSION__ >= 201112L
127
# define C_STANDARD 11
128
# define C_STANDARD_NAME "C11"
129
# elif __STDC_VERSION__ >= 199901L
130
# define C_STANDARD 99
131
# define C_STANDARD_NAME "C99"
132
# else
133
# define C_STANDARD 89
134
# define C_STANDARD_NAME "C89"
135
# endif
136
#else
138
# define C_STANDARD 89
140
# define C_STANDARD_NAME "C89/Default"
141
#endif
142
143
#include <stddef.h>
144
#include <stdint.h>
145
#include <stdio.h>
146
#include <string.h>
147
153
155
#define function static
156
158
#define global static
159
161
#define local_persist static
162
164
#define external extern
165
167
#if defined(COMPILER_MSVC)
168
# define thread_local __declspec(thread)
169
#elif defined(COMPILER_CLANG) || defined(COMPILER_GCC)
170
# define thread_local __thread
171
#elif C_STANDARD >= 11
172
# define thread_local _Thread_local
173
#else
174
# error "Thread local storage not supported on this compiler!"
175
#endif
176
177
#if defined(COMPILER_GCC) || defined(COMPILER_CLANG)
179
# define API_EXPORT __attribute__((visibility("default")))
181
# define API_LOCAL __attribute__((visibility("hidden")))
182
#elif defined(COMPILER_MSVC)
184
# define API_EXPORT __declspec(dllexport)
186
# define API_LOCAL
187
#else
189
# define API_EXPORT
191
# define API_LOCAL
192
#endif
193
194
#ifdef __cplusplus
196
# define C_LINKAGE_BEGIN extern "C" {
198
# define C_LINKAGE_END }
199
#else
201
# define C_LINKAGE_BEGIN
203
# define C_LINKAGE_END
204
#endif
206
212
214
#define STRINGIFY_DETAIL(x) #x
220
#define STRINGIFY(x) STRINGIFY_DETAIL(x)
221
223
#define GLUE_DETAIL(x, y) x##y
229
#define GLUE(x, y) GLUE_DETAIL(x, y)
230
236
#define INT_FROM_PTR(ptr) ((uintptr_t)(ptr))
237
244
#define PTR_FROM_INT(type, val) ((type *)(uintptr_t)(val))
245
252
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
253
254
#if defined(__GNUC__) || defined(__clang__) || \
255
(defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L)
256
257
# if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L
258
# define _TYPEOF(x) typeof(x)
259
# else
260
# define _TYPEOF(x) __typeof__(x)
261
# endif
262
266
# define MIN(a, b) \
267
({ \
268
_TYPEOF(a) _a = (a); \
269
_TYPEOF(b) _b = (b); \
270
_a < _b ? _a : _b; \
271
})
272
276
# define MAX(a, b) \
277
({ \
278
_TYPEOF(a) _a = (a); \
279
_TYPEOF(b) _b = (b); \
280
_a > _b ? _a : _b; \
281
})
282
286
# define CLAMP(val, min, max) \
287
({ \
288
_TYPEOF(val) _v = (val); \
289
_TYPEOF(min) _mn = (min); \
290
_TYPEOF(max) _mx = (max); \
291
(_v < _mn) ? _mn : ((_v > _mx) ? _mx : _v); \
292
})
293
294
#else
295
// Fallbacks for standard C89/C11 (MSVC)
297
# define MIN(a, b) (((a) < (b)) ? (a) : (b))
299
# define MAX(a, b) (((a) > (b)) ? (a) : (b))
301
# define CLAMP(val, min, max) (((val) < (min)) ? (min) : ((val) > (max)) ? (max) : (val))
302
#endif
303
310
#define SWAP(type, a, b) \
311
do { \
312
type _tmp = (a); \
313
(a) = (b); \
314
(b) = _tmp; \
315
} while (0)
316
321
#define Boolify(x) ((x) != 0)
322
330
#define AsciiID4(a, b, c, d) (((d) << 24) | ((c) << 16) | ((b) << 8) | (a))
331
336
#define ExpandAsciiID(x) (int)(sizeof(x)), (char *)(&(x))
338
344
351
#define ALIGN_UP_POW2(x, p) (((x) + (p) - 1) & ~((p) - 1))
352
359
#define ALIGN_DOWN_POW2(x, p) ((x) & ~((p) - 1))
360
366
#define IS_POW2_OR_ZERO(x) (((x) & ((x) - 1)) == 0)
367
374
#define SHIFT8(T, x, s) ((T)(x) << (s))
375
384
#define PACK_U32_LE(a, b, c, d) \
385
(SHIFT8(U32, a, 0) | SHIFT8(U32, b, 8) | SHIFT8(U32, c, 16) | SHIFT8(U32, d, 24))
386
387
393
395
#define MEM_ZERO(ptr, size) memset((ptr), 0, (size))
396
401
#define MEM_ZERO_STRUCT(ptr) MEM_ZERO((ptr), sizeof(*(ptr)))
402
407
#define MEM_ZERO_ARRAY(arr) MEM_ZERO((arr), sizeof(arr))
408
410
#define MEM_COPY(dst, src, size) memmove((dst), (src), (size))
411
418
#define MEM_COPY_STRUCT(dst, src) MEM_COPY((dst), (src), MIN(sizeof(*(dst)), sizeof(*(src))))
419
426
#define MEM_COPY_ARRAY(dst, src) MEM_COPY((dst), (src), MIN(sizeof(dst), sizeof(src)))
428
441
450
#define DLL_PUSH_BACK_NP(f, l, n, next, prev) \
451
((f) == 0 ? ((f) = (l) = (n), (n)->next = (n)->prev = 0) \
452
: ((n)->prev = (l), (l)->next = (n), (l) = (n), (n)->next = 0))
453
473
#define DLL_PUSH_BACK(f, l, n) DLL_PUSH_BACK_NP(f, l, n, next, prev)
474
484
#define DLL_PUSH_FRONT(f, l, n) DLL_PUSH_BACK_NP(l, f, n, prev, next)
485
494
#define DLL_REMOVE_NP(f, l, n, next, prev) \
495
((f) == (n) ? ((f) == (l) ? ((f) = (l) = (0)) : ((f) = (f)->next, (f)->prev = 0)) \
496
: (l) == (n) ? ((l) = (l)->prev, (l)->next = 0) \
497
: ((n)->next->prev = (n)->prev, (n)->prev->next = (n)->next))
498
509
#define DLL_REMOVE(f, l, n) DLL_REMOVE_NP(f, l, n, next, prev)
510
518
#define SLL_QUEUE_PUSH_N(f, l, n, next) \
519
(((f) == 0 ? (f) = (l) = (n) : ((l)->next = (n), (l) = (n))), (n)->next = 0)
520
530
#define SLL_QUEUE_PUSH(f, l, n) SLL_QUEUE_PUSH_N(f, l, n, next)
531
538
#define SLL_STACK_PUSH_N(f, n, next) ((n)->next = (f), (f) = (n))
539
548
#define SLL_STACK_PUSH(f, n) SLL_STACK_PUSH_N(f, n, next)
549
555
#define SLL_STACK_POP_N(f, next) ((f) == 0 ? 0 : ((f) = (f)->next))
556
565
#define SLL_STACK_POP(f) SLL_STACK_POP_N(f, next)
567
573
574
#if defined(COMPILER_MSVC)
576
# define debug_break() __debugbreak()
577
#elif defined(COMPILER_GCC) || defined(COMPILER_CLANG)
579
# define debug_break() __builtin_trap()
580
#else
582
# define debug_break() (*(volatile int *)0 = 0)
583
#endif
584
585
#if BUILD_DEBUG
590
# define ASSERT(expr) \
591
do { \
592
if (!(expr)) { \
593
fputs("Assertion failed: " #expr "\n", stderr); \
594
fputs("File: " __FILE__ "\n", stderr); \
595
fputs("Line: " STRINGIFY(__LINE__) "\n", stderr); \
596
debug_break(); \
597
} \
598
} while (0)
599
604
# define ASSERT_NOT_NULL(ptr) \
605
do { \
606
if ((ptr) == NULL) { \
607
fputs("Assertion failed: " #ptr " is NULL\n", stderr); \
608
fputs("File: " __FILE__ "\n", stderr); \
609
fputs("Line: " STRINGIFY(__LINE__) "\n", stderr); \
610
debug_break(); \
611
} \
612
} while (0)
613
#else
614
// Compile assertions out completely in Release builds for zero overhead
615
# define ASSERT(expr) ((void)0)
616
# define ASSERT_NOT_NULL(ptr) ((void)0)
617
#endif
619
620
#endif
// BASE_MACROS_H
include
base
base_macros.h
Generated by
1.16.1