convert math functions to generics
This commit is contained in:
parent
c27b200984
commit
30153e1af3
@ -4,8 +4,6 @@ FLAlloc FL_ALLOC = {0};
|
|||||||
Allocator ALLOC = {0};
|
Allocator ALLOC = {0};
|
||||||
read_only FLNode FL_NIL_NODE = {0};
|
read_only FLNode FL_NIL_NODE = {0};
|
||||||
|
|
||||||
#define ALLOC_CAP 16
|
|
||||||
|
|
||||||
// ::Allocator::Util::Header::
|
// ::Allocator::Util::Header::
|
||||||
|
|
||||||
usize CalcPaddingWithHeader(uintptr ptr, uintptr alignment, usize header_size)
|
usize CalcPaddingWithHeader(uintptr ptr, uintptr alignment, usize header_size)
|
||||||
@ -104,33 +102,64 @@ static Arena * ArenaInitDebug(rawptr buffer, usize length, u32 init_line_no)
|
|||||||
|
|
||||||
static void InitAllocator(usize init_size)
|
static void InitAllocator(usize init_size)
|
||||||
{
|
{
|
||||||
ALLOC.tree = FLMemAlloc(sizeof(RBTree));
|
ALLOC.grow_size = init_size;
|
||||||
RBTreeInit(ALLOC.tree);
|
ALLOC.buffer = MemAllocZeroed(init_size);
|
||||||
|
ALLOC.size = init_size;
|
||||||
|
ALLOC.free_size = init_size;
|
||||||
|
|
||||||
ALLOC.hash_table = FLMemAlloc(sizeof(HashTable));
|
ALLOC.hash_table = FLMemAlloc(sizeof(HashTable));
|
||||||
HashTableInit(ALLOC.hash_table, 32);
|
HashTableInit(ALLOC.hash_table, 32);
|
||||||
|
|
||||||
ALLOC.buffers = FLMemAlloc(sizeof(FreeListBuffer) * ALLOC_CAP);
|
ALLOC.tree = FLMemAlloc(sizeof(RBTree));
|
||||||
ALLOC.count = 1;
|
RBTreeInit(ALLOC.tree);
|
||||||
ALLOC.cap = ALLOC_CAP;
|
|
||||||
ALLOC.grow_size = init_size;
|
AllocInfo *info = CreateAllocInfo(ALLOC.buffer);
|
||||||
|
|
||||||
InitAllocatorBuffer(&ALLOC.buffers[0], init_size);
|
RBTreeFindOrInsert(ALLOC.tree, init_size, info);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void InitAllocatorBuffer(FreeListBuffer *buffer, usize init_size)
|
static AllocInfo *CreateAllocInfo(rawptr ptr)
|
||||||
{
|
{
|
||||||
buffer->buf = MemAllocZeroed(init_size);
|
AllocInfo *info = FLMemAlloc(sizeof(AllocInfo));
|
||||||
buffer->size = init_size;
|
info->ptrs = FLMemAlloc(sizeof(rawptr *));
|
||||||
buffer->free_size = init_size;
|
info->ptrs[0] = ptr;
|
||||||
|
info->count = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void AllocInfoAdd(AllocInfo *info, rawptr ptr)
|
||||||
|
{
|
||||||
|
rawptr *ptrs = FLMemAlloc(sizeof(rawptr) * (info->count+1));
|
||||||
|
MemCpy(ptrs, info->ptrs, sizeof(rawptr) * (info->count+1));
|
||||||
|
FLMemFree(info->ptrs);
|
||||||
|
info->ptrs = ptrs;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void AllocInfoRemove(AllocInfo *info, rawptr ptr)
|
||||||
|
{
|
||||||
|
u32 index = UINT32_MAX;
|
||||||
|
for (u32 i = 0; i < info->count; i++)
|
||||||
|
{
|
||||||
|
if (info->ptrs[i] == ptr)
|
||||||
|
{
|
||||||
|
index = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Assert(index != UINT32_MAX, "AllocInfoRemove called with invalid pointer");
|
||||||
|
|
||||||
|
rawptr *ptrs = FLMemAlloc(sizeof(rawptr) * (info->count-1));
|
||||||
|
MemCpy(ptrs, info->ptrs, index);
|
||||||
|
MemCpy(&ptrs[index], &info->ptrs[index+1], info->count-index-1);
|
||||||
|
|
||||||
|
FLMemFree(info->ptrs);
|
||||||
|
info->ptrs = ptrs;
|
||||||
|
info->count -= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DeinitAlloc()
|
static void DeinitAlloc()
|
||||||
{
|
{
|
||||||
for (u8 i = 0; i < ALLOC.count; i++)
|
MemFree(ALLOC.buffer, ALLOC.size);
|
||||||
{
|
|
||||||
MemFree(ALLOC.buffers[i].buf, ALLOC.buffers[i].size);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static rawptr Alloc(usize size)
|
static rawptr Alloc(usize size)
|
||||||
@ -140,19 +169,30 @@ static rawptr Alloc(usize size)
|
|||||||
|
|
||||||
static rawptr AllocAlign(usize size, usize alignment)
|
static rawptr AllocAlign(usize size, usize alignment)
|
||||||
{
|
{
|
||||||
return NULL;
|
if (size == 0) return NULL;
|
||||||
|
|
||||||
|
usize padding = 0;
|
||||||
|
|
||||||
|
if (alignment < 8)
|
||||||
|
alignment = 8;
|
||||||
|
|
||||||
|
RBNode *node = NULL;
|
||||||
|
RBTreeSearch(ALLOC.tree, size, &node);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Free(rawptr ptr)
|
static void Free(rawptr ptr)
|
||||||
{
|
{
|
||||||
|
if (ptr == NULL) return;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void AllocGrow()
|
static void AllocGrow(usize size)
|
||||||
{
|
{
|
||||||
Assert(ALLOC.count < ALLOC.cap, "Global allocator has reached capacity");
|
usize grow_size = size < ALLOC.grow_size ? ALLOC.grow_size : ALLOC.grow_size + size;
|
||||||
InitAllocatorBuffer(&ALLOC.buffers[ALLOC.count], ALLOC.grow_size);
|
MemRealloc(ALLOC.buffer, ALLOC.size, ALLOC.size + grow_size);
|
||||||
ALLOC.count += 1;
|
ALLOC.size += grow_size;
|
||||||
|
ALLOC.free_size += grow_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ::Allocator::GlobalAlloc::End::
|
// ::Allocator::GlobalAlloc::End::
|
||||||
@ -171,7 +211,7 @@ static rawptr FLMemAlloc(usize size)
|
|||||||
return FreeListAlloc(&FL_ALLOC, size);
|
return FreeListAlloc(&FL_ALLOC, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void FLFree(rawptr ptr)
|
static void FLMemFree(rawptr ptr)
|
||||||
{
|
{
|
||||||
FreeListFree(&FL_ALLOC, ptr);
|
FreeListFree(&FL_ALLOC, ptr);
|
||||||
}
|
}
|
||||||
@ -285,6 +325,8 @@ static void FreeListGrow(FLAlloc *alloc, usize alloc_size)
|
|||||||
|
|
||||||
static rawptr _FreeListAllocAlign(FreeList *alloc, usize size, u32 alignment)
|
static rawptr _FreeListAllocAlign(FreeList *alloc, usize size, u32 alignment)
|
||||||
{
|
{
|
||||||
|
if (size == 0) return NULL;
|
||||||
|
|
||||||
usize padding = 0;
|
usize padding = 0;
|
||||||
FLNode *prev_node = &FL_NIL_NODE;
|
FLNode *prev_node = &FL_NIL_NODE;
|
||||||
|
|
||||||
|
|||||||
@ -32,27 +32,28 @@ static Arena *ArenaInitDebug(rawptr buffer, usize length, u32 init_line_no);
|
|||||||
|
|
||||||
// ::Allocator::GlobalAlloc::Header::
|
// ::Allocator::GlobalAlloc::Header::
|
||||||
|
|
||||||
typedef struct FreeListBuffer
|
typedef struct AllocInfo
|
||||||
{
|
{
|
||||||
rawptr buf;
|
rawptr *ptrs;
|
||||||
u32 size;
|
u32 count;
|
||||||
u32 free_size;
|
} AllocInfo;
|
||||||
} FreeListBuffer;
|
|
||||||
|
|
||||||
typedef struct Allocator
|
typedef struct Allocator
|
||||||
{
|
{
|
||||||
RBTree *tree;
|
RBTree *tree;
|
||||||
FreeListBuffer *buffers;
|
|
||||||
HashTable *hash_table;
|
HashTable *hash_table;
|
||||||
usize grow_size;
|
rawptr buffer;
|
||||||
u64 count;
|
u64 size;
|
||||||
u64 cap;
|
u64 free_size;
|
||||||
|
u64 grow_size;
|
||||||
} Allocator;
|
} Allocator;
|
||||||
|
|
||||||
static void InitAllocator(usize init_size);
|
static void InitAllocator(usize init_size);
|
||||||
static void InitAllocatorBuffer(FreeListBuffer *buffer, usize init_size);
|
static AllocInfo *CreateAllocInfo(rawptr ptr);
|
||||||
|
static void AllocInfoAdd(AllocInfo *info, rawptr ptr);
|
||||||
|
static void AllocInfoRemove(AllocInfo *info, rawptr ptr);
|
||||||
static void DeinitAlloc();
|
static void DeinitAlloc();
|
||||||
static void AllocGrow();
|
static void AllocGrow(usize size);
|
||||||
static rawptr Alloc(usize size);
|
static rawptr Alloc(usize size);
|
||||||
static rawptr AllocAlign(usize size, usize alignment);
|
static rawptr AllocAlign(usize size, usize alignment);
|
||||||
static void Free(rawptr ptr);
|
static void Free(rawptr ptr);
|
||||||
@ -92,7 +93,7 @@ typedef struct FLAlloc
|
|||||||
|
|
||||||
static void GlobalFreeListInit(usize size);
|
static void GlobalFreeListInit(usize size);
|
||||||
static rawptr FLMemAlloc(usize size);
|
static rawptr FLMemAlloc(usize size);
|
||||||
static void FLFree(rawptr ptr);
|
static void FLMemFree(rawptr ptr);
|
||||||
static void _FreeListInit(FreeList **alloc, usize size);
|
static void _FreeListInit(FreeList **alloc, usize size);
|
||||||
static void FreeListInit(FLAlloc *alloc, usize size);
|
static void FreeListInit(FLAlloc *alloc, usize size);
|
||||||
static rawptr _FreeListAllocAlign(FreeList *alloc, usize size, u32 alignment);
|
static rawptr _FreeListAllocAlign(FreeList *alloc, usize size, u32 alignment);
|
||||||
|
|||||||
55
src/ds.c
55
src/ds.c
@ -21,8 +21,19 @@ static void RBTreeInit(RBTree *tree)
|
|||||||
tree->nil = P_RB_NIL;
|
tree->nil = P_RB_NIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static RBNode *RBTreeFindOrInsert(RBTree *tree, RBNode *node)
|
static inline void RBTreeInitNode(RBNode *node, u32 key, rawptr value)
|
||||||
{
|
{
|
||||||
|
node->parent = node->left = node->right = P_RB_NIL;
|
||||||
|
node->color = RB_BLACK;
|
||||||
|
node->key = key;
|
||||||
|
node->data = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
static RBNode *RBTreeFindOrInsert(RBTree *tree, u32 key, rawptr value)
|
||||||
|
{
|
||||||
|
RBNode *node = FLMemAlloc(sizeof(RBNode));
|
||||||
|
RBTreeInitNode(node, key, value);
|
||||||
|
|
||||||
RBNode *existing_node = P_RB_NIL;
|
RBNode *existing_node = P_RB_NIL;
|
||||||
|
|
||||||
node->left = node->right = tree->nil;
|
node->left = node->right = tree->nil;
|
||||||
@ -41,12 +52,12 @@ static RBNode *RBTreeFindOrInsert(RBTree *tree, RBNode *node)
|
|||||||
{
|
{
|
||||||
Assert(curr_node != tree->nil, "Current Node is NIL");
|
Assert(curr_node != tree->nil, "Current Node is NIL");
|
||||||
|
|
||||||
if (curr_node->value == node->value)
|
if (curr_node->key == node->key)
|
||||||
{
|
{
|
||||||
existing_node = curr_node;
|
existing_node = curr_node;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if (curr_node->value < node->value)
|
else if (curr_node->key < node->key)
|
||||||
{
|
{
|
||||||
if (curr_node->right == tree->nil)
|
if (curr_node->right == tree->nil)
|
||||||
{
|
{
|
||||||
@ -124,10 +135,10 @@ static void RBTreeCorrect(RBTree *tree, RBNode *node)
|
|||||||
} while ((p = node->parent));
|
} while ((p = node->parent));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void RBTreeDelete(RBTree *tree, i32 value)
|
static void RBTreeDelete(RBTree *tree, u32 key)
|
||||||
{
|
{
|
||||||
RBNode *node = NULL;
|
RBNode *node = NULL;
|
||||||
Assert(RBTreeSearch(tree, value, &node), "Unable to find node in RBTreeDelete");
|
Assert(RBTreeSearch(tree, key, &node), "Unable to find node in RBTreeDelete");
|
||||||
|
|
||||||
if (node == tree->root && node->left == tree->nil && node->right == tree->nil)
|
if (node == tree->root && node->left == tree->nil && node->right == tree->nil)
|
||||||
{
|
{
|
||||||
@ -140,7 +151,7 @@ static void RBTreeDelete(RBTree *tree, i32 value)
|
|||||||
while (ln->left != tree->nil)
|
while (ln->left != tree->nil)
|
||||||
ln = ln->left;
|
ln = ln->left;
|
||||||
|
|
||||||
node->value = ln->value;
|
node->key = ln->key;
|
||||||
node->data = ln->data;
|
node->data = ln->data;
|
||||||
|
|
||||||
if (node->right == ln)
|
if (node->right == ln)
|
||||||
@ -152,13 +163,13 @@ static void RBTreeDelete(RBTree *tree, i32 value)
|
|||||||
}
|
}
|
||||||
else if (node->color == RB_BLACK && node->left != tree->nil)
|
else if (node->color == RB_BLACK && node->left != tree->nil)
|
||||||
{
|
{
|
||||||
node->value = node->left->value;
|
node->key = node->left->key;
|
||||||
node->data = node->left->data;
|
node->data = node->left->data;
|
||||||
node->left = tree->nil;
|
node->left = tree->nil;
|
||||||
}
|
}
|
||||||
else if (node->color == RB_BLACK && node->right != tree->nil)
|
else if (node->color == RB_BLACK && node->right != tree->nil)
|
||||||
{
|
{
|
||||||
node->value = node->right->value;
|
node->key = node->right->key;
|
||||||
node->data = node->right->data;
|
node->data = node->right->data;
|
||||||
node->right = tree->nil;
|
node->right = tree->nil;
|
||||||
}
|
}
|
||||||
@ -240,7 +251,29 @@ static void RBTreeDelete(RBTree *tree, i32 value)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static b32 RBTreeSearch(RBTree *tree, i32 value, RBNode **out_node)
|
static b32 RBTreeSearchNearest(RBTree *tree, u32 key, RBNode **out_node)
|
||||||
|
{
|
||||||
|
if (tree->root == tree->nil) return false;
|
||||||
|
|
||||||
|
RBNode *node = tree->root;
|
||||||
|
RBNode *nearest = tree->root;
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
if (node->key == key)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (node->left == tree->nil && node->right == tree->nil)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (node->key < key && node->right != tree->nil)
|
||||||
|
node = node->right;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static b32 RBTreeSearch(RBTree *tree, u32 key, RBNode **out_node)
|
||||||
{
|
{
|
||||||
if (tree->root == tree->nil) return false;
|
if (tree->root == tree->nil) return false;
|
||||||
|
|
||||||
@ -249,7 +282,7 @@ static b32 RBTreeSearch(RBTree *tree, i32 value, RBNode **out_node)
|
|||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
if (node->value == value)
|
if (node->key == key)
|
||||||
{
|
{
|
||||||
found = true;
|
found = true;
|
||||||
break;
|
break;
|
||||||
@ -258,7 +291,7 @@ static b32 RBTreeSearch(RBTree *tree, i32 value, RBNode **out_node)
|
|||||||
if (node == tree->nil)
|
if (node == tree->nil)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (node->value < value)
|
if (node->key < key)
|
||||||
node = node->right;
|
node = node->right;
|
||||||
else
|
else
|
||||||
node = node->left;
|
node = node->left;
|
||||||
|
|||||||
10
src/ds.h
10
src/ds.h
@ -30,7 +30,7 @@ typedef struct RBNode
|
|||||||
struct RBNode *child[2];
|
struct RBNode *child[2];
|
||||||
};
|
};
|
||||||
struct RBNode *parent;
|
struct RBNode *parent;
|
||||||
i32 value;
|
u32 key;
|
||||||
rawptr data;
|
rawptr data;
|
||||||
RBNodeColor color;
|
RBNodeColor color;
|
||||||
} RBNode;
|
} RBNode;
|
||||||
@ -42,9 +42,11 @@ typedef struct RBTree
|
|||||||
} RBTree;
|
} RBTree;
|
||||||
|
|
||||||
static void RBTreeInit (RBTree *tree);
|
static void RBTreeInit (RBTree *tree);
|
||||||
static RBNode *RBTreeFindOrInsert(RBTree *tree, RBNode *node);
|
static inline void RBTreeInitNode(RBNode *node, u32 key, rawptr value);
|
||||||
static b32 RBTreeSearch (RBTree *tree, i32 value, RBNode **node);
|
static RBNode *RBTreeFindOrInsert(RBTree *tree, u32 key, rawptr value);
|
||||||
static void RBTreeDelete (RBTree *tree, i32 value);
|
static b32 RBTreeSearchNearest(RBTree *tree, u32 key, RBNode **node);
|
||||||
|
static b32 RBTreeSearch (RBTree *tree, u32 key, RBNode **node);
|
||||||
|
static void RBTreeDelete (RBTree *tree, u32 key);
|
||||||
static void RBTreeLeftRotate (RBTree *tree, RBNode *node);
|
static void RBTreeLeftRotate (RBTree *tree, RBNode *node);
|
||||||
static void RBTreeRightRotate(RBTree *tree, RBNode *node);
|
static void RBTreeRightRotate(RBTree *tree, RBNode *node);
|
||||||
static void RBTreeRotate (RBTree *tree, RBNode *node, RBNodeDir dir);
|
static void RBTreeRotate (RBTree *tree, RBNode *node, RBNodeDir dir);
|
||||||
|
|||||||
@ -1,5 +1,7 @@
|
|||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
|
|
||||||
|
// ::Entry::Linux::Globals::End::
|
||||||
|
|
||||||
#include "entry_linux.h"
|
#include "entry_linux.h"
|
||||||
|
|
||||||
// ::ThirdParty::Include::
|
// ::ThirdParty::Include::
|
||||||
@ -16,12 +18,19 @@
|
|||||||
# include "tests.c"
|
# include "tests.c"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// ::Entry::Linux::Globals::Start::
|
||||||
|
|
||||||
|
constexpr u8 asset_pack[] =
|
||||||
|
{
|
||||||
|
#embed "../assets.sgp"
|
||||||
|
};
|
||||||
|
|
||||||
static_assert(__COUNTER__ < Len(GLOBAL_PROFILER.anchors));
|
static_assert(__COUNTER__ < Len(GLOBAL_PROFILER.anchors));
|
||||||
|
|
||||||
void TraverseNode(RBTree *tree, RBNode *node, RBNodeDir *dir)
|
void TraverseNode(RBTree *tree, RBNode *node, RBNodeDir *dir)
|
||||||
{
|
{
|
||||||
char *dir_str = dir == NULL ? "Root" : *dir == RB_RIGHT ? "Right" : "Left";
|
char *dir_str = dir == NULL ? "Root" : *dir == RB_RIGHT ? "Right" : "Left";
|
||||||
Printfln("Color: %s Value: %d Dir: %s", node->color == RB_RED ? "Red" : "Black", node->value, dir_str);
|
Printfln("Color: %s Value: %d Dir: %s", node->color == RB_RED ? "Red" : "Black", node->key, dir_str);
|
||||||
if (node->left != tree->nil)
|
if (node->left != tree->nil)
|
||||||
{
|
{
|
||||||
RBNodeDir left_dir = RB_LEFT;
|
RBNodeDir left_dir = RB_LEFT;
|
||||||
|
|||||||
@ -841,8 +841,8 @@ static b32 CreateSwapchain()
|
|||||||
u32 width = renderer.vk.sc.extent.width;
|
u32 width = renderer.vk.sc.extent.width;
|
||||||
u32 height = renderer.vk.sc.extent.height;
|
u32 height = renderer.vk.sc.extent.height;
|
||||||
|
|
||||||
extent.width = u32Clamp((u32)width, capabilities.minImageExtent.width, capabilities.maxImageExtent.width);
|
extent.width = Clamp((u32)width, capabilities.minImageExtent.width, capabilities.maxImageExtent.width);
|
||||||
extent.height = u32Clamp((u32)height, capabilities.minImageExtent.height, capabilities.maxImageExtent.height);
|
extent.height = Clamp((u32)height, capabilities.minImageExtent.height, capabilities.maxImageExtent.height);
|
||||||
|
|
||||||
if (present_mode == INT_MAX || format == INT_MAX || color_space == INT_MAX)
|
if (present_mode == INT_MAX || format == INT_MAX || color_space == INT_MAX)
|
||||||
{
|
{
|
||||||
|
|||||||
34
src/util.c
34
src/util.c
@ -119,6 +119,8 @@ void MemZero(void *ptr, isize size)
|
|||||||
|
|
||||||
void MemCpy(rawptr dst, rawptr src, usize size)
|
void MemCpy(rawptr dst, rawptr src, usize size)
|
||||||
{
|
{
|
||||||
|
if (size == 0) return;
|
||||||
|
|
||||||
isize iter_size = size > sizeof(u64) ? 8 : 1;
|
isize iter_size = size > sizeof(u64) ? 8 : 1;
|
||||||
iter_size *= 4;
|
iter_size *= 4;
|
||||||
isize iter_len = size / iter_size;
|
isize iter_len = size / iter_size;
|
||||||
@ -164,35 +166,9 @@ void MemCpy(rawptr dst, rawptr src, usize size)
|
|||||||
|
|
||||||
// ::Util::Math::Functions::Start::
|
// ::Util::Math::Functions::Start::
|
||||||
|
|
||||||
u32 u32Min(u32 l, u32 r)
|
DefMathImpl(Min);
|
||||||
{
|
DefMathImpl(Max);
|
||||||
return l >= r ? r : l;
|
DefMathImpl(Clamp);
|
||||||
}
|
|
||||||
|
|
||||||
i32 i32Min(i32 l, i32 r)
|
|
||||||
{
|
|
||||||
return l >= r ? r : l;
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 u32Max(u32 l, u32 r)
|
|
||||||
{
|
|
||||||
return l >= r ? l : r;
|
|
||||||
}
|
|
||||||
|
|
||||||
i32 i32Max(i32 l, i32 r)
|
|
||||||
{
|
|
||||||
return l >= r ? l : r;
|
|
||||||
}
|
|
||||||
|
|
||||||
i32 i32Clamp(i32 v, i32 min, i32 max)
|
|
||||||
{
|
|
||||||
return i32Min(max, i32Max(v, min));
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 u32Clamp(u32 v, u32 min, u32 max)
|
|
||||||
{
|
|
||||||
return i32Min(max, i32Max(v, min));
|
|
||||||
}
|
|
||||||
|
|
||||||
// ::Util::Math::Functions::End::
|
// ::Util::Math::Functions::End::
|
||||||
|
|
||||||
|
|||||||
60
src/util.h
60
src/util.h
@ -113,12 +113,60 @@ void MemCpy(rawptr dst, rawptr src, usize len);
|
|||||||
|
|
||||||
// ::Util::Math::Functions::Header::
|
// ::Util::Math::Functions::Header::
|
||||||
|
|
||||||
u32 u32Min(u32 l, u32 r);
|
#define DefIntegerImpl(def) \
|
||||||
i32 i32Min(i32 l, i32 r);
|
Def##def(i8); \
|
||||||
u32 u32Max(u32 l, u32 r);
|
Def##def(i16); \
|
||||||
i32 i32Max(i32 l, i32 r);
|
Def##def(i32); \
|
||||||
i32 i32Clamp(i32 v, i32 min, i32 max);
|
Def##def(i64); \
|
||||||
u32 u32Clamp(u32 v, u32 min, u32 max);
|
Def##def(u8); \
|
||||||
|
Def##def(u16); \
|
||||||
|
Def##def(u32); \
|
||||||
|
Def##def(u64)
|
||||||
|
|
||||||
|
#define DefFloatImpl(def) \
|
||||||
|
Def##def(f32); \
|
||||||
|
Def##def(f64)
|
||||||
|
|
||||||
|
#define DefMathImpl(def) \
|
||||||
|
DefIntegerImpl(def); \
|
||||||
|
DefFloatImpl(def);
|
||||||
|
|
||||||
|
#define MathGeneric(fn, params) _Generic(params, \
|
||||||
|
i8: i8##fn, \
|
||||||
|
i16: i16##fn, \
|
||||||
|
i32: i32##fn, \
|
||||||
|
i64: i64##fn, \
|
||||||
|
u8: u8##fn, \
|
||||||
|
u16: u16##fn, \
|
||||||
|
u32: u32##fn, \
|
||||||
|
u64: u64##fn, \
|
||||||
|
f32: f32##fn, \
|
||||||
|
f64: f64##fn \
|
||||||
|
)params
|
||||||
|
|
||||||
|
#define Min(l, r) MathGeneric(Min, (l, r))
|
||||||
|
|
||||||
|
#define Max(l, r) MathGeneric(Max, (l, r))
|
||||||
|
|
||||||
|
#define Clamp(v, min, max) MathGeneric(Clamp, (v, min, max))
|
||||||
|
|
||||||
|
#define DefMin(T) \
|
||||||
|
T T##Min(T l, T r) \
|
||||||
|
{ \
|
||||||
|
return l < r ? l : r; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define DefMax(T) \
|
||||||
|
T T##Max(T l, T r) \
|
||||||
|
{ \
|
||||||
|
return l > r ? l : r; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define DefClamp(T) \
|
||||||
|
T T##Clamp(T v, T min, T max) \
|
||||||
|
{ \
|
||||||
|
return Min(max, Max(v, min)); \
|
||||||
|
}
|
||||||
|
|
||||||
// ::Util::Hashing::Functions::Header::
|
// ::Util::Hashing::Functions::Header::
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user