[add] first

This commit is contained in:
2023-10-08 10:24:48 +08:00
commit b1ae0510a9
1048 changed files with 3254361 additions and 0 deletions

View File

@@ -0,0 +1,60 @@
#pragma once
// Detect 64/32bit if not user defined.
#if !defined(PLATFORM_ARCH_64) && !defined(PLATFORM_ARCH_32)
#if defined(_AMD64_) || defined(__LP64__) || defined(_WIN64) || defined(_M_ARM64)
#define PLATFORM_ARCH_64 1
#define PLATFORM_ARCH_32 0
#else
#define PLATFORM_ARCH_64 0
#define PLATFORM_ARCH_32 1
#endif
#elif !defined(PLATFORM_ARCH_64)
#define PLATFORM_ARCH_64 (PLATFORM_ARCH_32 ? 0 : 1)
#elif !defined(PLATFORM_ARCH_32)
#define PLATFORM_ARCH_32 (PLATFORM_ARCH_64 ? 0 : 1)
#endif
// Cache line size in bytes
#ifndef PLATFORM_CACHE_LINE_SIZE
#define PLATFORM_CACHE_LINE_SIZE 64
#endif
// Detect endianess if not user defined.
#if !defined(PLATFORM_ARCH_BIG_ENDIAN) && !defined(PLATFORM_ARCH_LITTLE_ENDIAN)
#if defined(__BIG_ENDIAN__)
#define PLATFORM_ARCH_BIG_ENDIAN 1
#define PLATFORM_ARCH_LITTLE_ENDIAN 0
#else
#define PLATFORM_ARCH_BIG_ENDIAN 0
#define PLATFORM_ARCH_LITTLE_ENDIAN 1
#endif
#elif !defined(PLATFORM_ARCH_BIG_ENDIAN)
#define PLATFORM_ARCH_BIG_ENDIAN (PLATFORM_ARCH_LITTLE_ENDIAN ? 0 : 1)
#elif !defined(PLATFORM_ARCH_LITTLE_ENDIAN)
#define PLATFORM_ARCH_LITTLE_ENDIAN (PLATFORM_ARCH_BIG_ENDIAN ? 0 : 1)
#endif
// Detect SIMD features.
// SSE2
// Naming is inherited from Unity and indicates full SSE2 support.
#ifndef PLATFORM_SUPPORTS_SSE
#if (defined(_M_IX86_FP) && _M_IX86_FP == 2) || defined(_M_AMD64) || defined(_M_X64) || defined(__SSE2__)
#define PLATFORM_SUPPORTS_SSE 1
#else
#define PLATFORM_SUPPORTS_SSE 0
#endif
#endif
// NEON
// Indicates general availability. Note that there can be some differences in the exact instructions available.
#ifndef PLATFORM_SUPPORTS_NEON
#if defined(__ARM_NEON) || defined(__ARM_NEON__) || defined(__ARM_NEON_FP) || \
(defined(_MSC_VER) && (defined(_M_ARM) || defined(_M_ARM64)))
#define PLATFORM_SUPPORTS_NEON 1
#else
#define PLATFORM_SUPPORTS_NEON 0
#endif
#endif

View File

@@ -0,0 +1,47 @@
#pragma once
#ifndef BASELIB_ENABLE_ASSERTIONS
#ifdef NDEBUG
#define BASELIB_ENABLE_ASSERTIONS 0
#else
#define BASELIB_ENABLE_ASSERTIONS 1
#endif
#endif
#include "../C/Baselib_Debug.h"
#ifdef __cplusplus
BASELIB_C_INTERFACE
{
#endif
#if COMPILER_CLANG || COMPILER_GCC
__attribute__((format(printf, 1, 2)))
#endif
BASELIB_API void detail_AssertLog(const char* format, ...);
#define DETAIL__ASSERT_LOG(ASSERT_EXPRESSION_, message, ...) \
PP_EVAL(PP_IF_ELSE(PP_VARG_IS_NONEMPTY(__VA_ARGS__)) \
(detail_AssertLog("%s(%d): Assertion failed (%s) - " message "\n", __FILE__, __LINE__, #ASSERT_EXPRESSION_, __VA_ARGS__)) \
(detail_AssertLog("%s(%d): Assertion failed (%s) - %s\n", __FILE__, __LINE__, #ASSERT_EXPRESSION_, message)) \
)
#define BaselibAssert(ASSERT_EXPRESSION_, ...) \
do { \
if (BASELIB_ENABLE_ASSERTIONS) \
{ \
if(!(ASSERT_EXPRESSION_)) \
{ \
PP_EVAL(PP_IF_ELSE(PP_VARG_IS_NONEMPTY(__VA_ARGS__)) \
(DETAIL__ASSERT_LOG(ASSERT_EXPRESSION_, __VA_ARGS__)) \
(detail_AssertLog("%s(%d): Assertion failed (%s)\n", __FILE__, __LINE__, #ASSERT_EXPRESSION_)) \
); \
Baselib_Debug_Break(); \
} \
} \
} while(0)
#ifdef __cplusplus
} // BASELIB_C_INTERFACE
#endif

View File

@@ -0,0 +1,16 @@
#pragma once
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
// Default for PLATFORM_MEMORY_MALLOC_MIN_ALIGNMENT if not specified by platform.
#ifndef PLATFORM_MEMORY_MALLOC_MIN_ALIGNMENT
#define PLATFORM_MEMORY_MALLOC_MIN_ALIGNMENT COMPILER_ALIGN_OF(max_align_t)
#endif
// Custom type suitable for representing a UTF-16 codepoint crossplatform.
// Because char16_t is not available on all platforms,
// uint16_t is chosen as a type that inflicts the same behavior across platforms,
// as is requiring a cast from platform specific UTF-16 representation.
typedef uint16_t baselib_char16_t;

View File

@@ -0,0 +1,74 @@
#pragma once
// This defines the compiler environment for clang based compilers. Please make sure to define all required features
// (see VerifyCompilerEnvironment.h for reference)
#if defined(__cplusplus) && __cplusplus < 201103L
#error "Baselib requires C++11 support"
#endif
#define COMPILER_CLANG 1
#define HAS_CLANG_FEATURE(x) (__has_feature(x))
#define COMPILER_SUPPORTS_EXCEPTIONS HAS_CLANG_FEATURE(cxx_exceptions)
#define COMPILER_SUPPORTS_RTTI HAS_CLANG_FEATURE(cxx_rtti)
#define COMPILER_SUPPORTS_GENERIC_LAMBDA_EXPRESSIONS HAS_CLANG_FEATURE(cxx_generic_lambdas) // Clang >=3.4
#define COMPILER_BUILTIN_EXPECT(X_, Y_) __builtin_expect((X_), (Y_))
// Tells the compiler to assume that this statement is never reached.
// (reaching it anyways is undefined behavior!)
#define COMPILER_BUILTIN_UNREACHABLE() __builtin_unreachable()
// Tells the compiler to assume that the given expression is true until the expression is modified.
// (it is undefined behavior if the expression is not true after all)
#define COMPILER_BUILTIN_ASSUME(EXPR_) __builtin_assume(EXPR_)
#define COMPILER_NOINLINE __attribute__((unused, noinline)) // unused is needed to avoid warning when a function is not used
#define COMPILER_INLINE __attribute__((unused)) inline
#define COMPILER_FORCEINLINE __attribute__((unused, always_inline, nodebug)) inline
#define COMPILER_EMPTYINLINE __attribute__((const, always_inline, nodebug)) inline
#define COMPILER_NORETURN __attribute__((noreturn))
#if __has_extension(attribute_deprecated_with_message)
#define COMPILER_DEPRECATED(msg) __attribute__((deprecated(msg)))
#if __has_extension(enumerator_attributes)
#define COMPILER_DEPRECATED_ENUM_VALUE(msg) __attribute__((deprecated(msg)))
#else
#define COMPILER_DEPRECATED_ENUM_VALUE(msg)
#endif
#else
#define COMPILER_DEPRECATED(msg) __attribute__((deprecated))
#if __has_extension(enumerator_attributes)
#define COMPILER_DEPRECATED_ENUM_VALUE(msg) __attribute__((deprecated))
#else
#define COMPILER_DEPRECATED_ENUM_VALUE(msg)
#endif
#endif
#define COMPILER_ALIGN_OF(TYPE_) __alignof__(TYPE_)
#define COMPILER_ALIGN_AS(ALIGN_) __attribute__((aligned(ALIGN_)))
#define COMPILER_C_STATIC_ASSERT(EXPR_, MSG_) _Static_assert(EXPR_, MSG_)
#define COMPILER_ATTRIBUTE_UNUSED __attribute__((unused))
// Note that this is how the compiler defines a debug break which is not necessarily the standard way on any given platform.
// For a platform friendly implementation, use `BASELIB_DEBUG_TRAP`
#define COMPILER_DEBUG_TRAP() __builtin_debugtrap()
#define COMPILER_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
// Warning management
// pragma message on clang does always generate a warning that cannot be disabled, therefore the clang version
// of COMPILER_PRINT_MESSAGE() does nothing
#define COMPILER_PRINT_MESSAGE(MESSAGE_)
#define COMPILER_PRINT_WARNING(MESSAGE_) _Pragma(PP_STRINGIZE(message(__FILE__ "warning: " MESSAGE_)))
#define COMPILER_WARNING_UNUSED_VARIABLE PP_STRINGIZE(-Wunused-variable)
#define COMPILER_WARNING_DEPRECATED PP_STRINGIZE(-Wdeprecated)
#define COMPILER_WARNINGS_PUSH _Pragma(PP_STRINGIZE(clang diagnostic push))
#define COMPILER_WARNINGS_POP _Pragma(PP_STRINGIZE(clang diagnostic pop))
#define COMPILER_WARNINGS_DISABLE(Warn) _Pragma(PP_STRINGIZE(clang diagnostic ignored Warn))

View File

@@ -0,0 +1,99 @@
#pragma once
// Verify that the GCC is correctly defining __cplusplus. This is not the case for
// GCC versions < 4.7, where it is just defined to 1. We only error here in case of linux build
// as we, as we use the commandline --std=xxx to select the featureset there. On armcc and cxppc
// we do not use any >C99 features, so the detection works correctly with __cplusplus==1
#if (__cplusplus == 1) && defined(LINUX)
#error "This version of GCC is not supported. Please update to a more recent one."
#endif
#if defined(__cplusplus) && __cplusplus < 201103L
#error "Baselib requires C++11 support"
#endif
#define COMPILER_GCC 1
// __cpp_exceptions is the correct way to check whether exceptions are enabled or not, but is unfortunately not supported
// by GCC versions before 5.0. For Pre 5.0 GCC, we also need to check the __EXCEPTIONS macro
#if defined(__cpp_exceptions) || __EXCEPTIONS == 1
#define COMPILER_SUPPORTS_EXCEPTIONS 1
#else
#define COMPILER_SUPPORTS_EXCEPTIONS 0
#endif
// __cpp_rtti is the correct way to check whether RTTI is enabled or not, but is unfortunately not supported
// by GCC versions before 5.0. For Pre 5.0 GCC, we also need to check the __GXX_RTTI macro
#if defined(__cpp_rtti) || __GXX_RTTI == 1
#define COMPILER_SUPPORTS_RTTI 1
#else
#define COMPILER_SUPPORTS_RTTI 0
#endif
// GCC >=4.9
#if defined(__cpp_generic_lambdas) && (__cpp_generic_lambdas >= 201304)
#define COMPILER_SUPPORTS_GENERIC_LAMBDA_EXPRESSIONS 1
#else
#define COMPILER_SUPPORTS_GENERIC_LAMBDA_EXPRESSIONS 0
#endif
#define COMPILER_BUILTIN_EXPECT(X_, Y_) __builtin_expect((X_), (Y_))
// Tells the compiler to assume that this statement is never reached.
// (reaching it anyways is undefined behavior!)
#define COMPILER_BUILTIN_UNREACHABLE() __builtin_unreachable()
// Tells the compiler to assume that the given expression is true until the expression is modified.
// (it is undefined behavior if the expression is not true after all)
#define COMPILER_BUILTIN_ASSUME(EXPR_) do { if (!(EXPR_)) COMPILER_BUILTIN_UNREACHABLE(); } while(false)
#define COMPILER_NOINLINE __attribute__((unused, noinline)) // unused is needed to avoid warning when a function is not used
#define COMPILER_INLINE __attribute__((unused)) inline
#define COMPILER_FORCEINLINE __attribute__((unused, always_inline)) inline
#define COMPILER_EMPTYINLINE __attribute__((const, always_inline)) inline
#define COMPILER_NORETURN __attribute__((noreturn))
#if (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) || __GNUC__ > 4
#define COMPILER_DEPRECATED(msg) __attribute__((deprecated(msg)))
#else
#define COMPILER_DEPRECATED(msg) __attribute__((deprecated))
#endif
// Support for attributes on enumerators is GCC 6
#if __GNUC__ >= 6
#define COMPILER_DEPRECATED_ENUM_VALUE(msg) __attribute__((deprecated(msg)))
#else
#define COMPILER_DEPRECATED_ENUM_VALUE(msg)
#endif
#define COMPILER_ALIGN_OF(TYPE_) __alignof__(TYPE_)
#define COMPILER_ALIGN_AS(ALIGN_) __attribute__((aligned(ALIGN_)))
#define COMPILER_C_STATIC_ASSERT(EXPR_, MSG_) _Static_assert(EXPR_, MSG_)
#define COMPILER_ATTRIBUTE_UNUSED __attribute__((unused))
// Some versions of GCC do provide __builtin_debugtrap, but it seems to be unreliable.
// See https://github.com/scottt/debugbreak/issues/13
#if defined(__i386__) || defined(__x86_64__)
#define COMPILER_DEBUG_TRAP() __asm__ volatile("int $0x03")
#elif defined(__thumb__)
#define COMPILER_DEBUG_TRAP() __asm__ volatile(".inst 0xde01")
#elif defined(__arm__) && !defined(__thumb__)
#define COMPILER_DEBUG_TRAP() __asm__ volatile(".inst 0xe7f001f0")
#elif defined(__aarch64__)
#define COMPILER_DEBUG_TRAP() __asm__ volatile(".inst 0xd4200000")
#endif
#define COMPILER_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
#define HAS_CLANG_FEATURE(x) 0
// Warning management
#define COMPILER_PRINT_MESSAGE(MESSAGE_) _Pragma(PP_STRINGIZE(message(__FILE__ "info: " MESSAGE_)))
#define COMPILER_PRINT_WARNING(MESSAGE_) _Pragma(PP_STRINGIZE(message(__FILE__ "warning: " MESSAGE_)))
#define COMPILER_WARNING_UNUSED_VARIABLE PP_STRINGIZE(-Wunused-variable)
#define COMPILER_WARNING_DEPRECATED PP_STRINGIZE(-Wdeprecated)
#define COMPILER_WARNINGS_PUSH _Pragma("GCC diagnostic push")
#define COMPILER_WARNINGS_POP _Pragma("GCC diagnostic pop")
#define COMPILER_WARNINGS_DISABLE(Warn) _Pragma(PP_STRINGIZE(GCC diagnostic ignored Warn))

View File

@@ -0,0 +1,68 @@
#pragma once
#if _MSC_VER < 1900
#error "Baselib requires C++11 support, i.e. MSVC 2015 or newer"
#endif
#define COMPILER_MSVC 1
#ifdef _CPPUNWIND
#define COMPILER_SUPPORTS_EXCEPTIONS _CPPUNWIND
#else
#define COMPILER_SUPPORTS_EXCEPTIONS 0
#endif
#ifdef _CPPRTTI
#define COMPILER_SUPPORTS_RTTI _CPPRTTI
#else
#define COMPILER_SUPPORTS_RTTI 0
#endif
#define COMPILER_SUPPORTS_GENERIC_LAMBDA_EXPRESSIONS 1 // _MSC_VER >= 1900
#define COMPILER_BUILTIN_EXPECT(X_, Y_) (X_)
// Tells the compiler to assume that this statement is never reached.
// (reaching it anyways is undefined behavior!)
#define COMPILER_BUILTIN_UNREACHABLE() __assume(false)
// Tells the compiler to assume that the given expression is true until the expression is modified.
// (it is undefined behavior if the expression is not true after all)
#define COMPILER_BUILTIN_ASSUME(EXPR_) __assume(EXPR_)
#define HAS_CLANG_FEATURE(x) 0
// Warning management
#define COMPILER_PRINT_MESSAGE(MESSAGE_) __pragma(message(__FILE__ "(" PP_STRINGIZE(__LINE__) ") : info: " MESSAGE_))
#define COMPILER_PRINT_WARNING(MESSAGE_) __pragma(message(__FILE__ "(" PP_STRINGIZE(__LINE__) ") : warning: " MESSAGE_))
#define COMPILER_WARNING_UNUSED_VARIABLE 4101
#define COMPILER_WARNING_DEPRECATED 4995 4996
#define COMPILER_WARNINGS_PUSH __pragma(warning(push))
#define COMPILER_WARNINGS_POP __pragma(warning(pop))
#define COMPILER_WARNINGS_DISABLE(Warn) __pragma(warning(disable : Warn))
#define COMPILER_NOINLINE __declspec(noinline)
#define COMPILER_INLINE inline
#define COMPILER_FORCEINLINE __forceinline
#define COMPILER_EMPTYINLINE __forceinline
#define COMPILER_NORETURN __declspec(noreturn)
#define COMPILER_DEPRECATED(msg) __declspec(deprecated(msg))
#define COMPILER_DEPRECATED_ENUM_VALUE(msg) /* no equivalent for this in MSVC */
#define COMPILER_ALIGN_OF(TYPE_) __alignof(TYPE_)
#define COMPILER_ALIGN_AS(ALIGN_) __declspec(align(ALIGN_))
#define COMPILER_C_STATIC_ASSERT(EXPR_, MSG_) typedef char __static_assert_t[(EXPR_) != 0]
#define COMPILER_ATTRIBUTE_UNUSED __pragma(warning(suppress:4100))
#define COMPILER_DEBUG_TRAP() __debugbreak()
// Note that this is best effort, as "/analyze" compiler flag required to make warning appear
#define COMPILER_WARN_UNUSED_RESULT _Check_return_
#if !defined(alloca)
#define alloca _alloca
#endif

View File

@@ -0,0 +1,291 @@
// DO NOT PUT #pragma once or include guard check here
// This header is designed to be able to be included multiple times
// -------------------------------------------------------------------------------------------------
// this macros are undefined in UndefineCoreMacros.h
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// !!! IF YOU ADD A NEW MACRO TO THIS SECTION !!!
// !!! please add it to UndefineCoreMacros.h !!!
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// this is where we collect context-free macros of general utility. it's a holding area until the new sub-core layer
// project is started.
//
// IMPORTANT: only macros! and no non-system #includes!
// FORCE_INLINE forwarded to compiler defined macro
#define FORCE_INLINE COMPILER_FORCEINLINE
// You may use OPTIMIZER_LIKELY / OPTIMIZER_UNLIKELY to provide the compiler with branch prediction information.
//
// The return value is the value of 'EXPR_', which should be an integral expression.
//
// OPTIMIZER_LIKELY makes it so that the branch predictor chooses to take the branch.
// OPTIMIZER_UNLIKELY makes it so that the branch predictor chooses not to take the branch.
//
#define OPTIMIZER_LIKELY(EXPR_) COMPILER_BUILTIN_EXPECT(!!(EXPR_), 1)
#define OPTIMIZER_UNLIKELY(EXPR_) COMPILER_BUILTIN_EXPECT(!!(EXPR_), 0)
// UNUSED will tell the compiler not to warn about a given variable being unused. "yeah, we know - this is unused."
//
// the internet says that (void)sizeof(expr) is the right way to do this, but not for us, not with our
// compilers. the below is the result of much experimentation by @lucas, who says that we have at least one compiler
// that does not consider sizeof(expr) to be a 'usage' of the variable(s) inside of expr.
//
// also note that we do not have the 'if+const expr' warning enabled because combining #if and if expression/constants
// (which we often need to do - for example 'caps->gles.requireClearAlpha = PLATFORM_WEBGL || PLATFORM_STV') is super noisy.
//
#define UNUSED(EXPR_) \
do { if (false) (void)(EXPR_); } while(0)
// COMPILER_WARNING will generate a compiler warning. this will work for all our compilers, though note the usage
// requires a pragma. (based on http://goodliffe.blogspot.dk/2009/07/c-how-to-say-warning-to-visual-studio-c.html)
//
// usage:
//
// #pragma COMPILER_WARNING("this file is obsolete! use foo/bar.h instead.")
//
#define COMPILER_WARNING(MESSAGE_) message(__FILE__ "(" UNITY_STRINGIFY(__LINE__) ") : warning: " MESSAGE_)
#define UNSIGNED_FLAGS_1(FLAG1_) static_cast<unsigned int>(FLAG1_)
#define UNSIGNED_FLAGS_2(FLAG1_, FLAG2_) UNSIGNED_FLAGS_1(FLAG1_) | UNSIGNED_FLAGS_1(FLAG2_)
#define UNSIGNED_FLAGS_3(FLAG1_, FLAG2_, FLAG3_) UNSIGNED_FLAGS_1(FLAG1_) | UNSIGNED_FLAGS_2(FLAG2_, FLAG3_)
#define UNSIGNED_FLAGS_4(FLAG1_, FLAG2_, FLAG3_, FLAG4_) UNSIGNED_FLAGS_1(FLAG1_) | UNSIGNED_FLAGS_3(FLAG2_, FLAG3_, FLAG4_)
#define UNSIGNED_FLAGS_5(FLAG1_, FLAG2_, FLAG3_, FLAG4_, FLAG5_) UNSIGNED_FLAGS_1(FLAG1_) | UNSIGNED_FLAGS_4(FLAG2_, FLAG3_, FLAG4_, FLAG5_)
#define UNSIGNED_FLAGS_6(FLAG1_, FLAG2_, FLAG3_, FLAG4_, FLAG5_, FLAG6_) UNSIGNED_FLAGS_1(FLAG1_) | UNSIGNED_FLAGS_5(FLAG2_, FLAG3_, FLAG4_, FLAG5_, FLAG6_)
#define UNSIGNED_FLAGS(...) PP_VARG_SELECT_OVERLOAD(UNSIGNED_FLAGS_, (__VA_ARGS__))
// -------------------------------------------------------------------------------------------------
// this macros are not undefined in UndefineCoreMacros.h, hence we put a guard to not define them twice
#ifndef DETAIL__PP_AND_DETAILS_CORE_MACROS_DEFINED
#define DETAIL__PP_AND_DETAILS_CORE_MACROS_DEFINED
// when putting control-flow, multiple statements, or unknown code (e.g. passed via an outer macro) inside of a macro,
// wrap it in PP_WRAP_CODE to be safe. https://q.unity3d.com/answers/1382/view.html
//
// (also see http://stackoverflow.com/questions/154136/do-while-and-if-else-statements-in-c-c-macros)
//
// things not to use PP_WRAP_CODE for:
//
// * 'break' or 'continue' statements that are expected to operate on the scope containing the macro
// * introduction of variables that are expected not to go out of scope at macro end
//
#define PP_WRAP_CODE(CODE_) \
do { CODE_; } while (0)
// PP_EMPTY_STATEMENT is used to insert an empty statement in a macro to require a semicolon terminator where used.
// most useful when creating "function style" macros where there is no natural place inside the macro to leave off a
// semicolon so as to require it in usage (for example when the internals end with a closing brace).
//
#define PP_EMPTY_STATEMENT \
do { } while (0)
// PP_VARG_COUNT expands to the the number of arguments passed to the macro. It supports 1 to 20 arguments (0 is not
// supported)
//
#define PP_VARG_COUNT(...) \
DETAIL__PP_EXPAND_2(DETAIL__PP_VARG_COUNT, (__VA_ARGS__, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1))
// PP_VARG_SELECT_OVERLOAD calls the correct overloaded version of the macro "name" name1, name2 etc.
//
// WARNING: **Varargs break Intellisense**. Intellisense gives us the argument list, which most of the time should be
// sufficient documentation for using a macro. Macro overloading hides the args and possibly makes it less safe as
// well. So be certain this tradeoff is worth it!
//
// Use like this:
//
// #define FORWARD_DECLARE_CLASS_1(CLASSNAME_) class CLASSNAME_;
// #define FORWARD_DECLARE_CLASS_2(NAMESPACE_, CLASSNAME_) namespace NAMESPACE_ { class CLASSNAME_; }
// #define FORWARD_DECLARE_CLASS_3(NAMESPACE_1_, NAMESPACE_2_, CLASSNAME_) namespace NAMESPACE_1_ { namespace NAMESPACE_1_ { class CLASSNAME_; } }
// // Up to 10 overloads can be added
// #define FORWARD_DECLARE_CLASS(...) PP_VARG_SELECT_OVERLOAD(FORWARD_DECLARE_CLASS_, (__VA_ARGS__))
//
// ...which can then be used with optional number of arguments like this:
//
// FORWARD_DECLARE_CLASS(GlobalClass)
// FORWARD_DECLARE_CLASS(FooNamespace, FooClass)
// FORWARD_DECLARE_CLASS(FooNamespace, BarNamespace, FooBarClass)
//
#define PP_VARG_SELECT_OVERLOAD(NAME_, ARGS_) \
DETAIL__PP_EXPAND_2(DETAIL__PP_VARG_CONCAT(NAME_, PP_VARG_COUNT ARGS_), ARGS_)
// PP_CONCAT concatenates all passed preprocessor tokens after macro-expanding them
#define PP_CONCAT(...) PP_VARG_SELECT_OVERLOAD(DETAIL__PP_CONCAT_, (__VA_ARGS__))
// PP_NOOP does nothing, but is useful for forcing the preprocessor to re-evaluate expressions after expansion.
#define PP_NOOP()
// PP_DEFER defers evaluation of EXPR_ to the next expansion pass.
#define PP_DEFER(EXPR_) EXPR_ PP_NOOP ()
// PP_DEFER2 defers evaluation of EXPR_ to the expansion pass *after* the next one
#define PP_DEFER2(EXPR_) EXPR_ PP_NOOP PP_NOOP ()()
// PP_DEFER3 defers evaluation of EXP_ to the expansion pass *after* the expansion pass after the next one
#define PP_DEFER3(EXPR_) EXPR_ PP_NOOP PP_NOOP PP_NOOP ()()()
// PP_RECURSE allows recursive expansion of macros; PP_RECURSE(A) will expand to A_RECURSE which you should define to A.
#define PP_RECURSE(MACRO_) PP_DEFER(MACRO_##_RECURSE)()
// Use PP_EVAL to force up to 1024 evaluation passes on an expression, ensuring that everything is fully expanded.
#define PP_EVAL(...) DETAIL__PP_EVAL1024(__VA_ARGS__)
// Use PP_STRINGIZE to wrap the precise characters in the given argument in double quotes (auto-escaping where necessary).
// This is most often used to convert an expression to a string, but be aware that the contents aren't limited to what a
// C expression permits! For example PP_STRINGIZE(pork & beans ("awesome")!) results in the literal "pork & beans (\"awesome\")!"
#define PP_STRINGIZE(ARG_) DETAIL__PP_STRINGIZE_EXPAND(ARG_)
// PP_FIRST expands to the first argument in a list of arguments
#define PP_FIRST(A_, ...) A_
// PP_SECOND expands to the second argument in a list of (at least two) arguments
#define PP_SECOND(A_, B_, ...) B_
// PP_BOOLIFY expands to 0 if the argument is 0, and 1 otherwise
// It should be used inside a PP_EVAL expression.
#define PP_BOOLIFY(EXPR_) DETAIL__PP_BOOLIFY_NOT(DETAIL__PP_BOOLIFY_NOT(EXPR_))
// PP_VARG_IS_NONEMPTY evaluates to 0 if no arguments are provided, and 1 otherwise
// It should be used inside a PP_EVAL expression.
#if COMPILER_MSVC
#define PP_VARG_IS_NONEMPTY(...) PP_BOOLIFY(PP_FIRST(__VA_ARGS__ DETAIL__PP_VARG_END_MARKER)())
#else
#define PP_VARG_IS_NONEMPTY(...) PP_BOOLIFY(PP_DEFER(PP_FIRST)(DETAIL__PP_VARG_END_MARKER DETAIL__PP_VARG_UNPAREN_FIRST(__VA_ARGS__))())
#endif
// PP_IF_ELSE(EXPR_)(A_)(B_) evaluates to A_ if EXPR_ is nonzero, or to B_ if EXPR_ is 0.
// It should be used inside a PP_EVAL expression.
#define PP_IF_ELSE(EXPR_) DETAIL__PP_IF_ELSE(PP_BOOLIFY(EXPR_))
// PP_MAP applies MACRO_ to each of the following arguments.
// It should be used inside a PP_EVAL expression.
#define PP_MAP(MACRO_, ...) PP_EVAL(PP_IF_ELSE(PP_VARG_IS_NONEMPTY(__VA_ARGS__))(PP_DEFER3(DETAIL__PP_MAP_NONOPTIONAL)(MACRO_, __VA_ARGS__))())
// PP_UNPAREN removes one set of optional parenthesis around the argument.
// Useful for implementing macros that take types as argument since the commas in templated types
// normally are seen as macro argument separators.
// #define ARRAY(NAME_, TYPE_, COUNT_) PP_UNPAREN(TYPE_) NAME_[COUNT_]
// The type passed to the ARRAY macro ARRAY macro can now be used like:
// ARRAY(array_of_maps, (map<int,int>), 8);
// while still accepting:
// ARRAY(array_of_ints, int, 8);
#define PP_UNPAREN(EXPR_) DETAIL__PP_UNPAREN_EVAL_AND_CONCAT_FIRST_2_ARGS(DETAIL__PP_UNPAREN_EMPTY_, DETAIL__PP_UNPAREN_HELPER EXPR_)
#if __cplusplus
// PP_IS_STRING evaluates to true if the argument is of const char* type, false otherwise
#define PP_IS_STRING(EXPR_) (sizeof(core::detail::ReturnCharIfString(EXPR_)) == sizeof(char))
// PP_CONST_VALUE takes a value that _may_ be an int, or may be a string, and produces a constant expression suitable for use as an enum
// initializer. If you pass it a string, the result will still be a constant expression, but it will have undefined value.
#define PP_CONST_VALUE(EXPR_) ((int)DETAIL__PP_CONST_VALUE_HIGHBITS(EXPR_) + (int)DETAIL__PP_CONST_VALUE_LOWBITS(EXPR_))
#endif
// ----------------------------------------------------------------------------
// implementation details for above macros follow. we have this in a separate section to cut down on clutter above.
// visual c++ requires two levels of indirection to ensure proper macro expansion of PP_CONCAT with certain arguments involving __VA_ARGS__
// and other scenarios like the one below.
// #define PP_CAT(a,b) a##b
// #define PP_CAT2(a,b) PP_CAT(a,b)
// #define PP_CAT3(a,b) PP_CAT2(a,b)
//
// #define E(a) QQ a
// #define QQ() Q
//
// #define T2() PP_CAT2(_,E(()))
// #define T3() PP_CAT3(_,E(()))
//
// T2() and T3() will expand differently with VC but not with other preprocessors.
#define DETAIL__PP_CONCAT_Y(A_, B_) A_##B_
#define DETAIL__PP_CONCAT_X(A_, B_) DETAIL__PP_CONCAT_Y(A_, B_)
#define DETAIL__PP_EXPAND_2(A_, B_) A_ B_
#define DETAIL__PP_VARG_CONCAT_Y(A_, B_) A_##B_
#define DETAIL__PP_VARG_CONCAT_X(A_, B_) DETAIL__PP_VARG_CONCAT_Y(A_, B_)
#define DETAIL__PP_VARG_CONCAT(A_, B_) DETAIL__PP_VARG_CONCAT_X(A_, B_)
#define DETAIL__PP_VARG_COUNT(ARG0_, ARG1_, ARG2_, ARG3_, ARG4_, ARG5_, ARG6_, ARG7_, ARG8_, ARG9_, ARG10_, ARG11_, ARG12_, ARG13_, ARG14_, ARG15_, ARG16_, ARG17_, ARG18_, ARG19_, RESULT_, ...) RESULT_
#define DETAIL__PP_CONCAT_1(A_) DETAIL__PP_CONCAT_X(A_,)
#define DETAIL__PP_CONCAT_2(A_, B_) DETAIL__PP_CONCAT_X(A_, B_)
#define DETAIL__PP_CONCAT_3(A_, B_, C_) DETAIL__PP_CONCAT_2(DETAIL__PP_CONCAT_2(A_, B_), C_)
#define DETAIL__PP_CONCAT_4(A_, B_, C_, D_) DETAIL__PP_CONCAT_2(DETAIL__PP_CONCAT_2(A_, B_), DETAIL__PP_CONCAT_2(C_, D_))
#define DETAIL__PP_CONCAT_5(A_, B_, C_, D_, E_) DETAIL__PP_CONCAT_2(DETAIL__PP_CONCAT_2(A_, B_), DETAIL__PP_CONCAT_3(C_, D_, E_))
#define DETAIL__PP_CONCAT_6(A_, B_, C_, D_, E_, F_) DETAIL__PP_CONCAT_2(DETAIL__PP_CONCAT_2(A_, B_), DETAIL__PP_CONCAT_4(C_, D_, E_, F_))
#define DETAIL__PP_CONCAT_7(A_, B_, C_, D_, E_, F_, G_) DETAIL__PP_CONCAT_2(DETAIL__PP_CONCAT_3(A_, B_, C_), DETAIL__PP_CONCAT_4(D_, E_, F_, G_))
#define DETAIL__PP_CONCAT_8(A_, B_, C_, D_, E_, F_, G_, H_) DETAIL__PP_CONCAT_2(DETAIL__PP_CONCAT_4(A_, B_, C_, D_), DETAIL__PP_CONCAT_4(E_, F_, G_, H_))
#define DETAIL__PP_EVAL1024(...) DETAIL__PP_EVAL512(DETAIL__PP_EVAL512(__VA_ARGS__))
#define DETAIL__PP_EVAL512(...) DETAIL__PP_EVAL256(DETAIL__PP_EVAL256(__VA_ARGS__))
#define DETAIL__PP_EVAL256(...) DETAIL__PP_EVAL128(DETAIL__PP_EVAL128(__VA_ARGS__))
#define DETAIL__PP_EVAL128(...) DETAIL__PP_EVAL64(DETAIL__PP_EVAL64(__VA_ARGS__))
#define DETAIL__PP_EVAL64(...) DETAIL__PP_EVAL32(DETAIL__PP_EVAL32(__VA_ARGS__))
#define DETAIL__PP_EVAL32(...) DETAIL__PP_EVAL16(DETAIL__PP_EVAL16(__VA_ARGS__))
#define DETAIL__PP_EVAL16(...) DETAIL__PP_EVAL8(DETAIL__PP_EVAL8(__VA_ARGS__))
#define DETAIL__PP_EVAL8(...) DETAIL__PP_EVAL4(DETAIL__PP_EVAL4(__VA_ARGS__))
#define DETAIL__PP_EVAL4(...) DETAIL__PP_EVAL2(DETAIL__PP_EVAL2(__VA_ARGS__))
#define DETAIL__PP_EVAL2(...) DETAIL__PP_EVAL1(DETAIL__PP_EVAL1(__VA_ARGS__))
#define DETAIL__PP_EVAL1(...) __VA_ARGS__
#define DETAIL__PP_CONST_VALUE_ARR(EXPR_) core::detail::ConstValueHelper<sizeof(core::detail::ReturnCharIfString(EXPR_))>::arr
// Extract the high bits of x. We cannot just do (x & 0xffff0000) because 0x7fffffff is the maximum permitted array size on 32bit, so we have to shift
// and the array is not allowed to be size 0, so we add 0x10000 to ensure nonzero
#define DETAIL__PP_CONST_VALUE_HIGHBITS(EXPR_) ((sizeof(DETAIL__PP_CONST_VALUE_ARR(EXPR_)[ ((ptrdiff_t)(EXPR_) >> 16) + 0x10000]) - 0x10000) << 16)
// Extract the low bits of x - as with the high bits, the array cannot be zero-length, so we add 1 and then subtract it again after the sizeof
#define DETAIL__PP_CONST_VALUE_LOWBITS(EXPR_) (sizeof(DETAIL__PP_CONST_VALUE_ARR(EXPR_)[ ((ptrdiff_t)(EXPR_) & 0xFFFF) + 1]) - 1)
#define DETAIL__PP_STRINGIZE_EXPAND(EXPR_) #EXPR_
// Expand to 1 if the first argument is DETAIL__PP_PROBE(), 0 otherwise
#define DETAIL__PP_IS_PROBE(...) PP_DEFER(PP_SECOND)(__VA_ARGS__, 0)
#define DETAIL__PP_PROBE() _, 1
#define DETAIL__PP_BOOLIFY_NOT(EXPR_) PP_DEFER(DETAIL__PP_IS_PROBE)(PP_CONCAT(DETAIL__PP_BOOLIFY_NOT_PROBE_, EXPR_))
#define DETAIL__PP_BOOLIFY_NOT_PROBE_0 DETAIL__PP_PROBE()
#define DETAIL__PP_BOOLIFY_NOT_PROBE_1 0
#define DETAIL__PP_VARG_END_MARKER() 0
#define DETAIL__PP_VARG_UNPAREN_FIRST(...) DETAIL__PP_UNPAREN_EVAL_AND_CONCAT_FIRST_2_ARGS(DETAIL__PP_UNPAREN_EMPTY_, DETAIL__PP_UNPAREN_HELPER __VA_ARGS__)
#define DETAIL__PP_IF_ELSE(EXPR_) PP_CONCAT(DETAIL__PP_IF_, EXPR_)
#define DETAIL__PP_IF_1(...) __VA_ARGS__ DETAIL__PP_IF_1_ELSE
#define DETAIL__PP_IF_0(...) DETAIL__PP_IF_0_ELSE
#define DETAIL__PP_IF_1_ELSE(...)
#define DETAIL__PP_IF_0_ELSE(...) __VA_ARGS__
#define DETAIL__PP_MAP_NONOPTIONAL(MACRO_, FIRST_, ...) MACRO_(FIRST_) PP_IF_ELSE(PP_VARG_IS_NONEMPTY(__VA_ARGS__))( PP_DEFER2(DETAIL__PP_MAP_RECURSE)()(MACRO_, __VA_ARGS__) )()
#define DETAIL__PP_MAP_RECURSE() DETAIL__PP_MAP_NONOPTIONAL
#define DETAIL__PP_UNPAREN_CONCAT_FIRST_2_ARGS(x, ...) x##__VA_ARGS__
#define DETAIL__PP_UNPAREN_EVAL_AND_CONCAT_FIRST_2_ARGS(x, ...) DETAIL__PP_UNPAREN_CONCAT_FIRST_2_ARGS(x, __VA_ARGS__)
#define DETAIL__PP_UNPAREN_EMPTY_DETAIL__PP_UNPAREN_HELPER
#define DETAIL__PP_UNPAREN_HELPER(...) DETAIL__PP_UNPAREN_HELPER __VA_ARGS__
#if __cplusplus
namespace core
{
namespace detail
{
char ReturnCharIfString(const char*);
long ReturnCharIfString(unsigned int);
long ReturnCharIfString(int);
long ReturnCharIfString(float);
template<int dummy> struct ConstValueHelper { typedef char arr; };
template<> struct ConstValueHelper<sizeof(char)> { static char arr[1]; };
}
}
#endif
#endif /* DETAIL__PP_AND_DETAILS_CORE_MACROS_DEFINED */

View File

@@ -0,0 +1,53 @@
#pragma once
// Detect BASELIB_PLATFORM_X define.
//
// Note that PLATFORM_X defines in Unity code base may refer to one or more platforms defined by BASELIB_PLATFORM_X
// Platforms here are very loosely defined on the set of available system apis.
// They have closest relation with the platform toolchains defined in Bee.
#if defined(_XBOX_ONE)
#define BASELIB_PLATFORM_XBOXONE 1
#elif defined(__NX__)
#define BASELIB_PLATFORM_SWITCH 1
#elif defined __ORBIS__
#define BASELIB_PLATFORM_PS4 1
#elif defined __PROSPERO__
#define BASELIB_PLATFORM_PS5 1
#elif defined __EMSCRIPTEN__
#define BASELIB_PLATFORM_EMSCRIPTEN 1
#elif defined __wasi__
#define BASELIB_PLATFORM_WASI 1
#elif defined(__APPLE__)
#include <TargetConditionals.h>
#if TARGET_OS_IOS
#define BASELIB_PLATFORM_IOS 1
#elif TARGET_OS_TV
#define BASELIB_PLATFORM_TVOS 1
#elif TARGET_OS_OSX || TARGET_OS_MAC
#define BASELIB_PLATFORM_MACOS 1
#endif
#elif defined(__NetBSD__)
#define BASELIB_PLATFORM_NETBSD 1
#elif defined(linux) || defined(__linux__)
#if defined(LUMIN)
#define BASELIB_PLATFORM_LUMIN 1
#elif defined(GGP)
#define BASELIB_PLATFORM_STADIA 1
#elif defined(ANDROID) || defined(__ANDROID__)
#define BASELIB_PLATFORM_ANDROID 1
#elif defined(EMBEDDED_LINUX)
#define BASELIB_PLATFORM_EMBEDDED_LINUX 1
#else
#define BASELIB_PLATFORM_LINUX 1
#endif
#elif defined(_WIN32) || defined(__WIN32__)
#include <winapifamily.h>
#if (defined(WINAPI_FAMILY_GAMES) && (WINAPI_FAMILY == WINAPI_FAMILY_GAMES))
#define BASELIB_PLATFORM_WINDOWSGAMES 1
#elif WINAPI_FAMILY == WINAPI_FAMILY_APP
#define BASELIB_PLATFORM_WINRT 1
#else
#define BASELIB_PLATFORM_WINDOWS 1
#endif
#endif

View File

@@ -0,0 +1,24 @@
#pragma once
// This header handles the selection of the correct compiler and platform
// environment for the current build.
#if _MSC_VER
#include "Compiler/CompilerEnvironmentMsvc.h"
#elif __clang__
#include "Compiler/CompilerEnvironmentClang.h"
#elif __GNUC__ || __GCC__
#include "Compiler/CompilerEnvironmentGcc.h"
#else
#error "Unknown Compiler"
#endif
// There is one platform specific environment header for every platform.
// You need to specify the right platform specific include path for the correct one to be picked up.
#include "BaselibPlatformSpecificEnvironment.h"
#include "VerifyPlatformEnvironment.h"
#ifndef BASELIB_DEBUG_TRAP
#define BASELIB_DEBUG_TRAP COMPILER_DEBUG_TRAP
#endif

View File

@@ -0,0 +1,41 @@
// DO NOT PUT #pragma once or include guard check here
// This header is designed to be able to be included multiple times
// This header is used to redefine compiler macros after they were temporary undefined by UndefineCompilerMacros.h
// Please make sure to always use this paired with the UndefineCompilerMacros.h header.
//
// ex.
//
// #include "UndefineCompilerMacros.h"
// #include "Some3rdParty.h"
// #include "RedefineCompilerMacros.h"
#ifndef DETAIL__COMPILERMACROS_HAD_BEEN_UNDEFINED_BY_UNDEFINECOMPILER_H
#error "RedefineCompilerMacros.h can only be used after UndefinePlatforms.h got included before."
#endif
#undef DETAIL__COMPILERMACROS_HAD_BEEN_UNDEFINED_BY_UNDEFINECOMPILER_H
#undef COMPILER_GCC
#if defined(DETAIL__TEMP_COMPILER_GCC_WAS_1)
#undef DETAIL__TEMP_COMPILER_GCC_WAS_1
#define COMPILER_GCC 1
#else
#define COMPILER_GCC 0
#endif
#undef COMPILER_CLANG
#if defined(DETAIL__TEMP_COMPILER_CLANG_WAS_1)
#undef DETAIL__TEMP_COMPILER_CLANG_WAS_1
#define COMPILER_CLANG 1
#else
#define COMPILER_CLANG 0
#endif
#undef COMPILER_MSVC
#if defined(DETAIL__TEMP_COMPILER_MSVC_WAS_1)
#undef DETAIL__TEMP_COMPILER_MSVC_WAS_1
#define COMPILER_MSVC 1
#else
#define COMPILER_MSVC 0
#endif

View File

@@ -0,0 +1,32 @@
// DO NOT PUT #pragma once or include guard check here
// This header is designed to be able to be included multiple times
// This header is used to temporary undefine all compiler macros in case there is a naming conflict with
// 3rd party code. Please make sure to always use this paired with the RedefineCompilerMacros.h header.
//
// ex.
//
// #include "UndefineCompilerMacros.h"
// #include "Some3rdParty.h"
// #include "RedefineCompilerMacros.h"
#ifdef DETAIL__COMPILERMACROS_HAD_BEEN_UNDEFINED_BY_UNDEFINECOMPILER_H
#error "UndefineCompilerMacros.h has been included more than once or RedefineCompilerMacros.h is missing."
#endif
#if COMPILER_GCC
#define DETAIL__TEMP_COMPILER_GCC_WAS_1
#endif
#undef COMPILER_GCC
#if COMPILER_CLANG
#define DETAIL__TEMP_COMPILER_CLANG_WAS_1
#endif
#undef COMPILER_CLANG
#if COMPILER_MSVC
#define DETAIL__TEMP_COMPILER_MSVC_WAS_1
#endif
#undef COMPILER_MSVC
#define DETAIL__COMPILERMACROS_HAD_BEEN_UNDEFINED_BY_UNDEFINECOMPILER_H

View File

@@ -0,0 +1,18 @@
// DO NOT PUT #pragma once or include guard check here
// This header is designed to be able to be included multiple times
// We ignore PP_ and DETAIL__PP_
// It should not generate a warning if the same redefined with exactly the same
#undef FORCE_INLINE
#undef OPTIMIZER_LIKELY
#undef OPTIMIZER_UNLIKELY
#undef UNUSED
#undef COMPILER_WARNING
#undef UNSIGNED_FLAGS_1
#undef UNSIGNED_FLAGS_2
#undef UNSIGNED_FLAGS_3
#undef UNSIGNED_FLAGS_4
#undef UNSIGNED_FLAGS_5
#undef UNSIGNED_FLAGS_6
#undef UNSIGNED_FLAGS

View File

@@ -0,0 +1,128 @@
#pragma once
// This header verifies that all required platform defines have been provided by the
// BaselibPlatformEnvironment and defines all non-defined optional macros to 0. Please make
// sure to verify the proper definition of newly added platform defines here.
#ifndef EXPORTED_SYMBOL
#error "BaselibPlatformSpecificEnvironment is expected to define EXPORTED_SYMBOL."
#endif
#ifndef IMPORTED_SYMBOL
#error "BaselibPlatformSpecificEnvironment is expected to define IMPORTED_SYMBOL."
#endif
#ifndef PLATFORM_FUTEX_NATIVE_SUPPORT
#error "BaselibPlatformSpecificEnvironment is expected to define PLATFORM_FUTEX_NATIVE_SUPPORT to 0 or 1."
#endif
// define all other platforms to 0
#ifndef BASELIB_PLATFORM_WINDOWS
#define BASELIB_PLATFORM_WINDOWS 0
#endif
#ifndef BASELIB_PLATFORM_MACOS
#define BASELIB_PLATFORM_MACOS 0
#endif
#ifndef BASELIB_PLATFORM_LINUX
#define BASELIB_PLATFORM_LINUX 0
#endif
#ifndef BASELIB_PLATFORM_EMBEDDED_LINUX
#define BASELIB_PLATFORM_EMBEDDED_LINUX 0
#endif
#ifndef BASELIB_PLATFORM_WINRT
#define BASELIB_PLATFORM_WINRT 0
#endif
#ifndef BASELIB_PLATFORM_FAMILY_WINDOWSGAMES
#define BASELIB_PLATFORM_FAMILY_WINDOWSGAMES 0
#endif
#ifndef BASELIB_PLATFORM_EMSCRIPTEN
#define BASELIB_PLATFORM_EMSCRIPTEN 0
#endif
#ifndef BASELIB_PLATFORM_WASI
#define BASELIB_PLATFORM_WASI 0
#endif
#ifndef BASELIB_PLATFORM_ANDROID
#define BASELIB_PLATFORM_ANDROID 0
#endif
#ifndef BASELIB_PLATFORM_PS4
#define BASELIB_PLATFORM_PS4 0
#endif
#ifndef BASELIB_PLATFORM_PS5
#define BASELIB_PLATFORM_PS5 0
#endif
#ifndef BASELIB_PLATFORM_IOS
#define BASELIB_PLATFORM_IOS 0
#endif
#ifndef BASELIB_PLATFORM_TVOS
#define BASELIB_PLATFORM_TVOS 0
#endif
#ifndef BASELIB_PLATFORM_XBOXONE
#define BASELIB_PLATFORM_XBOXONE 0
#endif
#ifndef BASELIB_PLATFORM_SWITCH
#define BASELIB_PLATFORM_SWITCH 0
#endif
#ifndef BASELIB_PLATFORM_LUMIN
#define BASELIB_PLATFORM_LUMIN 0
#endif
#ifndef BASELIB_PLATFORM_STADIA
#define BASELIB_PLATFORM_STADIA 0
#endif
#ifndef BASELIB_PLATFORM_NETBSD
#define BASELIB_PLATFORM_NETBSD 0
#endif
// Define all other compilers with 0
#ifndef COMPILER_MSVC
#define COMPILER_MSVC 0
#endif
#ifndef COMPILER_GCC
#define COMPILER_GCC 0
#endif
#ifndef COMPILER_CLANG
#define COMPILER_CLANG 0
#endif
// Make sure no platform is defined twice.
// Note that having no known platform defined is accepted.
#if BASELIB_PLATFORM_WINDOWS + \
BASELIB_PLATFORM_MACOS + \
BASELIB_PLATFORM_LINUX + \
BASELIB_PLATFORM_EMBEDDED_LINUX + \
BASELIB_PLATFORM_WINRT + \
BASELIB_PLATFORM_FAMILY_WINDOWSGAMES + \
BASELIB_PLATFORM_EMSCRIPTEN + \
BASELIB_PLATFORM_WASI + \
BASELIB_PLATFORM_ANDROID + \
BASELIB_PLATFORM_PS4 + \
BASELIB_PLATFORM_PS5 + \
BASELIB_PLATFORM_IOS + \
BASELIB_PLATFORM_TVOS + \
BASELIB_PLATFORM_XBOXONE + \
BASELIB_PLATFORM_SWITCH + \
BASELIB_PLATFORM_LUMIN + \
BASELIB_PLATFORM_STADIA + \
BASELIB_PLATFORM_NETBSD \
> 1
#error "Only a single BASELIB_PLATFORM_X is allowed to be set to 1"
#endif