Zycore
1.5.1.0
Toggle main menu visibility
Loading...
Searching...
No Matches
Defines.h
Go to the documentation of this file.
1
/***************************************************************************************************
2
3
Zyan Core Library (Zycore-C)
4
5
Original Author : Florian Bernd, Joel Hoener
6
7
* Permission is hereby granted, free of charge, to any person obtaining a copy
8
* of this software and associated documentation files (the "Software"), to deal
9
* in the Software without restriction, including without limitation the rights
10
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
* copies of the Software, and to permit persons to whom the Software is
12
* furnished to do so, subject to the following conditions:
13
*
14
* The above copyright notice and this permission notice shall be included in all
15
* copies or substantial portions of the Software.
16
*
17
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23
* SOFTWARE.
24
25
***************************************************************************************************/
26
31
32
#ifndef ZYCORE_DEFINES_H
33
#define ZYCORE_DEFINES_H
34
35
/* ============================================================================================== */
36
/* Meta macros */
37
/* ============================================================================================== */
38
47
#define ZYAN_MACRO_CONCAT(x, y) x ## y
48
58
#define ZYAN_MACRO_CONCAT_EXPAND(x, y) ZYAN_MACRO_CONCAT(x, y)
59
60
/* ============================================================================================== */
61
/* Compiler detection */
62
/* ============================================================================================== */
63
64
#if defined(__clang__)
65
# define ZYAN_CLANG
66
# define ZYAN_GNUC
67
#elif defined(__ICC) || defined(__INTEL_COMPILER)
68
# define ZYAN_ICC
69
#elif defined(__GNUC__) || defined(__GNUG__)
70
# define ZYAN_GCC
71
# define ZYAN_GNUC
72
#elif defined(_MSC_VER)
73
# define ZYAN_MSVC
74
#elif defined(__BORLANDC__)
75
# define ZYAN_BORLAND
76
#else
77
# define ZYAN_UNKNOWN_COMPILER
78
#endif
79
80
/* ============================================================================================== */
81
/* Platform detection */
82
/* ============================================================================================== */
83
84
#if defined(_WIN32)
85
# define ZYAN_WINDOWS
86
#elif defined(__EMSCRIPTEN__)
87
# define ZYAN_EMSCRIPTEN
88
#elif defined(__wasi__) || defined(__WASI__)
89
// via: https://reviews.llvm.org/D57155
90
# define ZYAN_WASI
91
#elif defined(__APPLE__)
92
# define ZYAN_APPLE
93
# define ZYAN_POSIX
94
#elif defined(__linux)
95
# define ZYAN_LINUX
96
# define ZYAN_POSIX
97
#elif defined(__FreeBSD__)
98
# define ZYAN_FREEBSD
99
# define ZYAN_POSIX
100
#elif defined(__NetBSD__)
101
# define ZYAN_NETBSD
102
# define ZYAN_POSIX
103
#elif defined(sun) || defined(__sun)
104
# define ZYAN_SOLARIS
105
# define ZYAN_POSIX
106
#elif defined(__HAIKU__)
107
# define ZYAN_HAIKU
108
# define ZYAN_POSIX
109
#elif defined(__unix) || defined(__unix__)
110
# define ZYAN_UNIX
111
# define ZYAN_POSIX
112
#elif defined(__posix)
113
# define ZYAN_POSIX
114
#else
115
# define ZYAN_UNKNOWN_PLATFORM
116
#endif
117
118
/* ============================================================================================== */
119
/* Kernel mode detection */
120
/* ============================================================================================== */
121
122
#if (defined(ZYAN_WINDOWS) && defined(_KERNEL_MODE)) || \
123
(defined(ZYAN_APPLE) && defined(KERNEL)) || \
124
(defined(ZYAN_LINUX) && defined(__KERNEL__)) || \
125
(defined(__FreeBSD_kernel__))
126
# define ZYAN_KERNEL
127
#else
128
# define ZYAN_USER
129
#endif
130
131
/* ============================================================================================== */
132
/* Architecture detection */
133
/* ============================================================================================== */
134
135
#if defined(_M_AMD64) || defined(__x86_64__)
136
# define ZYAN_X64
137
#elif defined(_M_IX86) || defined(__i386__)
138
# define ZYAN_X86
139
#elif defined(_M_ARM64) || defined(__aarch64__)
140
# define ZYAN_AARCH64
141
#elif defined(_M_ARM) || defined(_M_ARMT) || defined(__arm__) || defined(__thumb__)
142
# define ZYAN_ARM
143
#elif defined(__EMSCRIPTEN__) || defined(__wasm__) || defined(__WASM__)
144
# define ZYAN_WASM
145
#elif defined(__loongarch__)
146
# define ZYAN_LOONGARCH
147
#elif defined(__powerpc64__)
148
# define ZYAN_PPC64
149
#elif defined(__powerpc__)
150
# define ZYAN_PPC
151
#elif defined(__riscv) && __riscv_xlen == 64
152
# define ZYAN_RISCV64
153
#else
154
# error "Unsupported architecture detected"
155
#endif
156
157
/* ============================================================================================== */
158
/* Debug/Release detection */
159
/* ============================================================================================== */
160
161
#if defined(ZYAN_MSVC) || defined(ZYAN_BORLAND)
162
# ifdef _DEBUG
163
# define ZYAN_DEBUG
164
# else
165
# define ZYAN_RELEASE
166
# endif
167
#elif defined(ZYAN_GNUC) || defined(ZYAN_ICC)
168
# ifdef NDEBUG
169
# define ZYAN_RELEASE
170
# else
171
# define ZYAN_DEBUG
172
# endif
173
#else
174
# define ZYAN_RELEASE
175
#endif
176
177
/* ============================================================================================== */
178
/* Deprecation hint */
179
/* ============================================================================================== */
180
181
#if defined(ZYAN_GCC) || defined(ZYAN_CLANG)
182
# define ZYAN_DEPRECATED __attribute__((__deprecated__))
183
#elif defined(ZYAN_MSVC)
184
# define ZYAN_DEPRECATED __declspec(deprecated)
185
#else
186
# define ZYAN_DEPRECATED
187
#endif
188
189
/* ============================================================================================== */
190
/* Generic DLL import/export helpers */
191
/* ============================================================================================== */
192
193
#if defined(ZYAN_MSVC)
194
# define ZYAN_DLLEXPORT __declspec(dllexport)
195
# define ZYAN_DLLIMPORT __declspec(dllimport)
196
#else
197
# define ZYAN_DLLEXPORT
198
# define ZYAN_DLLIMPORT
199
#endif
200
201
/* ============================================================================================== */
202
/* Zycore dll{export,import} */
203
/* ============================================================================================== */
204
205
// This is a cut-down version of what CMake's `GenerateExportHeader` would usually generate. To
206
// simplify builds without CMake, we define these things manually instead of relying on CMake
207
// to generate the header.
208
//
209
// For static builds, our CMakeList will define `ZYCORE_STATIC_BUILD`. For shared library builds,
210
// our CMake will define `ZYCORE_SHOULD_EXPORT` depending on whether the target is being imported or
211
// exported. If CMake isn't used, users can manually define these to fit their use-case.
212
213
// Backward compatibility: CMake would previously generate these variables names. However, because
214
// they have pretty cryptic names, we renamed them when we got rid of `GenerateExportHeader`. For
215
// backward compatibility for users that don't use CMake and previously manually defined these, we
216
// translate the old defines here and print a warning.
217
#if defined(ZYCORE_STATIC_DEFINE)
218
# pragma message("ZYCORE_STATIC_DEFINE was renamed to ZYCORE_STATIC_BUILD.")
219
# define ZYCORE_STATIC_BUILD
220
#endif
221
#if defined(Zycore_EXPORTS)
222
# pragma message("Zycore_EXPORTS was renamed to ZYCORE_SHOULD_EXPORT.")
223
# define ZYCORE_SHOULD_EXPORT
224
#endif
225
229
#if defined(ZYCORE_STATIC_BUILD)
230
# define ZYCORE_EXPORT
231
#else
232
# if defined(ZYCORE_SHOULD_EXPORT)
233
# define ZYCORE_EXPORT ZYAN_DLLEXPORT
234
# else
235
# define ZYCORE_EXPORT ZYAN_DLLIMPORT
236
# endif
237
#endif
238
242
#define ZYCORE_NO_EXPORT
243
244
/* ============================================================================================== */
245
/* Misc compatibility macros */
246
/* ============================================================================================== */
247
248
#if defined(ZYAN_CLANG)
249
# define ZYAN_NO_SANITIZE(what) __attribute__((no_sanitize(what)))
250
#else
251
# define ZYAN_NO_SANITIZE(what)
252
#endif
253
254
#if defined(ZYAN_MSVC) || defined(ZYAN_BORLAND)
255
# define ZYAN_INLINE __inline
256
#else
257
# define ZYAN_INLINE static inline
258
#endif
259
260
#if defined(ZYAN_MSVC)
261
# define ZYAN_NOINLINE __declspec(noinline)
262
#elif defined(ZYAN_GCC) || defined(ZYAN_CLANG)
263
# define ZYAN_NOINLINE __attribute__((noinline))
264
#else
265
# define ZYAN_NOINLINE
266
#endif
267
268
/* ============================================================================================== */
269
/* Debugging and optimization macros */
270
/* ============================================================================================== */
271
275
#if defined(ZYAN_NO_LIBC)
276
# define ZYAN_ASSERT(condition) (void)(condition)
277
#elif defined(ZYAN_WINDOWS) && defined(ZYAN_KERNEL)
278
# include <wdm.h>
279
# define ZYAN_ASSERT(condition) NT_ASSERT(condition)
280
#else
281
# include <assert.h>
282
# define ZYAN_ASSERT(condition) assert(condition)
283
#endif
284
288
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L && !defined(__cplusplus)
289
# define ZYAN_STATIC_ASSERT(x) _Static_assert(x, #x)
290
#elif (defined(__cplusplus) && __cplusplus >= 201103L) || \
291
(defined(__cplusplus) && defined (_MSC_VER) && (_MSC_VER >= 1600)) || \
292
(defined (_MSC_VER) && (_MSC_VER >= 1800))
293
# define ZYAN_STATIC_ASSERT(x) static_assert(x, #x)
294
#else
295
# define ZYAN_STATIC_ASSERT(x) \
296
typedef int ZYAN_MACRO_CONCAT_EXPAND(ZYAN_SASSERT_, __COUNTER__) [(x) ? 1 : -1]
297
#endif
298
302
#if defined(ZYAN_RELEASE)
303
# if defined(ZYAN_CLANG)
// GCC eagerly evals && RHS, we have to use nested ifs.
304
# if __has_builtin(__builtin_unreachable)
305
# define ZYAN_UNREACHABLE __builtin_unreachable()
306
# else
307
# define ZYAN_UNREACHABLE for(;;)
308
# endif
309
# elif defined(ZYAN_GCC) && ((__GNUC__ == 4 && __GNUC_MINOR__ > 4) || __GNUC__ > 4)
310
# define ZYAN_UNREACHABLE __builtin_unreachable()
311
# elif defined(ZYAN_ICC)
312
# ifdef ZYAN_WINDOWS
313
# include <stdlib.h>
// "missing return statement" workaround
314
# define ZYAN_UNREACHABLE __assume(0); (void)abort()
315
# else
316
# define ZYAN_UNREACHABLE __builtin_unreachable()
317
# endif
318
# elif defined(ZYAN_MSVC)
319
# define ZYAN_UNREACHABLE __assume(0)
320
# else
321
# define ZYAN_UNREACHABLE for(;;)
322
# endif
323
#elif defined(ZYAN_NO_LIBC)
324
# define ZYAN_UNREACHABLE for(;;)
325
#elif defined(ZYAN_WINDOWS) && defined(ZYAN_KERNEL)
326
# define ZYAN_UNREACHABLE { __fastfail(0); for(;;){} }
327
#else
328
# include <stdlib.h>
329
# define ZYAN_UNREACHABLE { assert(0); abort(); }
330
#endif
331
332
/* ============================================================================================== */
333
/* Utils */
334
/* ============================================================================================== */
335
336
/* ---------------------------------------------------------------------------------------------- */
337
/* General purpose */
338
/* ---------------------------------------------------------------------------------------------- */
339
345
#define ZYAN_UNUSED(x) (void)(x)
346
350
#if defined(ZYAN_GCC) && __GNUC__ >= 7
351
# define ZYAN_FALLTHROUGH ; __attribute__((__fallthrough__))
352
#else
353
# define ZYAN_FALLTHROUGH
354
#endif
355
361
#define ZYAN_BITFIELD(x) : x
362
366
#define ZYAN_REQUIRES_LIBC
367
374
#if defined(__RESHARPER__)
375
# define ZYAN_PRINTF_ATTR(format_index, first_to_check) \
376
[[gnu::format(printf, format_index, first_to_check)]]
377
#elif defined(ZYAN_GCC)
378
# define ZYAN_PRINTF_ATTR(format_index, first_to_check) \
379
__attribute__((format(printf, format_index, first_to_check)))
380
#else
381
# define ZYAN_PRINTF_ATTR(format_index, first_to_check)
382
#endif
383
390
#if defined(__RESHARPER__)
391
# define ZYAN_WPRINTF_ATTR(format_index, first_to_check) \
392
[[rscpp::format(wprintf, format_index, first_to_check)]]
393
#else
394
# define ZYAN_WPRINTF_ATTR(format_index, first_to_check)
395
#endif
396
397
/* ---------------------------------------------------------------------------------------------- */
398
/* Arrays */
399
/* ---------------------------------------------------------------------------------------------- */
400
408
#define ZYAN_ARRAY_LENGTH(a) (sizeof(a) / sizeof((a)[0]))
409
410
/* ---------------------------------------------------------------------------------------------- */
411
/* Arithmetic */
412
/* ---------------------------------------------------------------------------------------------- */
413
422
#define ZYAN_MIN(a, b) (((a) < (b)) ? (a) : (b))
423
432
#define ZYAN_MAX(a, b) (((a) > (b)) ? (a) : (b))
433
441
#define ZYAN_ABS(a) (((a) < 0) ? -(a) : (a))
442
452
#define ZYAN_IS_POWER_OF_2(x) (((x) & ((x) - 1)) == 0)
453
459
#define ZYAN_IS_ALIGNED_TO(x, align) (((x) & ((align) - 1)) == 0)
460
471
#define ZYAN_ALIGN_UP(x, align) (((x) + (align) - 1) & ~((align) - 1))
472
483
#define ZYAN_ALIGN_DOWN(x, align) (((x) - 1) & ~((align) - 1))
484
492
#if defined(ZYAN_LINUX) && defined(ZYAN_KERNEL)
493
# include <asm/div64.h>
/* do_div */
494
# define ZYAN_DIV64(n, divisor) do_div(n, divisor)
495
#else
496
# define ZYAN_DIV64(n, divisor) (n /= divisor)
497
#endif
498
499
/* ---------------------------------------------------------------------------------------------- */
500
/* Bit operations */
501
/* ---------------------------------------------------------------------------------------------- */
502
503
/*
504
* Checks, if the bit at index `b` is required to present the ordinal value `n`.
505
*
506
* @param n The ordinal value.
507
* @param b The bit index.
508
*
509
* @return `ZYAN_TRUE`, if the bit at index `b` is required to present the ordinal value `n` or
510
* `ZYAN_FALSE`, if not.
511
*
512
* Note that this macro always returns `ZYAN_FALSE` for `n == 0`.
513
*/
514
#define ZYAN_NEEDS_BIT(n, b) (((unsigned long)(n) >> (b)) > 0)
515
516
/*
517
* Returns the number of bits required to represent the ordinal value `n`.
518
*
519
* @param n The ordinal value.
520
*
521
* @return The number of bits required to represent the ordinal value `n`.
522
*
523
* Note that this macro returns `0` for `n == 0`.
524
*/
525
#define ZYAN_BITS_TO_REPRESENT(n) \
526
( \
527
ZYAN_NEEDS_BIT(n, 0) + ZYAN_NEEDS_BIT(n, 1) + \
528
ZYAN_NEEDS_BIT(n, 2) + ZYAN_NEEDS_BIT(n, 3) + \
529
ZYAN_NEEDS_BIT(n, 4) + ZYAN_NEEDS_BIT(n, 5) + \
530
ZYAN_NEEDS_BIT(n, 6) + ZYAN_NEEDS_BIT(n, 7) + \
531
ZYAN_NEEDS_BIT(n, 8) + ZYAN_NEEDS_BIT(n, 9) + \
532
ZYAN_NEEDS_BIT(n, 10) + ZYAN_NEEDS_BIT(n, 11) + \
533
ZYAN_NEEDS_BIT(n, 12) + ZYAN_NEEDS_BIT(n, 13) + \
534
ZYAN_NEEDS_BIT(n, 14) + ZYAN_NEEDS_BIT(n, 15) + \
535
ZYAN_NEEDS_BIT(n, 16) + ZYAN_NEEDS_BIT(n, 17) + \
536
ZYAN_NEEDS_BIT(n, 18) + ZYAN_NEEDS_BIT(n, 19) + \
537
ZYAN_NEEDS_BIT(n, 20) + ZYAN_NEEDS_BIT(n, 21) + \
538
ZYAN_NEEDS_BIT(n, 22) + ZYAN_NEEDS_BIT(n, 23) + \
539
ZYAN_NEEDS_BIT(n, 24) + ZYAN_NEEDS_BIT(n, 25) + \
540
ZYAN_NEEDS_BIT(n, 26) + ZYAN_NEEDS_BIT(n, 27) + \
541
ZYAN_NEEDS_BIT(n, 28) + ZYAN_NEEDS_BIT(n, 29) + \
542
ZYAN_NEEDS_BIT(n, 30) + ZYAN_NEEDS_BIT(n, 31) \
543
)
544
545
/* ---------------------------------------------------------------------------------------------- */
546
547
/* ============================================================================================== */
548
549
#endif
/* ZYCORE_DEFINES_H */
include
Zycore
Defines.h
Generated by
1.17.0