2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
18#ifndef GIMBAL_COMPILER_H
19#define GIMBAL_COMPILER_H
21#define __STDC_WANT_LIB_EXT1__ 1
27#ifdef __STDC_VERSION__
29# if (__STDC_VERSION__ >= 199409L
)
32# if (__STDC_VERSION__ >= 199901L
)
35# if (__STDC_VERSION__ >= 201112L
)
38# if (__STDC_VERSION__ >= 201710L
)
41# if (__STDC_VERSION__ >= 202311L
)
48# if (__cplusplus
>= 199711L
)
51# if (__cplusplus
>= 201103L
)
54# if (__cplusplus
>= 201402L
)
57# if (__cplusplus
>= 201703L
)
60# if (__cplusplus
>= 202002L
)
63# if (__cplusplus
>= 202302L
)
69#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__)
82# include <TargetConditionals.h>
83# if TARGET_IPHONE_SIMULATOR
85# define GBL_IOS_SIMULATOR 1
86# elif TARGET_OS_MACCATALYST
88# define GBL_MACCATALYST 1
89# elif TARGET_OS_IPHONE
96# error "Unknown Apple platform"
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__)
115#elif defined(_POSIX_VERSION)
128#elif defined(__clang__
)
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__)
138#elif defined(__ghs__)
139# define GBL_GREENHILL 1
140#elif defined(__CC_ARM)
142#elif defined(__IAR_SYSTEMS__ICC__)
146#if defined(__x86_64__
) || defined(_M_X64)
148#elif defined(i386) || defined(__i386__) || defined(__i386) || defined(_M_IX86)
150#elif defined(__ARM_ARCH_2__)
152#elif defined(__ARM_ARCH_3__) || defined(__ARM_ARCH_3M__)
154#elif defined(__ARM_ARCH_4T__) || defined(__TARGET_ARM_4T)
156#elif defined(__ARM_ARCH_5_) || defined(__ARM_ARCH_5E_)
158#elif defined(__ARM_ARCH_6T2_) || defined(__ARM_ARCH_6T2_)
160#elif defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__)
162#elif defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7S__)
164#elif defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7S__)
166#elif defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7S__)
168#elif defined(__ARM_ARCH_7M__)
170#elif defined(__ARM_ARCH_7S__)
172#elif defined(__aarch64__) || defined(_M_ARM64)
174#elif defined(mips) || defined(__mips__) || defined(__mips)
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)
184#elif defined(__m68k__)
189# define GBL_NULL nullptr
191# define GBL_NULL NULL
194#if UINTPTR_MAX
== 0xffff
196#elif UINTPTR_MAX
== 0xffffffff
198#elif UINTPTR_MAX
== 0xffffffffffffffff
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
212# define GBL_EXPORT_SHARED
213# define GBL_IMPORT_SHARED
217# define GBL_INITIALIZER(f)
219 struct f##_t_ { f##_t_(void) { f(); } }; static f##_t_ f##_;
221#elif defined(_MSC_VER)
222# pragma section(".CRT$XCU",read)
223# define GBL_INITIALIZER2_(f,p)
225 __declspec(allocate(".CRT$XCU")) void (*f##_)(void) = f;
226 __pragma(comment(linker,"/include:" p #f "_"))
229 #define GBL_INITIALIZER(f) GBL_INITIALIZER2_(f,"")
231 #define GBL_INITIALIZER(f) GBL_INITIALIZER2_(f,"_")
234# define GBL_INITIALIZER(f)
235 static void f(void) __attribute__((constructor));
241# define GBL_THREAD_LOCAL __declspec(thread)
243# if defined(__DREAMCAST__) || defined(__GAMECUBE__)
244# define GBL_THREAD_LOCAL _Thread_local
245# elif defined(__PSP__)
246# define GBL_THREAD_LOCAL
248# define GBL_THREAD_LOCAL __thread
255 _Pragma("float_control(except, off)")
256 _Pragma("fenv_access(off)")
257 _Pragma("float_control(precise, off)")
258 _Pragma("fp_contract(on)")
259# define GBL_FP_PRECISE
260 _Pragma("float_control(precise, on)")
261 _Pragma("fenv_access(on)")
262 _Pragma("float_control(except, on)")
264# define GBL_FP_FAST __attribute__((optimize("-ffast-math")))
265# define GBL_FP_PRECISE __attribute__((optimize("-fno-fast-math")))
272# define GBL_CPP_RTTI 1
273#elif defined(__clang__)
274# if __has_feature(cxx_rtti)
275# define GBL_CPP_RTTI 1
277# define GBL_CPP_RTTI 0
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
284# define GBL_CPP_RTTI 0
288#ifdef __cpp_exceptions
289# define GBL_CPP_EXCEPTIONS 1
290# define GBL_NOEXCEPT noexcept
292# define GBL_CPP_EXCEPTIONS 0
297# define GBL_CONSTEXPR constexpr
299# define GBL_CONSTEVAL consteval
301# define GBL_CONSTEVAL constexpr
304# define GBL_CONSTEXPR
305# define GBL_CONSTEVAL
310# define GBL_CPP_CONCEPTS 1
312# define GBL_CPP_CONCEPTS 0
317#ifdef __cpp_lib_source_location
318# define GBL_CPP_SOURCE_LOCATION 1
320# define GBL_CPP_SOURCE_LOCATION 0
324#if defined(__has_cpp_attribute
)
325# if __has_cpp_attribute
(deprecated)
326# define GBL_DEPRECATED(msg) [[deprecated(msg)]]
328# define GBL_DEPRECATED(msg)
331# define GBL_DEPRECATED(msg)
335#if defined(__has_cpp_attribute
)
336# if __has_cpp_attribute
(fallthrough)
337# define GBL_FALLTHROUGH [[fallthrough]]
339# define GBL_FALLTHROUGH
342# define GBL_FALLTHROUGH
346#if defined(__has_cpp_attribute
)
347# if __has_cpp_attribute
(likely)
348# define GBL_LIKELY(exp) (exp) [[likely]]
353# define GBL_LIKELY(exp) (__builtin_expect(!!(exp), 1
))
355# define GBL_LIKELY(exp) (exp)
360#if defined(__has_cpp_attribute
)
361# if __has_cpp_attribute
(unlikely)
362# define GBL_UNLIKELY(exp) (exp) [[unlikely]]
367# define GBL_UNLIKELY(exp) (__builtin_expect(!!(exp), 0
))
369# define GBL_UNLIKELY(exp) (exp)
374#if defined(__has_cpp_attribute
)
375# if __has_cpp_attribute
(maybe_unused)
376# define GBL_MAYBE_UNUSED [[maybe_unused]]
378# define GBL_MAYBE_UNUSED
380#elif defined(__clang__) || defined(__GNUC__)
381# define GBL_MAYBE_UNUSED __attribute__((unused))
383# define GBL_MAYBE_UNUSED
387#if defined(__has_cpp_attribute
)
388# if __has_cpp_attribute
(no_unique_address)
389# define GBL_NO_UNIQUE_ADDRESS [[no_unique_address]]
391# define GBL_NO_UNIQUE_ADDRESS
394# define GBL_NO_UNIQUE_ADDRESS
398#if defined(__has_cpp_attribute
)
399# if __has_cpp_attribute
(nodiscard)
400# define GBL_NODISCARD [[nodiscard]]
402# define GBL_NODISCARD
405# define GBL_NODISCARD
409#if defined(__has_cpp_attribute
)
410# if __has_cpp_attribute
(noreturn)
411# define GBL_NORETURN [[noreturn]]
417# define GBL_NORETURN _Noreturn
423#if __cpp_static_assert
424# if __cpp_static_assert
> 201400
425# define GBL_STATIC_ASSERT(cond) static_assert(cond)
427# define GBL_STATIC_ASSERT(cond) static_assert(cond, #cond)
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);
434# define GBL_STATIC_ASSERT(cond)
435# define GBL_STATIC_ASSERT_MSG(cond, msg)
439# define GBL_RESTRICT restrict
445# define GBL_STATIC_ARRAY(idx) static idx
447# define GBL_STATIC_ARRAY(idx) idx
451# define GBL_STRUCT_INIT(type, ...) (type{ __VA_ARGS__ })
453# define GBL_STRUCT_INIT(type, ...) ((type){ __VA_ARGS__ })
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)
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
)
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)
479#if GBL_CONFIG_PREFETCH_ENABLED
481# if defined(_MSC_VER) || defined(__MINGW64__)
482# if defined(_M_ARM64) || defined(_M_ARM64EC)
485# include <immintrin.h>
487# define GBL_PREFETCH(addr) _mm_prefetch(addr, _MM_HINT_T0)
488# elif defined(__GNUC__)
489# define GBL_PREFETCH __builtin_prefetch
492# define GBL_PREFETCH(...)
495# define GBL_PREFETCH(...)
499# define GBL_INLINE_ inline
501# define GBL_INLINE_ static inline
507# define GBL_INLINE GBL_MAYBE_UNUSED GBL_INLINE_
511# define GBL_FORCE_INLINE __attribute__((always_inline)) GBL_INLINE_
512#elif defined(_MSC_VER)
513# define GBL_FORCE_INLINE __forceinline
515# define GBL_FORCE_INLINE GBL_INLINE
519# define GBL_NO_INLINE __attribute__((noinline))
520#elif defined(_MSC_VER)
521# define GBL_NO_INLINE __declspec(noinline)
523# define GBL_NO_INLINE
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
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
551# if defined(__APPLE__) || defined(__GLIBC__
) ||
552 defined(__sun) || defined(__CYGWIN__) ||
553 defined(__EMSCRIPTEN__) || defined(VITA) ||
554 defined(__DREAMCAST__) || defined(PSP) ||
555 defined(__GAMECUBE__)
557# elif defined(_WIN32)
560# define alloca _alloca
565# define GBL_ALLOCA alloca
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)
575# define GBL_QUICK_EXIT(c) exit(c)
578#ifndef GBL_PRAGMA_MACRO_PUSH
579# define GBL_PRAGMA_MACRO_PUSH(X) push_macro(X)
582#ifndef GBL_PRAGMA_MACRO_POP
583# define GBL_PRAGMA_MACRO_POP(X) pop_macro(X)
587# define GBL_MAX_ALIGN_T double
589# define GBL_MAX_ALIGN_T max_align_t
595
596
597
598
599
600
601
602
603
604
605
606
608
609
610
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
)
617# if (defined (sun) || defined (__sun__))
618# define GBL_STMT_START if(1
)
619# define GBL_STMT_END else(void)0
621# define GBL_STMT_START do
622# define GBL_STMT_END while(0
)
627#define GBL_NULL_TERMINATED
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)
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)
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;
649# define GBL_BITMASK_POPCOUNT(mask) std::popcount(mask)
651# define GBL_BITMASK_POPCOUNT_SW(mask)
652 (((mask) >= sizeof(unsigned long) * CHAR_BIT) ?
653 (unsigned long) -1
: (1u
<< (mask)) - 1
)
655# if defined(__clang__
) || defined(__GNUC__
)
656# define GBL_BITMASK_CLZ(mask) __builtin_clz(mask)
657# define GBL_BITMASK_CTZ(mask) __builtin_ctz(mask)
658# define GBL_BITMASK_FFS(mask) __builtin_ffs(mask)
659# define GBL_BITMASK_POPCOUNT(mask) __builtin_popcount(mask)
660# elif defined(_MSC_VER)
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;
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;
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;
674# define GBL_BITMASK_POPCOUNT(mask) GBL_BITMASK_POPCOUNT_SW(mask)
676# define GBL_BITMASK_CLZ(mask)
677# define GBL_BITMASK_CTZ(mask)
678# define GBL_BITMASK_FFS(mask)
679# define GBL_BITMASK_POPCOUNT(mask) GBL_BITMASK_POPCOUNT_SW(mask)
#define GBL_UNLIKELY(exp)