2
3
4
5
6
7
9#ifndef GIMBAL_COMPILER_H
10#define GIMBAL_COMPILER_H
12#define __STDC_WANT_LIB_EXT1__ 1
20#ifdef __STDC_VERSION__
22# if (__STDC_VERSION__ >= 199409L
)
25# if (__STDC_VERSION__ >= 199901L
)
28# if (__STDC_VERSION__ >= 201112L
)
31# if (__STDC_VERSION__ >= 201710L
)
34# if (__STDC_VERSION__ >= 202311L
)
41# if (__cplusplus
>= 199711L
)
44# if (__cplusplus
>= 201103L
)
47# if (__cplusplus
>= 201402L
)
50# if (__cplusplus
>= 201703L
)
53# if (__cplusplus
>= 202002L
)
56# if (__cplusplus
>= 202302L
)
62#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__)
75# include <TargetConditionals.h>
76# if TARGET_IPHONE_SIMULATOR
78# define GBL_IOS_SIMULATOR 1
79# elif TARGET_OS_MACCATALYST
81# define GBL_MACCATALYST 1
82# elif TARGET_OS_IPHONE
89# error "Unknown Apple platform"
95#elif defined(__DREAMCAST__)
96# define GBL_DREAMCAST 1
106#elif defined(_POSIX_VERSION)
115#elif defined(__clang__
)
117#elif defined(__MINGW32__)
118# define GBL_MINGW32 1
119#elif defined(__MINGW64__)
120# define GBL_MINGW64 1
121#elif defined(__EMSCRIPTEN__)
122# define GBL_EMSCRIPTEN 1
123#elif defined(__GNUC__)
125#elif defined(__ghs__)
126# define GBL_GREENHILL 1
127#elif defined(__CC_ARM)
129#elif defined(__IAR_SYSTEMS__ICC__)
133#if defined(__x86_64__
) || defined(_M_X64)
135#elif defined(i386) || defined(__i386__) || defined(__i386) || defined(_M_IX86)
137#elif defined(__ARM_ARCH_2__)
139#elif defined(__ARM_ARCH_3__) || defined(__ARM_ARCH_3M__)
141#elif defined(__ARM_ARCH_4T__) || defined(__TARGET_ARM_4T)
143#elif defined(__ARM_ARCH_5_) || defined(__ARM_ARCH_5E_)
145#elif defined(__ARM_ARCH_6T2_) || defined(__ARM_ARCH_6T2_)
147#elif defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__)
149#elif defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7S__)
151#elif defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7S__)
153#elif defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7S__)
155#elif defined(__ARM_ARCH_7M__)
157#elif defined(__ARM_ARCH_7S__)
159#elif defined(__aarch64__) || defined(_M_ARM64)
161#elif defined(mips) || defined(__mips__) || defined(__mips)
165#elif defined(__powerpc) || defined(__powerpc__) || defined(__powerpc64__) || defined(__POWERPC__) || defined(__ppc__) || defined(__PPC__) || defined(_ARCH_PPC)
166# define GBL_POWERPC 1
167#elif defined(__PPC64__) || defined(__ppc64__) || defined(_ARCH_PPC64)
168# define GBL_POWERPC64 1
169#elif defined(__sparc__) || defined(__sparc)
171#elif defined(__m68k__)
176# define GBL_NULL nullptr
178# define GBL_NULL NULL
181#if UINTPTR_MAX
== 0xffff
183#elif UINTPTR_MAX
== 0xffffffff
185#elif UINTPTR_MAX
== 0xffffffffffffffff
193# define GBL_EXPORT_SHARED __declspec(dllexport)
194# define GBL_IMPORT_SHARED __declspec(dllimport)
195#elif defined(__clang__
) || defined(__GNUC__
)
196# define GBL_EXPORT_SHARED __attribute__((visibility("default")))
197# define GBL_IMPORT_SHARED
199# define GBL_EXPORT_SHARED
200# define GBL_IMPORT_SHARED
204# define GBL_INITIALIZER(f)
206 struct f##_t_ { f##_t_(void) { f(); } }; static f##_t_ f##_;
208#elif defined(_MSC_VER)
209# pragma section(".CRT$XCU",read)
210# define GBL_INITIALIZER2_(f,p)
212 __declspec(allocate(".CRT$XCU")) void (*f##_)(void) = f;
213 __pragma(comment(linker,"/include:" p #f "_"))
216 #define GBL_INITIALIZER(f) GBL_INITIALIZER2_(f,"")
218 #define GBL_INITIALIZER(f) GBL_INITIALIZER2_(f,"_")
221# define GBL_INITIALIZER(f)
222 static void f(void) __attribute__((constructor));
228# define GBL_THREAD_LOCAL __declspec(thread)
230# if defined(__DREAMCAST__)
231# define GBL_THREAD_LOCAL _Thread_local
232# elif defined(__PSP__)
233# define GBL_THREAD_LOCAL
235# define GBL_THREAD_LOCAL __thread
243# define GBL_CPP_RTTI 1
244#elif defined(__clang__)
245# if __has_feature(cxx_rtti)
246# define GBL_CPP_RTTI 1
248# define GBL_CPP_RTTI 0
250#elif defined(__GNUG__) && defined(__GXX_RTTI)
251# define GBL_CPP_RTTI 1
252#elif defined(_MSC_VER) && defined(_CPPRTTI)
253# define GBL_CPP_RTTI 1
255# define GBL_CPP_RTTI 0
259#ifdef __cpp_exceptions
260# define GBL_CPP_EXCEPTIONS 1
261# define GBL_NOEXCEPT noexcept
263# define GBL_CPP_EXCEPTIONS 0
268# define GBL_CONSTEXPR constexpr
270# define GBL_CONSTEVAL consteval
272# define GBL_CONSTEVAL constexpr
275# define GBL_CONSTEXPR
276# define GBL_CONSTEVAL
281# define GBL_CPP_CONCEPTS 1
283# define GBL_CPP_CONCEPTS 0
288#ifdef __cpp_lib_source_location
289# define GBL_CPP_SOURCE_LOCATION 1
291# define GBL_CPP_SOURCE_LOCATION 0
295#if defined(__has_cpp_attribute
)
296# if __has_cpp_attribute
(deprecated)
297# define GBL_DEPRECATED(msg) [[deprecated(msg)]]
299# define GBL_DEPRECATED(msg)
302# define GBL_DEPRECATED(msg)
306#if defined(__has_cpp_attribute
)
307# if __has_cpp_attribute
(fallthrough)
308# define GBL_FALLTHROUGH [[fallthrough]]
310# define GBL_FALLTHROUGH
313# define GBL_FALLTHROUGH
317#if defined(__has_cpp_attribute
)
318# if __has_cpp_attribute
(likely)
319# define GBL_LIKELY [[likely]]
329#if defined(__has_cpp_attribute
)
330# if __has_cpp_attribute
(maybe_unused)
331# define GBL_MAYBE_UNUSED [[maybe_unused]]
333# define GBL_MAYBE_UNUSED
335#elif defined(__clang__) || defined(__GNUC__)
336# define GBL_MAYBE_UNUSED __attribute__((unused))
338# define GBL_MAYBE_UNUSED
342#if defined(__has_cpp_attribute
)
343# if __has_cpp_attribute
(no_unique_address)
344# define GBL_NO_UNIQUE_ADDRESS [[no_unique_address]]
346# define GBL_NO_UNIQUE_ADDRESS
349# define GBL_NO_UNIQUE_ADDRESS
353#if defined(__has_cpp_attribute
)
354# if __has_cpp_attribute
(nodiscard)
355# define GBL_NODISCARD [[nodiscard]]
357# define GBL_NODISCARD
360# define GBL_NODISCARD
364#if defined(__has_cpp_attribute
)
365# if __has_cpp_attribute
(noreturn)
366# define GBL_NORETURN [[noreturn]]
372# define GBL_NORETURN _Noreturn
379#if defined(__has_cpp_attribute
)
380# if __has_cpp_attribute
(unlikely)
381# define GBL_UNLIKELY [[unlikely]]
389#if __cpp_static_assert
390# if __cpp_static_assert
> 201400
391# define GBL_STATIC_ASSERT(cond) static_assert(cond)
393# define GBL_STATIC_ASSERT(cond) static_assert(cond, #cond)
395# define GBL_STATIC_ASSERT_MSG(cond, msg) static_assert(cond, msg)
396#elif defined(GBL_C11)
397# define GBL_STATIC_ASSERT(cond) _Static_assert(cond, #cond);
398# define GBL_STATIC_ASSERT_MSG(cond, msg) _Static_assert(cond, msg);
400# define GBL_STATIC_ASSERT(cond)
401# define GBL_STATIC_ASSERT_MSG(cond, msg)
405# define GBL_RESTRICT restrict
411# define GBL_STATIC_ARRAY(idx) static idx
413# define GBL_STATIC_ARRAY(idx) idx
417# define GBL_STRUCT_INIT(type, ...) (type{ __VA_ARGS__ })
419# define GBL_STRUCT_INIT(type, ...) ((type){ __VA_ARGS__ })
423# define GBL_ALIGNAS(e) alignas(e)
424# define GBL_ALIGNOF(e) alignof(e)
425#elif defined(GBL_C11)
426# define GBL_ALIGNAS(e) _Alignas(e)
427# define GBL_ALIGNOF(e) _Alignof(e)
430#if defined(_MSC_VER) || defined(__MINGW64__)
431# define GBL_ALIGNED_ALLOC(a, s) _aligned_malloc(s, a)
432# define GBL_ALIGNED_REALLOC(p, a, s) _aligned_realloc(p, s, a)
433# define GBL_ALIGNED_FREE(p) _aligned_free(p)
434#elif defined(__MINGW32__)
435# define GBL_ALIGNED_ALLOC(a, s) __mingw_aligned_malloc(s, a)
436# define GBL_ALIGNED_REALLOC(p, a, s) __mingw_aligned_realloc(p, s, a)
437# define GBL_ALIGNED_FREE(p) __mingw_aligned_free(p)
438#elif defined(GBL_C11) || defined(GBL_CPP17)
440# define GBL_ALIGNED_ALLOC(a, s) aligned_alloc(a, s)
441# define GBL_ALIGNED_REALLOC(p, a, s) realloc(p, s)
442# define GBL_ALIGNED_FREE(p) free(p)
445#if GBL_CONFIG_PREFETCH_ENABLED
447# if defined(_MSC_VER) || defined(__MINGW64__)
448# if defined(_M_ARM64) || defined(_M_ARM64EC)
451# include <immintrin.h>
453# define GBL_PREFETCH(addr) _mm_prefetch(addr, _MM_HINT_T0)
454# elif defined(__GNUC__)
455# define GBL_PREFETCH __builtin_prefetch
458# define GBL_PREFETCH(...)
461# define GBL_PREFETCH(...)
465# define GBL_INLINE_ inline
467# define GBL_INLINE_ static inline
473# define GBL_INLINE GBL_MAYBE_UNUSED GBL_INLINE_
477# define GBL_FORCE_INLINE __attribute__((always_inline)) GBL_INLINE_
478#elif defined(_MSC_VER)
479# define GBL_FORCE_INLINE __forceinline
481# define GBL_FORCE_INLINE GBL_INLINE
488#ifdef __STDC_WANT_LIB_EXT1__
489#define GBL_C11_EXT1 1
490#define GBL_VPRINTF vprintf_s
491#define GBL_VFPRINTF vfprintf_s
492#define GBL_VSPRINTF vsprintf_s
493#define GBL_VSNPRINTF vsnprintf_s
494#define GBL_MEMSET memset_s
495#define GBL_MEMCPY memcpy_s
497#define GBL_C11_EXT1 0
498#define GBL_VPRINTF vprintf
499#define GBL_VFPRINTF vfprintf
500#define GBL_VSPRINTF vsprintf
501#define GBL_VSNPRINTF vsnprintf
502#define GBL_MEMSET memset
503#define GBL_MEMCPY memcpy
509# if defined(__APPLE__) || defined(__GLIBC__
) ||
510 defined(__sun) || defined(__CYGWIN__) ||
511 defined(__EMSCRIPTEN__) || defined(VITA) ||
512 defined(__DREAMCAST__) || defined(PSP)
514# elif defined(_WIN32)
517# define alloca _alloca
522# define GBL_ALLOCA alloca
526# define GBL_QUICK_EXIT(c) exit(c)
527#elif defined(GBL_CPP11
)
528# define GBL_QUICK_EXIT(c) quick_exit(c)
529#elif defined(GBL_C11)
530# define GBL_QUICK_EXIT(c) quick_exit(c)
532# define GBL_QUICK_EXIT(c) exit(c)
535#ifndef GBL_PRAGMA_MACRO_PUSH
536# define GBL_PRAGMA_MACRO_PUSH(X) push_macro(X)
539#ifndef GBL_PRAGMA_MACRO_POP
540# define GBL_PRAGMA_MACRO_POP(X) pop_macro(X)
544# define GBL_MAX_ALIGN_T double
546# define GBL_MAX_ALIGN_T max_align_t
552
553
554
555
556
557
558
559
560
561
562
563
565
566
567
568
569#if !(defined (GBL_STMT_START) && defined (GBL_STMT_END))
570# if defined (__GNUC__
) && !defined (__STRICT_ANSI__) && !defined (__cplusplus
)
571# define GBL_STMT_START do
572# define GBL_STMT_END while(0
)
574# if (defined (sun) || defined (__sun__))
575# define GBL_STMT_START if(1
)
576# define GBL_STMT_END else(void)0
578# define GBL_STMT_START do
579# define GBL_STMT_END while(0
)
584#define GBL_NULL_TERMINATED
589# define GBL_BITMASK_CLZ(mask) std::countl_zero(mask)
590# define GBL_BITMASK_CTZ(mask) std::countr_zero(mask)
591 inline constexpr auto GBL_BITMASK_FFS(
auto mask)
noexcept {
592 const auto idx = GBL_BITMASK_CLZ(mask);
593 return idx? idx + 1 : 0;
595# define GBL_BITMASK_POPCOUNT(mask) std::popcount(mask)
597# define GBL_BITMASK_POPCOUNT_SW(mask)
598 (((mask) >= sizeof(unsigned long) * CHAR_BIT) ?
599 (unsigned long) -1
: (1u
<< (mask)) - 1
)
601# if defined(__clang__
) || defined(__GNUC__
)
602# define GBL_BITMASK_CLZ(mask) __builtin_clz(mask)
603# define GBL_BITMASK_CTZ(mask) __builtin_ctz(mask)
604# define GBL_BITMASK_FFS(mask) __builtin_ffs(mask)
605# define GBL_BITMASK_POPCOUNT(mask) __builtin_popcount(mask)
606# elif defined(_MSC_VER)
608 GBL_CONSTEXPR GBL_INLINE
unsigned GBL_BITMASK_CLZ(
unsigned mask) GBL_NOEXCEPT {
609 unsigned long idx = 0;
610 return _BitScanReverse(&idx, mask)? ((
sizeof(
unsigned) * 8) - idx) : 0;
612 GBL_CONSTEXPR GBL_INLINE
unsigned GBL_BITMASK_CTZ(
unsigned mask) GBL_NOEXCEPT {
613 unsigned long idx = 0;
614 return _BitScanForward(&idx, mask)? idx : 0;
616 GBL_CONSTEXPR GBL_INLINE
unsigned GBL_BITMASK_FFS(
unsigned mask) GBL_NOEXCEPT {
617 const unsigned idx = GBL_BITMASK_CTZ(mask);
618 return idx? idx + 1 : 0;
620# define GBL_BITMASK_POPCOUNT(mask) GBL_BITMASK_POPCOUNT_SW(mask)
622# define GBL_BITMASK_CLZ(mask)
623# define GBL_BITMASK_CTZ(mask)
624# define GBL_BITMASK_FFS(mask)
625# define GBL_BITMASK_POPCOUNT(mask) GBL_BITMASK_POPCOUNT_SW(mask)