libGimbal 0.1.0
C17-Based Extended Standard Library and Cross-Language Runtime Framework
Loading...
Searching...
No Matches
gimbal_compiler.h
Go to the documentation of this file.
1/*! \file
2 * \brief Helper Definitions for language, compiler, and platform
3 * \ingroup preprocessor
4 * \sa gimbal_macro_utilities.h
5 *
6 * This header contains an assortment of preprocessor definitions
7 * for the following:
8 * - Compiler type
9 * - Architecture type
10 * - C/C++ language revision
11 * - C/C++ language features
12 * - Compiler extensions and features
13 *
14 * \author 2023, 2025 Falco Girgis
15 * \copyright MIT LIicense
16 */
17
18#ifndef GIMBAL_COMPILER_H
19#define GIMBAL_COMPILER_H
20
21#define __STDC_WANT_LIB_EXT1__ 1
22
23#include <stddef.h>
24#include <stdint.h>
25
26// C Version
27#ifdef __STDC_VERSION__
28# define GBL_C89 1
29# if (__STDC_VERSION__ >= 199409L)
30# define GBL_C95 1
31# endif
32# if (__STDC_VERSION__ >= 199901L)
33# define GBL_C99 1
34# endif
35# if (__STDC_VERSION__ >= 201112L)
36# define GBL_C11 1
37# endif
38# if (__STDC_VERSION__ >= 201710L)
39# define GBL_C17 1
40# endif
41# if (__STDC_VERSION__ >= 202311L)
42# define GBL_C23 1
43# endif
44#endif
45
46//C++ Version
47#ifdef __cplusplus
48# if (__cplusplus >= 199711L)
49# define GBL_CPP98 1
50# endif
51# if (__cplusplus >= 201103L)
52# define GBL_CPP11 1
53# endif
54# if (__cplusplus >= 201402L)
55# define GBL_CPP14 1
56# endif
57# if (__cplusplus >= 201703L)
58# define GBL_CPP17 1
59# endif
60# if (__cplusplus >= 202002L)
61# define GBL_CPP20 1
62# endif
63# if (__cplusplus >= 202302L)
64# define GBL_CPP23 1
65# endif
66#endif
67
68
69#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__)
70 // Common for all Windows platforms
71# define GBL_WIN 1
72# ifdef _WIN64
73 // 64-bit Windows only
74# define GBL_WIN64 1
75# else
76 // 32-bit Windows only
77# define GBL_WIN32 1
78# endif
79#elif __APPLE__
80 // Common to all Apple platforms
81# define GBL_APPLE
82# include <TargetConditionals.h>
83# if TARGET_IPHONE_SIMULATOR
84 // iOS, tvOS, or watchOS Simulator
85# define GBL_IOS_SIMULATOR 1
86# elif TARGET_OS_MACCATALYST
87 // Mac's Catalyst (ports iOS API into Mac, like UIKit).
88# define GBL_MACCATALYST 1
89# elif TARGET_OS_IPHONE
90 // iOS, tvOS, or watchOS device
91# define GBL_IOS 1
92# elif TARGET_OS_MAC
93 // Other kinds of Apple platforms
94# define GBL_MACOS 1
95# else
96# error "Unknown Apple platform"
97# endif
98#elif __ANDROID__
99 // Below __linux__ check should be enough to handle Android,
100 // but something may be unique to Android.
101# define GBL_ANDROID 1
102#elif defined(__DREAMCAST__)
103# define GBL_DREAMCAST 1
104#elif defined(__GAMECUBE__)
105# define GBL_GAMECUBE 1
106#elif defined(__PSP__)
107# define GBL_PSP 1
108#elif defined(VITA)
109# define GBL_PSVITA 1
110#elif __linux__
111# define GBL_LINUX 1
112#elif __unix__ // all unices not caught above
113 // Unix
114# define GBL_UNIX 1
115#elif defined(_POSIX_VERSION)
116 // POSIX
117# define GBL_POSIX
118#endif
119
120#ifdef __GNUC__
121# define GBL_GNUC 1
122#endif
123
124#ifdef _MSC_VER
125# define GBL_MSVC 1
126#elif defined(__ICC)
127# define GBL_ICC 1
128#elif defined(__clang__)
129# define GBL_CLANG 1
130#elif defined(__MINGW32__)
131# define GBL_MINGW32 1
132#elif defined(__MINGW64__)
133# define GBL_MINGW64 1
134#elif defined(__EMSCRIPTEN__)
135# define GBL_EMSCRIPTEN 1
136#elif defined(__GNUC__)
137# define GBL_GCC 1
138#elif defined(__ghs__)
139# define GBL_GREENHILL 1
140#elif defined(__CC_ARM)
141# define GBL_ARMCC 1
142#elif defined(__IAR_SYSTEMS__ICC__)
143# define GBL_IAR 1
144#endif
145
146#if defined(__x86_64__) || defined(_M_X64)
147# define GBL_X86_64 1
148#elif defined(i386) || defined(__i386__) || defined(__i386) || defined(_M_IX86)
149# define GBL_X86_32 1
150#elif defined(__ARM_ARCH_2__)
151# define GBL_ARM2 1
152#elif defined(__ARM_ARCH_3__) || defined(__ARM_ARCH_3M__)
153# define GBL_ARM3 1
154#elif defined(__ARM_ARCH_4T__) || defined(__TARGET_ARM_4T)
155# define GBL_ARM4T 1
156#elif defined(__ARM_ARCH_5_) || defined(__ARM_ARCH_5E_)
157# define GBL_ARM5 1
158#elif defined(__ARM_ARCH_6T2_) || defined(__ARM_ARCH_6T2_)
159# define GBL_ARM6T2 1
160#elif defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__)
161# define GBL_ARM6 1
162#elif defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7S__)
163# define GBL_ARM7 1
164#elif defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7S__)
165# define GBL_ARM7A 1
166#elif defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7S__)
167# define GBL_ARM7R 1
168#elif defined(__ARM_ARCH_7M__)
169# define GBL_ARM7M 1
170#elif defined(__ARM_ARCH_7S__)
171# define GBL_ARM7S 1
172#elif defined(__aarch64__) || defined(_M_ARM64)
173# define GBL_ARM64 1
174#elif defined(mips) || defined(__mips__) || defined(__mips)
175# define GBL_MIPS 1
176#elif defined(__sh__)
177# define GBL_SUPERH 1
178#elif defined(__powerpc) || defined(__powerpc__) || defined(__powerpc64__) || defined(__POWERPC__) || defined(__ppc__) || defined(__PPC__) || defined(_ARCH_PPC)
179# define GBL_POWERPC 1
180#elif defined(__PPC64__) || defined(__ppc64__) || defined(_ARCH_PPC64)
181# define GBL_POWERPC64 1
182#elif defined(__sparc__) || defined(__sparc)
183# define GBL_SPARC 1
184#elif defined(__m68k__)
185# define GBL_M68K 1
186#endif
187
188#ifdef GBL_CPP11
189# define GBL_NULL nullptr
190#else
191# define GBL_NULL NULL
192#endif
193
194#if UINTPTR_MAX == 0xffff
195# define GBL_16BIT
196#elif UINTPTR_MAX == 0xffffffff
197# define GBL_32BIT
198#elif UINTPTR_MAX == 0xffffffffffffffff
199# define GBL_64BIT
200#else
201 /* wtf, you're on your own, bro */
202#endif
203
204// Shared library symbol imports/exports
205#ifdef _MSC_VER
206# define GBL_EXPORT_SHARED __declspec(dllexport)
207# define GBL_IMPORT_SHARED __declspec(dllimport)
208#elif defined(__clang__) || defined(__GNUC__)
209# define GBL_EXPORT_SHARED __attribute__((visibility("default")))
210# define GBL_IMPORT_SHARED
211#else
212# define GBL_EXPORT_SHARED
213# define GBL_IMPORT_SHARED
214#endif
215
216#ifdef __cplusplus
217# define GBL_INITIALIZER(f)
218 static void f(void);
219 struct f##_t_ { f##_t_(void) { f(); } }; static f##_t_ f##_;
220 static void f(void)
221#elif defined(_MSC_VER)
222# pragma section(".CRT$XCU",read)
223# define GBL_INITIALIZER2_(f,p)
224 static void f(void);
225 __declspec(allocate(".CRT$XCU")) void (*f##_)(void) = f;
226 __pragma(comment(linker,"/include:" p #f "_"))
227 static void f(void)
228# ifdef _WIN64
229 #define GBL_INITIALIZER(f) GBL_INITIALIZER2_(f,"")
230# else
231 #define GBL_INITIALIZER(f) GBL_INITIALIZER2_(f,"_")
232# endif
233#else
234# define GBL_INITIALIZER(f)
235 static void f(void) __attribute__((constructor));
236 static void f(void)
237#endif
238
239// Thread-local storage
240#ifdef _MSC_VER
241# define GBL_THREAD_LOCAL __declspec(thread)
242#else
243# if defined(__DREAMCAST__) || defined(__GAMECUBE__)
244# define GBL_THREAD_LOCAL _Thread_local
245# elif defined(__PSP__)
246# define GBL_THREAD_LOCAL
247# else
248# define GBL_THREAD_LOCAL __thread
249# endif
250#endif
251
252// Floating-point precision directives
253#ifdef _MSC_VER
254# define GBL_FP_FAST
255 _Pragma("float_control(except, off)") /* disable environment sensitivity */
256 _Pragma("fenv_access(off)") /* disable exception semantics */
257 _Pragma("float_control(precise, off)") /* disable precise semantics */
258 _Pragma("fp_contract(on)") /* enable contractions */
259# define GBL_FP_PRECISE
260 _Pragma("float_control(precise, on)") /* enable precise semantics */
261 _Pragma("fenv_access(on)") /* enable environment sensitivity */
262 _Pragma("float_control(except, on)") /* enable exception semantics */
263#else
264# define GBL_FP_FAST __attribute__((optimize("-ffast-math")))
265# define GBL_FP_PRECISE __attribute__((optimize("-fno-fast-math")))
266#endif
267
268//====== C++ FEATURE SUPPORT ==============
269
270// RTTI
271#ifdef __cpp_rtti
272# define GBL_CPP_RTTI 1
273#elif defined(__clang__)
274# if __has_feature(cxx_rtti)
275# define GBL_CPP_RTTI 1
276# else
277# define GBL_CPP_RTTI 0
278# endif
279#elif defined(__GNUG__) && defined(__GXX_RTTI)
280# define GBL_CPP_RTTI 1
281#elif defined(_MSC_VER) && defined(_CPPRTTI)
282# define GBL_CPP_RTTI 1
283#else
284# define GBL_CPP_RTTI 0
285#endif
286
287// Exceptions
288#ifdef __cpp_exceptions
289# define GBL_CPP_EXCEPTIONS 1
290# define GBL_NOEXCEPT noexcept
291#else
292# define GBL_CPP_EXCEPTIONS 0
293# define GBL_NOEXCEPT
294#endif
295
296#ifdef GBL_CPP11
297# define GBL_CONSTEXPR constexpr
298# ifdef GBL_CPP20
299# define GBL_CONSTEVAL consteval
300# else
301# define GBL_CONSTEVAL constexpr
302# endif
303#else
304# define GBL_CONSTEXPR
305# define GBL_CONSTEVAL
306#endif
307
308// Concepts
309#ifdef __cpp_concepts
310# define GBL_CPP_CONCEPTS 1
311#else
312# define GBL_CPP_CONCEPTS 0
313#endif
314
315
316// Source Location
317#ifdef __cpp_lib_source_location
318# define GBL_CPP_SOURCE_LOCATION 1
319#else
320# define GBL_CPP_SOURCE_LOCATION 0
321#endif
322
323// Deprecated
324#if defined(__has_cpp_attribute)
325# if __has_cpp_attribute(deprecated)
326# define GBL_DEPRECATED(msg) [[deprecated(msg)]]
327# else
328# define GBL_DEPRECATED(msg)
329# endif
330#else
331# define GBL_DEPRECATED(msg)
332#endif
333
334// Fallthrough
335#if defined(__has_cpp_attribute)
336# if __has_cpp_attribute(fallthrough)
337# define GBL_FALLTHROUGH [[fallthrough]]
338# else
339# define GBL_FALLTHROUGH
340# endif
341#else
342# define GBL_FALLTHROUGH
343#endif
344
345// Likely
346#if defined(__has_cpp_attribute)
347# if __has_cpp_attribute(likely)
348# define GBL_LIKELY(exp) (exp) [[likely]]
349# endif
350#endif
351#ifndef GBL_LIKELY
352# ifdef GBL_GNUC
353# define GBL_LIKELY(exp) (__builtin_expect(!!(exp), 1))
354# else
355# define GBL_LIKELY(exp) (exp)
356# endif
357#endif
358
359// unlikely
360#if defined(__has_cpp_attribute)
361# if __has_cpp_attribute(unlikely)
362# define GBL_UNLIKELY(exp) (exp) [[unlikely]]
363# endif
364#endif
365#ifndef GBL_UNLIKELY
366# ifdef GBL_GNUC
367# define GBL_UNLIKELY(exp) (__builtin_expect(!!(exp), 0))
368# else
369# define GBL_UNLIKELY(exp) (exp)
370# endif
371#endif
372
373// Maybe_Unused
374#if defined(__has_cpp_attribute)
375# if __has_cpp_attribute(maybe_unused)
376# define GBL_MAYBE_UNUSED [[maybe_unused]]
377# else
378# define GBL_MAYBE_UNUSED
379# endif
380#elif defined(__clang__) || defined(__GNUC__)
381# define GBL_MAYBE_UNUSED __attribute__((unused))
382#else
383# define GBL_MAYBE_UNUSED
384#endif
385
386// No_Unique_Address
387#if defined(__has_cpp_attribute)
388# if __has_cpp_attribute(no_unique_address)
389# define GBL_NO_UNIQUE_ADDRESS [[no_unique_address]]
390# else
391# define GBL_NO_UNIQUE_ADDRESS
392# endif
393#else
394# define GBL_NO_UNIQUE_ADDRESS
395#endif
396
397// No_Discard
398#if defined(__has_cpp_attribute)
399# if __has_cpp_attribute(nodiscard)
400# define GBL_NODISCARD [[nodiscard]]
401# else
402# define GBL_NODISCARD
403# endif
404#else
405# define GBL_NODISCARD
406#endif
407
408// No_Return (Cpp)
409#if defined(__has_cpp_attribute)
410# if __has_cpp_attribute(noreturn)
411# define GBL_NORETURN [[noreturn]]
412# else
413# define GBL_NORETURN
414# endif
415# else
416# ifdef GBL_C11
417# define GBL_NORETURN _Noreturn
418# else
419# define GBL_NORETURN
420# endif
421#endif
422
423#if __cpp_static_assert
424# if __cpp_static_assert > 201400
425# define GBL_STATIC_ASSERT(cond) static_assert(cond)
426# else
427# define GBL_STATIC_ASSERT(cond) static_assert(cond, #cond)
428# endif
429# define GBL_STATIC_ASSERT_MSG(cond, msg) static_assert(cond, msg)
430#elif defined(GBL_C11)
431# define GBL_STATIC_ASSERT(cond) _Static_assert(cond, #cond);
432# define GBL_STATIC_ASSERT_MSG(cond, msg) _Static_assert(cond, msg);
433#else
434# define GBL_STATIC_ASSERT(cond)
435# define GBL_STATIC_ASSERT_MSG(cond, msg)
436#endif
437
438#ifdef GBL_C99
439# define GBL_RESTRICT restrict
440#else
441# define GBL_RESTRICT
442#endif
443
444#ifdef GBL_C99
445# define GBL_STATIC_ARRAY(idx) static idx
446#else
447# define GBL_STATIC_ARRAY(idx) idx
448#endif
449
450#ifdef __cplusplus
451# define GBL_STRUCT_INIT(type, ...) (type{ __VA_ARGS__ })
452#else
453# define GBL_STRUCT_INIT(type, ...) ((type){ __VA_ARGS__ })
454#endif
455
456#ifdef __cplusplus
457# define GBL_ALIGNAS(e) alignas(e)
458# define GBL_ALIGNOF(e) alignof(e)
459#elif defined(GBL_C11)
460# define GBL_ALIGNAS(e) _Alignas(e)
461# define GBL_ALIGNOF(e) _Alignof(e)
462#endif
463
464#if defined(_MSC_VER) || defined(__MINGW64__)
465# define GBL_ALIGNED_ALLOC(a, s) _aligned_malloc(s, a)
466# define GBL_ALIGNED_REALLOC(p, a, s) _aligned_realloc(p, s, a)
467# define GBL_ALIGNED_FREE(p) _aligned_free(p)
468#elif defined(__MINGW32__)
469# define GBL_ALIGNED_ALLOC(a, s) __mingw_aligned_malloc(s, a)
470# define GBL_ALIGNED_REALLOC(p, a, s) __mingw_aligned_realloc(p, s, a)
471# define GBL_ALIGNED_FREE(p) __mingw_aligned_free(p)
472#elif defined(GBL_C11) || defined(GBL_CPP17)
473# include <stdlib.h>
474# define GBL_ALIGNED_ALLOC(a, s) aligned_alloc(a, s)
475# define GBL_ALIGNED_REALLOC(p, a, s) realloc(p, s)
476# define GBL_ALIGNED_FREE(p) free(p)
477#endif
478
479#if GBL_CONFIG_PREFETCH_ENABLED
480# ifndef GBL_PREFETCH
481# if defined(_MSC_VER) || defined(__MINGW64__)
482# if defined(_M_ARM64) || defined(_M_ARM64EC)
483# include <intrin.h>
484# else
485# include <immintrin.h>
486# endif
487# define GBL_PREFETCH(addr) _mm_prefetch(addr, _MM_HINT_T0)
488# elif defined(__GNUC__)
489# define GBL_PREFETCH __builtin_prefetch
490# endif
491# else
492# define GBL_PREFETCH(...)
493# endif
494#else
495# define GBL_PREFETCH(...)
496#endif
497
498#ifdef __cplusplus
499# define GBL_INLINE_ inline
500#else
501# define GBL_INLINE_ static inline
502#endif
503
504#ifdef __cplusplus
505# define GBL_INLINE GBL_MAYBE_UNUSED GBL_INLINE_
506#else
507# define GBL_INLINE GBL_MAYBE_UNUSED GBL_INLINE_
508#endif
509
510#ifdef __GNUC__
511# define GBL_FORCE_INLINE __attribute__((always_inline)) GBL_INLINE_
512#elif defined(_MSC_VER)
513# define GBL_FORCE_INLINE __forceinline
514#else
515# define GBL_FORCE_INLINE GBL_INLINE
516#endif
517
518#ifdef __GNUC__
519# define GBL_NO_INLINE __attribute__((noinline))
520#elif defined(_MSC_VER)
521# define GBL_NO_INLINE __declspec(noinline)
522#else
523# define GBL_NO_INLINE
524#endif
525
526// ====== NONSTANDARD COMPILER-SPECIFIC C FUNCTIONS ==========
527
528// "Safer" C11 functions with boundaries
529#if 0
530#ifdef __STDC_WANT_LIB_EXT1__
531#define GBL_C11_EXT1 1
532#define GBL_VPRINTF vprintf_s
533#define GBL_VFPRINTF vfprintf_s
534#define GBL_VSPRINTF vsprintf_s
535#define GBL_VSNPRINTF vsnprintf_s
536#define GBL_MEMSET memset_s
537#define GBL_MEMCPY memcpy_s
538#else
539#define GBL_C11_EXT1 0
540#define GBL_VPRINTF vprintf
541#define GBL_VFPRINTF vfprintf
542#define GBL_VSPRINTF vsprintf
543#define GBL_VSNPRINTF vsnprintf
544#define GBL_MEMSET memset
545#define GBL_MEMCPY memcpy
546#endif
547#endif
548
549// alloca()
550#ifndef GBL_ALLOCA
551# if defined(__APPLE__) || defined(__GLIBC__) ||
552 defined(__sun) || defined(__CYGWIN__) ||
553 defined(__EMSCRIPTEN__) || defined(VITA) ||
554 defined(__DREAMCAST__) || defined(PSP) ||
555 defined(__GAMECUBE__)
556# include <alloca.h> // Sane platforms
557# elif defined(_WIN32)
558# include <malloc.h> // Windoez
559# ifndef alloca
560# define alloca _alloca // Clang with MS Codegen
561# endif
562# else
563# include <stdlib.h> // BSD extension
564# endif
565# define GBL_ALLOCA alloca
566#endif
567
568#if __APPLE__ // at very least fucking MacOS headers are missing it!
569# define GBL_QUICK_EXIT(c) exit(c)
570#elif defined(GBL_CPP11)
571# define GBL_QUICK_EXIT(c) quick_exit(c)
572#elif defined(GBL_C11)
573# define GBL_QUICK_EXIT(c) quick_exit(c)
574#else
575# define GBL_QUICK_EXIT(c) exit(c)
576#endif
577
578#ifndef GBL_PRAGMA_MACRO_PUSH
579# define GBL_PRAGMA_MACRO_PUSH(X) push_macro(X)
580#endif
581
582#ifndef GBL_PRAGMA_MACRO_POP
583# define GBL_PRAGMA_MACRO_POP(X) pop_macro(X)
584#endif
585
586#ifdef _MSC_VER
587# define GBL_MAX_ALIGN_T double
588#else
589# define GBL_MAX_ALIGN_T max_align_t
590#endif
591
592#define GBL_ALLOC_MIN_SIZE GBL_ALIGNOF(GBL_MAX_ALIGN_T)
593
594/* ==========================================================
595 * Provide simple macro statement wrappers (adapted from Perl):
596 * G_STMT_START { statements; } G_STMT_END;
597 * can be used as a single statement, as in
598 * if (x) G_STMT_START { ... } G_STMT_END; else ...
599 *
600 * For gcc we will wrap the statements within `({' and `})' braces.
601 * For SunOS they will be wrapped within `if (1)' and `else (void) 0',
602 * and otherwise within `do' and `while (0)'.
603 * ========================================================
604 * Graciously stolen from GLib. Imitation is the most sincere form of flattery.
605 * --Falco Girgis
606 */
607/* REMOVED WHILE TRYING TO AVOID CLANG WARNINGS AND TO BE STANDARD COMPLIANT
608 * # if defined (__GNUC__) && !defined (__STRICT_ANSI__) && !defined (__cplusplus)
609# define GBL_STMT_START (void) __extension__ (
610# define GBL_STMT_END )
611# */
612#if !(defined (GBL_STMT_START) && defined (GBL_STMT_END))
613# if defined (__GNUC__) && !defined (__STRICT_ANSI__) && !defined (__cplusplus)
614# define GBL_STMT_START do
615# define GBL_STMT_END while(0)
616# else
617# if (defined (sun) || defined (__sun__))
618# define GBL_STMT_START if(1)
619# define GBL_STMT_END else(void)0
620# else
621# define GBL_STMT_START do
622# define GBL_STMT_END while(0)
623# endif
624# endif
625#endif
626
627#define GBL_NULL_TERMINATED
628
629#if GBL_MSVC
630# include <stdlib.h>
631# define GBL_BSWAP_U16(v) _byteswap_ushort(v)
632# define GBL_BSWAP_U32(v) _byteswap_ulong(v)
633# define GBL_BSWAP_U64(v) _byteswap_uint64(v)
634#else
635# define GBL_BSWAP_U16(v) __builtin_bswap16(v)
636# define GBL_BSWAP_U32(v) __builtin_bswap32(v)
637# define GBL_BSWAP_U64(v) __builtin_bswap64(v)
638#endif
639
640// Low-Level BitMask Operations
641#ifdef GBL_CPP20
642# include <bit>
643# define GBL_BITMASK_CLZ(mask) std::countl_zero(mask)
644# define GBL_BITMASK_CTZ(mask) std::countr_zero(mask)
645 inline constexpr auto GBL_BITMASK_FFS(auto mask) noexcept {
646 const auto idx = GBL_BITMASK_CLZ(mask);
647 return idx? idx + 1 : 0;
648 }
649# define GBL_BITMASK_POPCOUNT(mask) std::popcount(mask)
650#else
651# define GBL_BITMASK_POPCOUNT_SW(mask)
652 (((mask) >= sizeof(unsigned long) * CHAR_BIT) ?
653 (unsigned long) -1 : (1u << (mask)) - 1)
654
655# if defined(__clang__) || defined(__GNUC__)
656# define GBL_BITMASK_CLZ(mask) __builtin_clz(mask) // count leading zeroes
657# define GBL_BITMASK_CTZ(mask) __builtin_ctz(mask) // count trailing zeroes
658# define GBL_BITMASK_FFS(mask) __builtin_ffs(mask) // find first set
659# define GBL_BITMASK_POPCOUNT(mask) __builtin_popcount(mask) // count number of 1s
660# elif defined(_MSC_VER)
661# include <intrin.h>
662 GBL_CONSTEXPR GBL_INLINE unsigned GBL_BITMASK_CLZ(unsigned mask) GBL_NOEXCEPT {
663 unsigned long idx = 0;
664 return _BitScanReverse(&idx, mask)? ((sizeof(unsigned) * 8) - idx) : 0;
665 }
666 GBL_CONSTEXPR GBL_INLINE unsigned GBL_BITMASK_CTZ(unsigned mask) GBL_NOEXCEPT {
667 unsigned long idx = 0;
668 return _BitScanForward(&idx, mask)? idx : 0;
669 }
670 GBL_CONSTEXPR GBL_INLINE unsigned GBL_BITMASK_FFS(unsigned mask) GBL_NOEXCEPT {
671 const unsigned idx = GBL_BITMASK_CTZ(mask);
672 return idx? idx + 1 : 0;
673 }
674# define GBL_BITMASK_POPCOUNT(mask) GBL_BITMASK_POPCOUNT_SW(mask)
675# else
676# define GBL_BITMASK_CLZ(mask) // implement me in software later TODO
677# define GBL_BITMASK_CTZ(mask)
678# define GBL_BITMASK_FFS(mask)
679# define GBL_BITMASK_POPCOUNT(mask) GBL_BITMASK_POPCOUNT_SW(mask)
680# endif
681#endif
682
683#endif // GIMBAL_COMPILER_H
#define GBL_MAX_ALIGN_T
#define GBL_UNLIKELY(exp)
#define GBL_MAYBE_UNUSED
#define GBL_LIKELY(exp)
#define GBL_INLINE_