193 lines
7.1 KiB
C
193 lines
7.1 KiB
C
#pragma once
|
|
|
|
#include <Juliet.h>
|
|
#include <Core/Common/CoreTypes.h>
|
|
|
|
#define global static
|
|
#define internal static
|
|
|
|
#define Glue_(A, B) A##B
|
|
#define Glue(A, B) Glue_(A, B)
|
|
#define StaticAssert(C, ID) global uint8 Glue(ID, __LINE__)[(C) ? 1 : -1]
|
|
|
|
// 1. Stringify helpers
|
|
#define JULIET_STR(x) #x
|
|
#define JULIET_TOSTRING(x) JULIET_STR(x)
|
|
|
|
// 2. Define the pragma operator based on compiler
|
|
#if defined(__clang__) || defined(__GNUC__)
|
|
#define JULIET_PRAGMA(x) _Pragma(#x)
|
|
#define JULIET_SUPPRESS_MSVC(id)
|
|
#define JULIET_SUPPRESS_CLANG(str) JULIET_PRAGMA(clang diagnostic ignored str)
|
|
#elif defined(_MSC_VER)
|
|
#define JULIET_PRAGMA(x) __pragma(x)
|
|
#define JULIET_SUPPRESS_MSVC(id) JULIET_PRAGMA(warning(disable : id))
|
|
#define JULIET_SUPPRESS_CLANG(str)
|
|
#else
|
|
#define JULIET_PRAGMA(x)
|
|
#define JULIET_SUPPRESS_MSVC(id)
|
|
#define JULIET_SUPPRESS_CLANG(str)
|
|
#endif
|
|
|
|
// 3. The Agnostic "Push/Pop"
|
|
#if defined(__clang__)
|
|
#define JULIET_WARNING_PUSH JULIET_PRAGMA(clang diagnostic push)
|
|
#define JULIET_WARNING_POP JULIET_PRAGMA(clang diagnostic pop)
|
|
#elif defined(_MSC_VER)
|
|
#define JULIET_WARNING_PUSH JULIET_PRAGMA(warning(push))
|
|
#define JULIET_WARNING_POP JULIET_PRAGMA(warning(pop))
|
|
#else
|
|
#define JULIET_WARNING_PUSH
|
|
#define JULIET_WARNING_POP
|
|
#endif
|
|
|
|
#if defined(_MSC_VER)
|
|
#define JULIET_PLATFORM_BREAK() (__nop(), __debugbreak())
|
|
#elif defined(__clang__) || defined(__GNUC__)
|
|
#define JULIET_PLATFORM_BREAK() __builtin_trap()
|
|
#else
|
|
#include <signal.h>
|
|
#define JULIET_PLATFORM_BREAK() raise(SIGTRAP)
|
|
#endif
|
|
|
|
#if JULIET_DEBUG
|
|
#define JULIET_ASSERT_INTERNAL(expression, message) \
|
|
do \
|
|
{ \
|
|
if (!(expression)) \
|
|
{ \
|
|
JulietAssert(#expression, message, __FILE__, __func__, (uint32)__LINE__, 0); \
|
|
} \
|
|
} \
|
|
while (0)
|
|
|
|
#define AssertHR(hr_expression, message) \
|
|
do \
|
|
{ \
|
|
long hr_val = (hr_expression); \
|
|
if (hr_val < 0) \
|
|
{ \
|
|
JulietAssert(#hr_expression, message, __FILE__, __func__, (uint32)__LINE__, hr_val); \
|
|
} \
|
|
} \
|
|
while (0)
|
|
|
|
#define GET_ASSERT_MACRO(_1, _2, NAME, ...) NAME
|
|
#define Assert(...) GET_ASSERT_MACRO(__VA_ARGS__, JULIET_ASSERT_INTERNAL, JULIET_ASSERT_NO_MSG)(__VA_ARGS__)
|
|
#define JULIET_ASSERT_NO_MSG(expression) JULIET_ASSERT_INTERNAL(expression, "No additional information provided.")
|
|
|
|
#define Unimplemented() \
|
|
do \
|
|
{ \
|
|
JulietAssert("UNIMPLEMENTED", "This code path is not yet functional.", __FILE__, __func__, (uint32)__LINE__, 0); \
|
|
} \
|
|
while (0)
|
|
|
|
#else
|
|
#define Assert(...) ((void)0)
|
|
#define AssertHR(hr_expression, message) ((void)(hr_expression))
|
|
#define Unimplemented() ((void)0)
|
|
#endif
|
|
|
|
JULIET_API extern void JulietAssert(const char* expression, const char* message, const char* file, const char* function,
|
|
uint32 line, long handle_result);
|
|
|
|
#define ZeroStruct(structInstance) ZeroSize(sizeof(structInstance), &(structInstance))
|
|
#define ZeroArray(array) ZeroSize(sizeof((array)), (array))
|
|
#define ZeroDynArray(Count, Pointer) ZeroSize((Count) * sizeof((Pointer)[0]), (Pointer))
|
|
|
|
static inline void ZeroSize(size_t size, void* ptr)
|
|
{
|
|
uint8* byte_ptr = (uint8*)ptr;
|
|
while (size--)
|
|
{
|
|
*byte_ptr++ = 0;
|
|
}
|
|
}
|
|
|
|
#define Restrict __restrict
|
|
|
|
static inline bool8 IsValidByteBuffer(ByteBuffer buffer)
|
|
{
|
|
return (buffer.Size > 0 && buffer.Data != NULL);
|
|
}
|
|
|
|
extern JULIET_API void FreeByteBuffer(ByteBuffer* buffer);
|
|
|
|
static inline bool8 IsPow2(uint64 x)
|
|
{
|
|
return (x != 0) && ((x & (x - 1)) == 0);
|
|
}
|
|
|
|
static inline uint64 AlignPow2(uint64 x, uint64 alignment)
|
|
{
|
|
Assert(IsPow2(alignment));
|
|
return (x + alignment - 1) & ~(alignment - 1);
|
|
}
|
|
|
|
static inline void SwapMemory(void* Restrict a, void* Restrict b, size_t elem_size)
|
|
{
|
|
uint8* pa = (uint8*)a;
|
|
uint8* pb = (uint8*)b;
|
|
for (size_t i = 0; i < elem_size; ++i)
|
|
{
|
|
uint8 tmp = pa[i];
|
|
pa[i] = pb[i];
|
|
pb[i] = tmp;
|
|
}
|
|
}
|
|
|
|
#if defined(__clang__)
|
|
#define COMPILER_CLANG 1
|
|
#elif defined(_MSC_VER)
|
|
#define COMPILER_MSVC 1
|
|
#endif
|
|
|
|
#if !defined(COMPILER_CLANG)
|
|
#define COMPILER_CLANG 0
|
|
#endif
|
|
#if !defined(COMPILER_MSVC)
|
|
#define COMPILER_MSVC 0
|
|
#endif
|
|
|
|
#if COMPILER_MSVC
|
|
#define AlignOf(T) __alignof(T)
|
|
#elif COMPILER_CLANG
|
|
#define AlignOf(T) __alignof(T)
|
|
#elif COMPILER_GCC
|
|
#define AlignOf(T) __alignof__(T)
|
|
#else
|
|
#error AlignOf not defined for this compiler.
|
|
#endif
|
|
|
|
#if COMPILER_MSVC || (COMPILER_CLANG && defined(_MSC_VER))
|
|
#define ThreadLocal __declspec(thread)
|
|
#else
|
|
#define ThreadLocal __thread
|
|
#endif
|
|
|
|
static inline uint16 safe_cast_uint16(uint32 value)
|
|
{
|
|
Assert(value <= uint16Max);
|
|
uint16 result = (uint16)value;
|
|
return result;
|
|
}
|
|
|
|
#define bitmask1 0x00000001u
|
|
#define bitmask2 0x00000003u
|
|
#define bitmask3 0x00000007u
|
|
#define bitmask4 0x0000000fu
|
|
#define bitmask5 0x0000001fu
|
|
#define bitmask6 0x0000003fu
|
|
#define bitmask7 0x0000007fu
|
|
#define bitmask8 0x000000ffu
|
|
#define bitmask9 0x000001ffu
|
|
#define bitmask10 0x000003ffu
|
|
#define bitmask11 0x000007ffu
|
|
#define bitmask12 0x00000fffu
|
|
#define bitmask13 0x00001fffu
|
|
#define bitmask14 0x00003fffu
|
|
#define bitmask15 0x00007fffu
|
|
#define bitmask16 0x0000ffffu
|
|
#define bitmask32 0xffffffffu
|