23#ifndef MOCHI_PLATFORM_H
24#define MOCHI_PLATFORM_H
26#if defined(__cplusplus)
37#if defined(__cplusplus)
38#define MOCHI_LANGUAGE_CPP 1
39#define MOCHI_LANGUAGE_CPP17 (__cplusplus >= 201703L)
40#ifndef MOCHI_LANGUAGE_CPP20
41#define MOCHI_LANGUAGE_CPP20 (__cplusplus >= 202002L)
43#define MOCHI_LANGUAGE_C 0
45#define MOCHI_LANGUAGE_CPP 0
46#define MOCHI_LANGUAGE_CPP17 0
47#ifndef MOCHI_LANGUAGE_CPP20
48#define MOCHI_LANGUAGE_CPP20 0
50#define MOCHI_LANGUAGE_C 1
66#if defined(__CUDA_ARCH__)
67#define MOCHI_ARCH_CPU 0
68#define MOCHI_ARCH_GPU 1
70#define MOCHI_ARCH_CPU 1
71#define MOCHI_ARCH_GPU 0
75#if defined(PLATFORM_ENABLE_VECTORINTRINSICS_NEON) && PLATFORM_ENABLE_VECTORINTRINSICS_NEON
76#define MOCHI_UNREAL_ARCH_NEON 1
78#define MOCHI_UNREAL_ARCH_NEON 0
81#if defined(__aarch64__) || MOCHI_UNREAL_ARCH_NEON
82#define MOCHI_ARCH_ARM 1
84#define MOCHI_ARCH_ARM 0
87#if MOCHI_ARCH_CPU && MOCHI_ARCH_ARM && (defined(__ARM_NEON) || MOCHI_UNREAL_ARCH_NEON)
88#define MOCHI_ARCH_ARM_NEON 1
90#define MOCHI_ARCH_ARM_NEON 0
94#define MOCHI_UNREAL_ARCH_AVX2 0
96#if defined(PLATFORM_CPU_X86_FAMILY)
97#if PLATFORM_CPU_X86_FAMILY
98#undef MOCHI_UNREAL_ARCH_AVX2
99#define MOCHI_UNREAL_ARCH_AVX2 1
107#if defined(UNREALIOS_LINUX_EDITOR)
108#if UNREALIOS_LINUX_EDITOR
109#undef MOCHI_UNREAL_ARCH_AVX2
110#define MOCHI_UNREAL_ARCH_AVX2 0
114#if defined(_M_X64) || defined(__x86_64) || MOCHI_UNREAL_ARCH_AVX2
115#define MOCHI_ARCH_X64 1
117#define MOCHI_ARCH_X64 0
120#if MOCHI_ARCH_CPU && MOCHI_ARCH_X64 && (defined(__AVX2__) || MOCHI_UNREAL_ARCH_AVX2)
121#define MOCHI_ARCH_X64_AVX2 1
123#define MOCHI_ARCH_X64_AVX2 0
126#if MOCHI_ARCH_CPU && MOCHI_ARCH_X64_AVX2 && \
127 (defined(__FMA__) || (defined(_MSC_VER) && !defined(__clang__)))
128#define MOCHI_ARCH_X64_FMA 1
130#define MOCHI_ARCH_X64_FMA 0
133#if MOCHI_ARCH_CPU && MOCHI_ARCH_X64_AVX2 && \
134 (defined(__SVML__) || (defined(_MSC_VER) && !defined(__clang__)))
135#define MOCHI_ARCH_X64_SVML 1
137#define MOCHI_ARCH_X64_SVML 0
141#if !MOCHI_ARCH_ARM && (defined(__arm__) || defined(_M_ARM))
142#error Mochi does not support older 32-bit versions of ARM
144#if MOCHI_ARCH_ARM && MOCHI_ARCH_X64
145#error Failed to detect correct architecture
147#if MOCHI_UNREAL_ARCH_AVX2 && MOCHI_UNREAL_ARCH_NEON
148#error Cannot have both AVX and NEON
167#if defined(_MSC_VER) && !defined(__clang__)
171#define MOCHI_COMPILER_MSVC 1
173#define MOCHI_COMPILER_MSVC 0
178#if defined(_MSVC_TRADITIONAL)
179#define MOCHI_MSVC_TRADITIONAL _MSVC_TRADITIONAL
181#define MOCHI_MSVC_TRADITIONAL 0
184#if defined(__GNUC__) && !defined(__clang__)
185#define MOCHI_COMPILER_GCC 1
187#define MOCHI_COMPILER_GCC 0
189#if defined(__clang__)
190#define MOCHI_COMPILER_CLANG 1
191#if (__clang_major__ < 19)
192#define MOCHI_CLANG_AWAIT_SUSPEND_BUG 1
194#define MOCHI_CLANG_AWAIT_SUSPEND_BUG 0
197#define MOCHI_COMPILER_CLANG 0
198#define MOCHI_CLANG_AWAIT_SUSPEND_BUG 0
201#if defined(__CUDA_ARCH__)
202#define MOCHI_COMPILER_CUDA_CPU 0
203#define MOCHI_COMPILER_CUDA_GPU 1
204#define MOCHI_COMPILER_CUDA 1
205#elif defined(__CUDACC__)
206#define MOCHI_COMPILER_CUDA_CPU 1
207#define MOCHI_COMPILER_CUDA_GPU 0
208#define MOCHI_COMPILER_CUDA 1
210#define MOCHI_COMPILER_CUDA_CPU 0
211#define MOCHI_COMPILER_CUDA_GPU 0
212#define MOCHI_COMPILER_CUDA 0
216#if defined(__SANITIZE_ADDRESS__) && (MOCHI_COMPILER_CLANG || MOCHI_COMPILER_GCC)
217#define MOCHI_COMPILER_ASAN 1
219#define MOCHI_COMPILER_ASAN 0
221#if defined(__SANITIZE_THREAD__) && (MOCHI_COMPILER_CLANG || MOCHI_COMPILER_GCC)
222#define MOCHI_COMPILER_TSAN 1
224#define MOCHI_COMPILER_TSAN 0
226#if (MOCHI_COMPILER_CLANG || MOCHI_COMPILER_GCC)
227#if defined(__has_feature)
228#if __has_feature(address_sanitizer)
229#undef MOCHI_COMPILER_ASAN
230#define MOCHI_COMPILER_ASAN 1
233#if defined(__has_feature)
234#if __has_feature(thread_sanitizer)
235#undef MOCHI_COMPILER_TSAN
236#define MOCHI_COMPILER_TSAN 1
241#if MOCHI_COMPILER_CLANG
242#if __has_feature(cxx_rtti)
243#define MOCHI_COMPILER_HAS_RTTI 1
245#define MOCHI_COMPILER_HAS_RTTI 0
247#elif MOCHI_COMPILER_GCC
249#define MOCHI_COMPILER_HAS_RTTI 1
251#define MOCHI_COMPILER_HAS_RTTI 0
253#elif MOCHI_COMPILER_MSVC
255#define MOCHI_COMPILER_HAS_RTTI 1
257#define MOCHI_COMPILER_HAS_RTTI 0
262#define MOCHI_COMPILER_HAS_RTTI 1
268#define MOCHI_HAS_VA_OPT (MOCHI_LANGUAGE_CPP20 && !MOCHI_MSVC_TRADITIONAL)
278#if defined(__ANDROID__)
279#define MOCHI_PLATFORM_ANDROID 1
281#define MOCHI_PLATFORM_ANDROID 0
284#if defined(__linux__) && !defined(__ANDROID__)
285#define MOCHI_PLATFORM_LINUX 1
287#define MOCHI_PLATFORM_LINUX 0
290#if defined(__APPLE__)
291#define MOCHI_PLATFORM_MACOS 1
293#define MOCHI_PLATFORM_MACOS 0
297#define MOCHI_PLATFORM_WINDOWS 1
299#define MOCHI_PLATFORM_WINDOWS 0
309#if MOCHI_COMPILER_CUDA
310#define MOCHI_ANY __host__ __device__
311#define MOCHI_CPU __host__
312#define MOCHI_GPU __device__
313#define MOCHI_GPU_KERNEL __global__
318#define MOCHI_GPU_KERNEL
332#if MOCHI_COMPILER_CUDA_GPU
333#define MOCHI_FORCE_INLINE __forceinline__
334#elif MOCHI_COMPILER_MSVC
335#define MOCHI_FORCE_INLINE __forceinline
337#define MOCHI_FORCE_INLINE __attribute__((always_inline)) inline
340#define MOCHI_FORCE_INLINE inline
361#if MOCHI_COMPILER_CUDA_GPU
362#define MOCHI_FORCE_INLINE_LAMBDA
363#elif (MOCHI_COMPILER_CLANG || MOCHI_COMPILER_GCC)
364#define MOCHI_FORCE_INLINE_LAMBDA __attribute__((always_inline))
366#if defined(__has_cpp_attribute)
367#if __has_cpp_attribute(msvc::forceinline)
368#define MOCHI_FORCE_INLINE_LAMBDA [[msvc::forceinline]]
370#define MOCHI_FORCE_INLINE_LAMBDA
373#define MOCHI_FORCE_INLINE_LAMBDA
377#define MOCHI_FORCE_INLINE_LAMBDA
393#if MOCHI_COMPILER_CUDA_GPU
394#define MOCHI_UNROLL_LOOP_N(N) _Pragma(MOCHI_PP_STRINGIFY(unroll N))
395#elif MOCHI_COMPILER_MSVC
396#define MOCHI_UNROLL_LOOP_N(N)
397#elif MOCHI_COMPILER_GCC
398#define MOCHI_UNROLL_LOOP_N(N) _Pragma(MOCHI_PP_STRINGIFY(GCC unroll N))
399#elif MOCHI_COMPILER_CLANG
400#define MOCHI_UNROLL_LOOP_N(N) _Pragma(MOCHI_PP_STRINGIFY(unroll N))
402#define MOCHI_UNROLL_LOOP_N(N)
412#if MOCHI_COMPILER_CUDA_GPU
413#define MOCHI_NO_INLINE __noinline__
414#elif MOCHI_COMPILER_MSVC
415#define MOCHI_NO_INLINE __declspec(noinline)
417#define MOCHI_NO_INLINE __attribute__((noinline))
432#if MOCHI_COMPILER_CUDA_GPU || MOCHI_COMPILER_GCC || MOCHI_COMPILER_CLANG
433#define MOCHI_RESTRICT __restrict__
434#elif MOCHI_COMPILER_MSVC
435#define MOCHI_RESTRICT __restrict
437#define MOCHI_RESTRICT restrict
445#if MOCHI_ARCH_X64_AVX2
446#define MOCHI_SIMD_REGISTER_COUNT 16
447#define MOCHI_SIMD_REGISTER_SIZE_BYTES 32
448#elif MOCHI_ARCH_ARM_NEON
449#define MOCHI_SIMD_REGISTER_COUNT 32
450#define MOCHI_SIMD_REGISTER_SIZE_BYTES 16
452#define MOCHI_SIMD_REGISTER_COUNT Unsupported architecture
453#define MOCHI_SIMD_REGISTER_SIZE_BYTES Unsupported architecture
462#ifndef MOCHI_CACHE_LINE_SIZE
465#define MOCHI_CACHE_LINE_SIZE 64
468#define MOCHI_CACHE_ALIGN alignas(MOCHI_CACHE_LINE_SIZE)
479#if MOCHI_COMPILER_GCC || MOCHI_COMPILER_CLANG
481#define MOCHI_NO_INIT __attribute__((uninitialized))
493#if MOCHI_COMPILER_CUDA_GPU
494#define MOCHI_DEBUG_BREAK() asm("brkpt;")
495#elif MOCHI_PLATFORM_WINDOWS
496#define MOCHI_DEBUG_BREAK() __debugbreak()
498#define MOCHI_DEBUG_BREAK() __builtin_trap()
522#if MOCHI_COMPILER_CUDA_GPU
523#define MOCHI_WARNING_PUSH()
524#define MOCHI_WARNING_PUSH_IGNORE_ALL()
525#define MOCHI_WARNING_POP()
526#elif MOCHI_COMPILER_MSVC
527#define MOCHI_WARNING_PUSH() __pragma(warning(push))
528#define MOCHI_WARNING_PUSH_IGNORE_ALL() __pragma(warning(push, 0))
529#define MOCHI_WARNING_POP() __pragma(warning(pop))
530#elif MOCHI_COMPILER_CLANG
531#define MOCHI_WARNING_PUSH() _Pragma("GCC diagnostic push")
532#define MOCHI_WARNING_PUSH_IGNORE_ALL() \
533 _Pragma("GCC diagnostic push") _Pragma("GCC diagnostic ignored \"-Weverything\"")
534#define MOCHI_WARNING_POP() _Pragma("GCC diagnostic pop")
535#elif MOCHI_COMPILER_GCC
536#define MOCHI_WARNING_PUSH() _Pragma("GCC diagnostic push")
537#define MOCHI_WARNING_PUSH_IGNORE_ALL() \
538 _Pragma("GCC diagnostic push") _Pragma("GCC diagnostic ignored \"-Wall\"") \
539 _Pragma("GCC diagnostic ignored \"-Wextra\"")
540#define MOCHI_WARNING_POP() _Pragma("GCC diagnostic pop")
542#define MOCHI_WARNING_PUSH()
543#define MOCHI_WARNING_PUSH_IGNORE_ALL()
544#define MOCHI_WARNING_POP()
547#if MOCHI_COMPILER_MSVC
548#define MOCHI_WARNING_IGNORE_MSVC(X) __pragma(warning(disable : X))
549#define MOCHI_WARNING_ENFORCE_MSVC(X) __pragma(warning(error : X))
551#define MOCHI_WARNING_IGNORE_MSVC(X)
552#define MOCHI_WARNING_ENFORCE_MSVC(X)
555#if MOCHI_COMPILER_GCC
556#define MOCHI_WARNING_IGNORE_GCC(X) _Pragma(#X)
557#define MOCHI_WARNING_ENFORCE_GCC(X) _Pragma(#X)
559#define MOCHI_WARNING_IGNORE_GCC(X)
560#define MOCHI_WARNING_ENFORCE_GCC(X)
563#if MOCHI_COMPILER_CLANG
564#define MOCHI_WARNING_IGNORE_CLANG(X) _Pragma(#X)
565#define MOCHI_WARNING_ENFORCE_CLANG(X) _Pragma(#X)
567#define MOCHI_WARNING_IGNORE_CLANG(X)
568#define MOCHI_WARNING_ENFORCE_CLANG(X)
572#if MOCHI_COMPILER_GCC || MOCHI_COMPILER_CLANG
573#define MOCHI_WARNING_IGNORE_GCC_CLANG(X) _Pragma(#X)
574#define MOCHI_WARNING_ENFORCE_GCC_CLANG(X) _Pragma(#X)
576#define MOCHI_WARNING_IGNORE_GCC_CLANG(X)
577#define MOCHI_WARNING_ENFORCE_GCC_CLANG(X)
593#if MOCHI_COMPILER_CUDA
594#define MOCHI_WARNING_IGNORE_CUDA(X) __pragma(diag_suppress = X)
595#define MOCHI_WARNING_ENFORCE_CUDA(X) __pragma(diag_error = X)
597#define MOCHI_WARNING_IGNORE_CUDA(X)
598#define MOCHI_WARNING_ENFORCE_CUDA(X)
604#if MOCHI_COMPILER_CUDA_GPU
605#if __CUDAVER__ >= 75000
606#define MOCHI_DISABLE_CUDA_GPU_EXEC_CHECK() __pragma(nv_exec_check_disable)
608#define MOCHI_DISABLE_CUDA_GPU_EXEC_CHECK()
611#define MOCHI_DISABLE_CUDA_GPU_EXEC_CHECK()
614#define MOCHI_TEMPLATE_FUNCTION MOCHI_DISABLE_CUDA_GPU_EXEC_CHECK()
619#define MOCHI_WARNING_SUPPRESS_CUDA() \
621 MOCHI_WARNING_IGNORE_MSVC(4201) \
623 MOCHI_WARNING_IGNORE_MSVC(4244) \
625 MOCHI_WARNING_IGNORE_MSVC(4324) \
627 MOCHI_WARNING_IGNORE_MSVC(4458) \
629 MOCHI_WARNING_IGNORE_MSVC(4505) \
631 MOCHI_WARNING_IGNORE_MSVC(4700) \
633 MOCHI_WARNING_IGNORE_MSVC(4706) \
636 MOCHI_WARNING_IGNORE_CUDA(implicit_return_from_non_void_function)
642#define MOCHI_WARNING_SUPPRESS_EIGEN() \
644 MOCHI_WARNING_IGNORE_MSVC(4127) \
646 MOCHI_WARNING_IGNORE_MSVC(4554) \
648 MOCHI_WARNING_IGNORE_MSVC(4245) \
650 MOCHI_WARNING_IGNORE_CUDA(esa_on_defaulted_function_ignored)
658#if MOCHI_COMPILER_MSVC
659#define MOCHI_DEBUG_RTCHECKS_ENABLE() __pragma(runtime_checks("sc", restore))
660#define MOCHI_DEBUG_RTCHECKS_DISABLE() __pragma(runtime_checks("sc", off))
662#define MOCHI_DEBUG_RTCHECKS_ENABLE()
663#define MOCHI_DEBUG_RTCHECKS_DISABLE()
670#if MOCHI_COMPILER_MSVC
672#define MOCHI_NOP() __nop();
674#define MOCHI_NOP() __asm__ __volatile__("nop");
677#define MOCHI_NOP_10() \
678 MOCHI_NOP(); MOCHI_NOP(); MOCHI_NOP(); MOCHI_NOP(); MOCHI_NOP(); \
679 MOCHI_NOP(); MOCHI_NOP(); MOCHI_NOP(); MOCHI_NOP(); MOCHI_NOP();
680#define MOCHI_NOP_50() \
681 MOCHI_NOP_10(); MOCHI_NOP_10(); MOCHI_NOP_10(); MOCHI_NOP_10(); MOCHI_NOP_10();
682#define MOCHI_NOP_250() \
683 MOCHI_NOP_50(); MOCHI_NOP_50(); MOCHI_NOP_50(); MOCHI_NOP_50(); MOCHI_NOP_50();
691#define MOCHI_PP_CAT(a, b) MOCHI_PP_CAT_IMPL(a, b)
692#define MOCHI_PP_CAT_IMPL(a, b) a##b
695#define MOCHI_PP_STRINGIFY(X) MOCHI_PP_STRINGIFY_IMPL(X)
696#define MOCHI_PP_STRINGIFY_IMPL(X) #X
703#define MOCHI_DECLARE_MOVE(Name) \
704 Name(Name&&) noexcept = default; \
705 Name& operator=(Name&&) = default;
708#define MOCHI_DECLARE_NO_MOVE(Name) \
709 Name(Name&&) = delete; \
710 Name& operator=(Name&&) = delete;
714#define MOCHI_DECLARE_COPY(Name) \
715 Name(Name const&) = default; \
716 Name& operator=(Name const&) = default;
719#define MOCHI_DECLARE_NO_COPY(Name) \
720 Name(Name const&) = delete; \
721 Name& operator=(Name const&) = delete;
726#define MOCHI_DECLARE_NO_COPY_NO_MOVE(Name) \
727 MOCHI_DECLARE_NO_COPY(Name) \
728 MOCHI_DECLARE_NO_MOVE(Name)
732#define MOCHI_DECLARE_MOVE_ONLY(Name) \
733 MOCHI_DECLARE_MOVE(Name); \
734 MOCHI_DECLARE_NO_COPY(Name)
739#define MOCHI_DECLARE_NO_ASSIGN(Name) \
740 Name& operator=(Name const&) = delete; \
741 Name& operator=(Name&&) = delete;
745#if MOCHI_COMPILER_MSVC
746#define MOCHI_EMPTY_BASE __declspec(empty_bases)
748#define MOCHI_EMPTY_BASE
755#if MOCHI_LANGUAGE_CPP
770#define MOCHI_CONCEPT(a) std::enable_if_t<a, superdex::ConceptMatch> = superdex::ConceptMatch::True
773#define MOCHI_CONCEPT_DEF(a) std::enable_if_t<a, superdex::ConceptMatch>
782#if MOCHI_LANGUAGE_CPP20
783#define MOCHI_LIKELY [[likely]]
784#define MOCHI_UNLIKELY [[unlikely]]
787#define MOCHI_UNLIKELY
794#if !(MOCHI_COMPILER_CUDA || MOCHI_COMPILER_MSVC || MOCHI_COMPILER_GCC || MOCHI_COMPILER_CLANG)
795#error "Unknown compiler"
798 MOCHI_PLATFORM_ANDROID || MOCHI_PLATFORM_LINUX || MOCHI_PLATFORM_MACOS || \
799 MOCHI_PLATFORM_WINDOWS)
800#error "Unknown platform"