Files
Juliet/Juliet/include/Core/Common/CoreUtils.h
T

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