Zycore
1.5.2
Zyan Core Library for C
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
67
#if defined(__has_include)
68
# define ZYAN_HAS_INCLUDE(name) __has_include(name)
69
#else
70
# define ZYAN_HAS_INCLUDE(name) 0
71
#endif
72
80
#if defined(__has_builtin)
81
# define ZYAN_HAS_BUILTIN(symbol) __has_builtin(symbol)
82
#else
83
# define ZYAN_HAS_BUILTIN(symbol) 0
84
#endif
85
86
/* ============================================================================================== */
87
/* Compiler detection */
88
/* ============================================================================================== */
89
90
#if defined(__clang__)
91
# define ZYAN_CLANG
92
# define ZYAN_GNUC
93
# if defined(_MSC_VER)
94
# define ZYAN_CLANG_CL
95
# define ZYAN_MSVC
96
# endif
97
#elif defined(__ICC) || defined(__INTEL_COMPILER)
98
# define ZYAN_ICC
99
#elif defined(__GNUC__) || defined(__GNUG__)
100
# define ZYAN_GCC
101
# define ZYAN_GNUC
102
#elif defined(_MSC_VER)
103
# define ZYAN_MSVC
104
#elif defined(__BORLANDC__)
105
# define ZYAN_BORLAND
106
#else
107
# define ZYAN_UNKNOWN_COMPILER
108
#endif
109
110
/* ============================================================================================== */
111
/* Platform detection */
112
/* ============================================================================================== */
113
114
#if defined(_WIN32)
115
# define ZYAN_WINDOWS
116
#elif defined(__EMSCRIPTEN__)
117
# define ZYAN_EMSCRIPTEN
118
#elif defined(__wasi__) || defined(__WASI__)
119
// via: https://reviews.llvm.org/D57155
120
# define ZYAN_WASI
121
#elif defined(__APPLE__)
122
# define ZYAN_APPLE
123
# define ZYAN_POSIX
124
#elif defined(__linux)
125
# define ZYAN_LINUX
126
# define ZYAN_POSIX
127
#elif defined(__FreeBSD__)
128
# define ZYAN_FREEBSD
129
# define ZYAN_POSIX
130
#elif defined(__NetBSD__)
131
# define ZYAN_NETBSD
132
# define ZYAN_POSIX
133
#elif defined(sun) || defined(__sun)
134
# define ZYAN_SOLARIS
135
# define ZYAN_POSIX
136
#elif defined(__HAIKU__)
137
# define ZYAN_HAIKU
138
# define ZYAN_POSIX
139
#elif defined(__unix) || defined(__unix__)
140
# define ZYAN_UNIX
141
# define ZYAN_POSIX
142
#elif defined(__posix)
143
# define ZYAN_POSIX
144
#else
145
# define ZYAN_UNKNOWN_PLATFORM
146
#endif
147
148
/* ============================================================================================== */
149
/* Kernel mode detection */
150
/* ============================================================================================== */
151
152
#if (defined(ZYAN_WINDOWS) && defined(_KERNEL_MODE)) || \
153
(defined(ZYAN_APPLE) && defined(KERNEL)) || \
154
(defined(ZYAN_LINUX) && defined(__KERNEL__)) || \
155
(defined(__FreeBSD_kernel__))
156
# define ZYAN_KERNEL
157
#else
158
# define ZYAN_USER
159
#endif
160
161
/* ============================================================================================== */
162
/* Architecture detection */
163
/* ============================================================================================== */
164
165
#if defined(_M_AMD64) || defined(__x86_64__)
166
# define ZYAN_X64
167
# define ZYAN_ARCHITECTURE_WIDTH 64
168
#elif defined(_M_IX86) || defined(__i386__)
169
# define ZYAN_X86
170
# define ZYAN_ARCHITECTURE_WIDTH 32
171
#elif defined(_M_ARM64) || defined(__aarch64__)
172
# define ZYAN_AARCH64
173
# define ZYAN_ARCHITECTURE_WIDTH 64
174
#elif defined(_M_ARM) || defined(_M_ARMT) || defined(__arm__) || defined(__thumb__)
175
# define ZYAN_ARM
176
# define ZYAN_ARCHITECTURE_WIDTH 32
177
#elif defined(__EMSCRIPTEN__) || defined(__wasm__) || defined(__WASM__)
178
# define ZYAN_WASM
179
# define ZYAN_ARCHITECTURE_WIDTH 32
180
#elif defined(__loongarch__)
181
# define ZYAN_LOONGARCH
182
# define ZYAN_ARCHITECTURE_WIDTH 64
183
#elif defined(__powerpc64__)
184
# define ZYAN_PPC64
185
# define ZYAN_ARCHITECTURE_WIDTH 64
186
#elif defined(__powerpc__)
187
# define ZYAN_PPC
188
# define ZYAN_ARCHITECTURE_WIDTH 32
189
#elif defined(__riscv) || defined(__riscv__)
190
# if __riscv_xlen == 64
191
# define ZYAN_RISCV64
192
# define ZYAN_ARCHITECTURE_WIDTH 64
193
# else
194
# define ZYAN_RISCV32
195
# define ZYAN_ARCHITECTURE_WIDTH 32
196
# endif
197
#elif defined(__arc__)
198
# define ZYAN_ARC
199
#elif defined(__s390x__)
200
# define ZYAN_S390
201
#elif defined(__sparc__)
202
# define ZYAN_SPARC
203
#elif defined(__mips__)
204
# define ZYAN_MIPS
205
#else
206
# error "Unsupported architecture detected"
207
#endif
208
209
#if !defined(ZYAN_ARCHITECTURE_WIDTH)
210
# if defined(__LP64__)
211
# define ZYAN_ARCHITECTURE_WIDTH 64
212
# else
213
# define ZYAN_ARCHITECTURE_WIDTH 32
214
# endif
215
#endif
216
217
/* ============================================================================================== */
218
/* Endianness detection */
219
/* ============================================================================================== */
220
221
#define ZYAN_LITTLE_ENDIAN 0
222
#define ZYAN_BIG_ENDIAN 1
223
224
#if !defined(ZYAN_NO_LIBC) && ZYAN_HAS_INCLUDE(<stdbit.h>)
225
# include <stdbit.h>
226
# if __STDC_ENDIAN_NATIVE__ == __STDC_ENDIAN_LITTLE__
227
# define ZYAN_ENDIAN ZYAN_LITTLE_ENDIAN
228
# elif __STDC_ENDIAN_NATIVE__ == __STDC_ENDIAN_BIG__
229
# define ZYAN_ENDIAN ZYAN_BIG_ENDIAN
230
# else
231
# error "Unsupported endianness"
232
# endif
233
#elif defined(__BYTE_ORDER__)
234
# if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
235
# define ZYAN_ENDIAN ZYAN_LITTLE_ENDIAN
236
# elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
237
# define ZYAN_ENDIAN ZYAN_BIG_ENDIAN
238
# else
239
# error "Unsupported endianness"
240
# endif
241
#elif defined(ZYAN_S390) || defined(ZYAN_SPARC) || defined(ZYAN_MIPS)
242
# define ZYAN_ENDIAN ZYAN_BIG_ENDIAN
243
#else
244
# define ZYAN_ENDIAN ZYAN_LITTLE_ENDIAN
245
#endif
246
247
/* ============================================================================================== */
248
/* Debug/Release detection */
249
/* ============================================================================================== */
250
251
#if defined(ZYAN_MSVC) || defined(ZYAN_BORLAND)
252
# ifdef _DEBUG
253
# define ZYAN_DEBUG
254
# else
255
# define ZYAN_RELEASE
256
# endif
257
#elif defined(ZYAN_GNUC) || defined(ZYAN_ICC)
258
# ifdef NDEBUG
259
# define ZYAN_RELEASE
260
# else
261
# define ZYAN_DEBUG
262
# endif
263
#else
264
# define ZYAN_RELEASE
265
#endif
266
267
/* ============================================================================================== */
268
/* Deprecation hint */
269
/* ============================================================================================== */
270
271
#if defined(ZYAN_GCC) || defined(ZYAN_CLANG)
272
# define ZYAN_DEPRECATED __attribute__((__deprecated__))
273
#elif defined(ZYAN_MSVC)
274
# define ZYAN_DEPRECATED __declspec(deprecated)
275
#else
276
# define ZYAN_DEPRECATED
277
#endif
278
279
/* ============================================================================================== */
280
/* Generic DLL import/export helpers */
281
/* ============================================================================================== */
282
283
#if defined(ZYAN_MSVC) || (defined(ZYAN_WINDOWS) && defined(ZYAN_GNUC))
284
# define ZYAN_DLLEXPORT __declspec(dllexport)
285
# define ZYAN_DLLIMPORT __declspec(dllimport)
286
#else
287
# if defined(ZYAN_GNUC)
288
# define ZYAN_DLLEXPORT __attribute__((__visibility__("default")))
289
# define ZYAN_DLLIMPORT extern
290
# else
291
# define ZYAN_DLLEXPORT
292
# define ZYAN_DLLIMPORT
293
# endif
294
#endif
295
296
/* ============================================================================================== */
297
/* Zycore dll{export,import} */
298
/* ============================================================================================== */
299
300
// This is a cut-down version of what CMake's `GenerateExportHeader` would usually generate. To
301
// simplify builds without CMake, we define these things manually instead of relying on CMake
302
// to generate the header.
303
//
304
// For static builds, our CMakeList will define `ZYCORE_STATIC_BUILD`. For shared library builds,
305
// our CMake will define `ZYCORE_SHOULD_EXPORT` depending on whether the target is being imported or
306
// exported. If CMake isn't used, users can manually define these to fit their use-case.
307
308
// Backward compatibility: CMake would previously generate these variables names. However, because
309
// they have pretty cryptic names, we renamed them when we got rid of `GenerateExportHeader`. For
310
// backward compatibility for users that don't use CMake and previously manually defined these, we
311
// translate the old defines here and print a warning.
312
#if defined(ZYCORE_STATIC_DEFINE)
313
# pragma message("ZYCORE_STATIC_DEFINE was renamed to ZYCORE_STATIC_BUILD.")
314
# define ZYCORE_STATIC_BUILD
315
#endif
316
#if defined(Zycore_EXPORTS)
317
# pragma message("Zycore_EXPORTS was renamed to ZYCORE_SHOULD_EXPORT.")
318
# define ZYCORE_SHOULD_EXPORT
319
#endif
320
324
#if defined(ZYCORE_STATIC_BUILD)
325
# define ZYCORE_EXPORT
326
#else
327
# if defined(ZYCORE_SHOULD_EXPORT)
328
# define ZYCORE_EXPORT ZYAN_DLLEXPORT
329
# else
330
# define ZYCORE_EXPORT ZYAN_DLLIMPORT
331
# endif
332
#endif
333
337
#if defined(ZYAN_GNUC)
338
# define ZYCORE_NO_EXPORT __attribute__((__visibility__("hidden")))
339
#else
340
# define ZYCORE_NO_EXPORT
341
#endif
342
343
/* ============================================================================================== */
344
/* Misc compatibility macros */
345
/* ============================================================================================== */
346
347
#if defined(ZYAN_CLANG)
348
# define ZYAN_NO_SANITIZE(what) __attribute__((no_sanitize(what)))
349
#else
350
# define ZYAN_NO_SANITIZE(what)
351
#endif
352
353
#if defined(ZYAN_BORLAND)
354
# define ZYAN_INLINE static __inline
355
#else
356
# define ZYAN_INLINE static inline
357
#endif
358
359
#if defined(ZYAN_MSVC)
360
# define ZYAN_NOINLINE __declspec(noinline)
361
#elif defined(ZYAN_GCC) || defined(ZYAN_CLANG)
362
# define ZYAN_NOINLINE __attribute__((noinline))
363
#else
364
# define ZYAN_NOINLINE
365
#endif
366
367
/* ============================================================================================== */
368
/* Debugging and optimization macros */
369
/* ============================================================================================== */
370
374
#if defined(ZYAN_NO_LIBC)
375
# define ZYAN_ASSERT(condition) (void)(condition)
376
#elif defined(ZYAN_WINDOWS) && defined(ZYAN_KERNEL)
377
# include <wdm.h>
378
# define ZYAN_ASSERT(condition) NT_ASSERT(condition)
379
#else
380
# include <assert.h>
381
# define ZYAN_ASSERT(condition) assert(condition)
382
#endif
383
387
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L && !defined(__cplusplus)
388
# define ZYAN_STATIC_ASSERT(x) _Static_assert(x, #x)
389
#elif (defined(__cplusplus) && __cplusplus >= 201103L) || \
390
(defined(__cplusplus) && defined (_MSC_VER) && (_MSC_VER >= 1600)) || \
391
(defined (_MSC_VER) && (_MSC_VER >= 1800))
392
# define ZYAN_STATIC_ASSERT(x) static_assert(x, #x)
393
#elif defined(ZYAN_GNUC)
394
# define ZYAN_STATIC_ASSERT(x) \
395
__attribute__((unused)) typedef int ZYAN_MACRO_CONCAT_EXPAND(ZYAN_SASSERT_, __COUNTER__) [(x) ? 1 : -1]
396
#else
397
# define ZYAN_STATIC_ASSERT(x) \
398
typedef int ZYAN_MACRO_CONCAT_EXPAND(ZYAN_SASSERT_, __COUNTER__) [(x) ? 1 : -1]
399
#endif
400
404
#if defined(ZYAN_RELEASE)
405
# if defined(ZYAN_CLANG)
// GCC eagerly evals && RHS, we have to use nested ifs.
406
# if __has_builtin(__builtin_unreachable)
407
# define ZYAN_UNREACHABLE __builtin_unreachable()
408
# else
409
# define ZYAN_UNREACHABLE for(;;)
410
# endif
411
# elif defined(ZYAN_GCC) && ((__GNUC__ == 4 && __GNUC_MINOR__ > 4) || __GNUC__ > 4)
412
# define ZYAN_UNREACHABLE __builtin_unreachable()
413
# elif defined(ZYAN_ICC)
414
# ifdef ZYAN_WINDOWS
415
# include <stdlib.h>
// "missing return statement" workaround
416
# define ZYAN_UNREACHABLE __assume(0); (void)abort()
417
# else
418
# define ZYAN_UNREACHABLE __builtin_unreachable()
419
# endif
420
# elif defined(ZYAN_MSVC)
421
# define ZYAN_UNREACHABLE __assume(0)
422
# else
423
# define ZYAN_UNREACHABLE for(;;)
424
# endif
425
#elif defined(ZYAN_NO_LIBC)
426
# define ZYAN_UNREACHABLE for(;;)
427
#elif defined(ZYAN_WINDOWS) && defined(ZYAN_KERNEL)
428
# define ZYAN_UNREACHABLE { __fastfail(0); for(;;){} }
429
#else
430
# include <stdlib.h>
431
# define ZYAN_UNREACHABLE { assert(0); abort(); }
432
#endif
433
434
/* ============================================================================================== */
435
/* Utils */
436
/* ============================================================================================== */
437
438
/* ---------------------------------------------------------------------------------------------- */
439
/* General purpose */
440
/* ---------------------------------------------------------------------------------------------- */
441
447
#define ZYAN_UNUSED(x) (void)(x)
448
452
#if defined(ZYAN_GCC) && __GNUC__ >= 7
453
# define ZYAN_FALLTHROUGH ; __attribute__((__fallthrough__))
454
#else
455
# define ZYAN_FALLTHROUGH
456
#endif
457
463
#define ZYAN_BITFIELD(x) : x
464
468
#define ZYAN_REQUIRES_LIBC
469
476
#if defined(__RESHARPER__)
477
# define ZYAN_PRINTF_ATTR(format_index, first_to_check) \
478
[[gnu::format(printf, format_index, first_to_check)]]
479
#elif defined(ZYAN_GCC)
480
# define ZYAN_PRINTF_ATTR(format_index, first_to_check) \
481
__attribute__((format(printf, format_index, first_to_check)))
482
#else
483
# define ZYAN_PRINTF_ATTR(format_index, first_to_check)
484
#endif
485
492
#if defined(__RESHARPER__)
493
# define ZYAN_WPRINTF_ATTR(format_index, first_to_check) \
494
[[rscpp::format(wprintf, format_index, first_to_check)]]
495
#else
496
# define ZYAN_WPRINTF_ATTR(format_index, first_to_check)
497
#endif
498
499
/* ---------------------------------------------------------------------------------------------- */
500
/* Arrays */
501
/* ---------------------------------------------------------------------------------------------- */
502
510
#define ZYAN_ARRAY_LENGTH(a) (sizeof(a) / sizeof((a)[0]))
511
512
/* ---------------------------------------------------------------------------------------------- */
513
/* Arithmetic */
514
/* ---------------------------------------------------------------------------------------------- */
515
524
#define ZYAN_MIN(a, b) (((a) < (b)) ? (a) : (b))
525
534
#define ZYAN_MAX(a, b) (((a) > (b)) ? (a) : (b))
535
543
#define ZYAN_ABS(a) (((a) < 0) ? -(a) : (a))
544
554
#define ZYAN_IS_POWER_OF_2(x) (((x) & ((x) - 1)) == 0)
555
561
#define ZYAN_IS_ALIGNED_TO(x, align) (((x) & ((align) - 1)) == 0)
562
573
#define ZYAN_ALIGN_UP(x, align) (((x) + (align) - 1) & ~((align) - 1))
574
585
#define ZYAN_ALIGN_DOWN(x, align) (((x) - 1) & ~((align) - 1))
586
594
#if defined(ZYAN_LINUX) && defined(ZYAN_KERNEL)
595
# include <asm/div64.h>
/* do_div */
596
# define ZYAN_DIV64(n, divisor) do_div((n), (divisor))
597
#else
598
# define ZYAN_DIV64(n, divisor) ((n) /= (divisor))
599
#endif
600
601
/* ---------------------------------------------------------------------------------------------- */
602
/* Bit operations */
603
/* ---------------------------------------------------------------------------------------------- */
604
605
/*
606
* Checks, if the bit at index `b` is required to present the ordinal value `n`.
607
*
608
* @param n The ordinal value.
609
* @param b The bit index.
610
*
611
* @return `ZYAN_TRUE`, if the bit at index `b` is required to present the ordinal value `n` or
612
* `ZYAN_FALSE`, if not.
613
*
614
* Note that this macro always returns `ZYAN_FALSE` for `n == 0`.
615
*/
616
#define ZYAN_NEEDS_BIT(n, b) (((unsigned long)(n) >> (b)) > 0)
617
618
/*
619
* Returns the number of bits required to represent the ordinal value `n`.
620
*
621
* @param n The ordinal value.
622
*
623
* @return The number of bits required to represent the ordinal value `n`.
624
*
625
* Note that this macro returns `0` for `n == 0`.
626
*/
627
#define ZYAN_BITS_TO_REPRESENT(n) \
628
( \
629
ZYAN_NEEDS_BIT(n, 0) + ZYAN_NEEDS_BIT(n, 1) + \
630
ZYAN_NEEDS_BIT(n, 2) + ZYAN_NEEDS_BIT(n, 3) + \
631
ZYAN_NEEDS_BIT(n, 4) + ZYAN_NEEDS_BIT(n, 5) + \
632
ZYAN_NEEDS_BIT(n, 6) + ZYAN_NEEDS_BIT(n, 7) + \
633
ZYAN_NEEDS_BIT(n, 8) + ZYAN_NEEDS_BIT(n, 9) + \
634
ZYAN_NEEDS_BIT(n, 10) + ZYAN_NEEDS_BIT(n, 11) + \
635
ZYAN_NEEDS_BIT(n, 12) + ZYAN_NEEDS_BIT(n, 13) + \
636
ZYAN_NEEDS_BIT(n, 14) + ZYAN_NEEDS_BIT(n, 15) + \
637
ZYAN_NEEDS_BIT(n, 16) + ZYAN_NEEDS_BIT(n, 17) + \
638
ZYAN_NEEDS_BIT(n, 18) + ZYAN_NEEDS_BIT(n, 19) + \
639
ZYAN_NEEDS_BIT(n, 20) + ZYAN_NEEDS_BIT(n, 21) + \
640
ZYAN_NEEDS_BIT(n, 22) + ZYAN_NEEDS_BIT(n, 23) + \
641
ZYAN_NEEDS_BIT(n, 24) + ZYAN_NEEDS_BIT(n, 25) + \
642
ZYAN_NEEDS_BIT(n, 26) + ZYAN_NEEDS_BIT(n, 27) + \
643
ZYAN_NEEDS_BIT(n, 28) + ZYAN_NEEDS_BIT(n, 29) + \
644
ZYAN_NEEDS_BIT(n, 30) + ZYAN_NEEDS_BIT(n, 31) \
645
)
646
647
/* ---------------------------------------------------------------------------------------------- */
648
649
/* ============================================================================================== */
650
651
#endif
/* ZYCORE_DEFINES_H */
include
Zycore
Defines.h
Generated by
1.15.0