#pragma once #include "CoreTypes.h" #include "TypeTraits/TypeTraits.h" #include NAMESPACE_REDCRAFT_BEGIN NAMESPACE_MODULE_BEGIN(Redcraft) NAMESPACE_MODULE_BEGIN(Utility) NAMESPACE_PRIVATE_BEGIN template struct TVarArgsAssert { static_assert(CArithmetic || CEnum || CPointer || CMemberPointer || CClass, "The type must be arithmetic, enum, pointer, member pointer, or class"); static_assert(!CNullPointer, "The 'nullptr_t' is promoted to 'void*' when passed through '...'"); static_assert(!CSameAs, "The 'float' is promoted to 'double' when passed through '...'"); static_assert(!CSameAs, "The 'bool' is promoted to 'int' when passed through '...'"); static_assert(!CSameAs, "The 'char' is promoted to 'int' when passed through '...'"); static_assert(!CSameAs, "The 'short' is promoted to 'int' when passed through '...'"); static_assert(CSameAs>, "The 'const' and 'volatile' qualifiers are removed when passed through '...'"); static_assert(!CEnum || CScopedEnum, "The unscoped enum is promoted to 'int' when passed through '...'"); static_assert(!CClass || CTriviallyCopyable, "The non-trivially copyable class is not supported"); }; template inline constexpr TVarArgsAssert VarArgsAssert{ }; NAMESPACE_PRIVATE_END /** Enables access to variadic function arguments. */ #define VARARGS_ACCESS_BEGIN(ContextName, NamedParam) NAMESPACE_STD::va_list ContextName; va_start(ContextName, NamedParam) /** Makes a copy of the variadic function arguments. */ #define VARARGS_ACCESS_COPY(ContextName, ContextSource) NAMESPACE_STD::va_list ContextName; va_copy(ContextName, ContextSource) /** Accesses the next variadic function argument. */ #define VARARGS_ACCESS(ContextName, Type) (NAMESPACE_PRIVATE::VarArgsAssert, va_arg(ContextName, Type)) /** Ends traversal of the variadic function arguments. */ #define VARARGS_ACCESS_END(ContextName) va_end(ContextName) NAMESPACE_MODULE_END(Utility) NAMESPACE_MODULE_END(Redcraft) NAMESPACE_REDCRAFT_END