#if !defined(LD_CORE_MACROS_H_)
#define LD_CORE_MACROS_H_

#include <assert.h>

#define Assert(exp) assert(exp)
#define StaticAssert(exp) static_assert(exp, #exp)

#define ArraySize(x) (sizeof(x) / sizeof((x)[0]))
#define Min(a, b) ((a) < (b) ? (a) : (b))
#define Max(a, b) ((a) > (b) ? (a) : (b))
#define Clamp(min, x, max) (Min(Max(min, x), max))
#define Clamp01(x) Clamp(0, x, 1)

#define cast(x) (x)

#define _Glue(a, b) a##b
#define _Stringify(x) #x

#define Glue(a, b) _Glue(a, b)
#define Stringify(x) _Stringify(x)

#if LANG_CPP
	#define Alignof(x) alignof(x)
#else
	#define Alignof(x) _Alignof(x)
#endif

// Singly linked lists (named members)
//
#define SLL_EnqueueN(h, t, n, next) (((h) == 0) ? ((h) = (t) = (n), (n)->next = 0) : ((t)->next = (n), (t) = (n), (n)->next = 0))
#define SLL_EnqueueFrontN(h, t, n, next) (((h) == 0) ? ((h) = (t) = (n), (n)->next = 0) : ((n)->next = (h), (h) = (n)))
#define SLL_DequeueN(h, t, next) ((h) == (t) ? ((h) = 0, (t) = 0) : ((h) = (h)->next))

#define SLL_PushN(h, n, next) ((n)->next = (h), (h) = (n))
#define SLL_PopN(h, next) (((h) != 0) ? (h) = (h)->next : 0)

#define SLL_Enqueue(h, t, n) SLL_EnqueueN(h, t, n, next)
#define SLL_EnqueueFront(h, t, n) SLL_EnqueueFrontN(h, t, n, next)
#define SLL_Dequeue(h, t) SLL_DequeueN(h, t, next)

#define SLL_Push(h, n) SLL_PushN(h, n, next)
#define SLL_Pop(h) (((h) != 0) ? (h) = (h)->next : 0)

#define function      static
#define internal      static
#define global_var    static
#define local_persist static

#if COMPILER_CL
	#define thread_var __declspec(thread)
#else
	#define thread_var __thread
#endif

#endif  // LD_CORE_MACROS_H_
