#include "array.h" #include "../memory//memory.h" typedef struct BzArrayHead { i32 capacity; i32 size; i32 stride; } BzArrayHead; #define ARRAY_HEAD(array) (((BzArrayHead *) array) -1) void *_bzArrayCreate(i32 startCapacity, i32 stride) { BzArrayHead *head = bzAlloc(sizeof(*head) + startCapacity * stride); BZ_ASSERT(startCapacity > 0); head[0] = (BzArrayHead) { .capacity=startCapacity, .size=0, .stride=stride }; return &head[1]; } void _bzArrayDestroy(void *arr) { bzFree(ARRAY_HEAD(arr)); } void _bzArrayClear(void *arr) { ARRAY_HEAD(arr)->size = 0; } i32 _bzArraySize(void *arr) { return ARRAY_HEAD(arr)->size; } i32 _bzArrayCapacity(void *arr) { return ARRAY_HEAD(arr)->capacity; } void *_bzArrayResize(void **arr, i32 newSize) { BzArrayHead *old = ARRAY_HEAD(*arr); BZ_ASSERT(newSize >= old->size); if (newSize == old->capacity) return *arr; BzArrayHead *new = bzResize(old, sizeof(*new) + newSize * old->stride); new[0].capacity = newSize; return &new[1]; } void *_bzArrayEnsureCapacity(void **arr, i32 capacity) { BzArrayHead *head = ARRAY_HEAD(*arr); if (capacity > head->capacity) return _bzArrayResize(arr, head->capacity << 1); return *arr; } i32 _bzArrayGet(void *arr, i32 idx) { BzArrayHead *head = ARRAY_HEAD(arr); BZ_ASSERT(idx >= 0 && idx < head->size); return idx; } void _bzArrayDelN(void *arr, i32 idx, i32 n) { BzArrayHead *head = ARRAY_HEAD(arr); BZ_ASSERT(n <= head->size); BZ_ASSERT(idx >= 0 && idx + n <= head->size); bzMemMove((u8 *) arr + idx * head->stride, (u8 *) arr + (idx + n) * head->stride, n * head->stride); head->size -= n; } void _bzArrayDelSwap(void *arr, i32 idx) { BzArrayHead *head = ARRAY_HEAD(arr); BZ_ASSERT(idx >= 0 && idx < head->size); i32 lastIdx = head->size - 1; if (idx != lastIdx) { bzMemMove((u8 *) arr + idx * head->stride, (u8 *) arr + (lastIdx) * head->stride, head->stride); } head->size--; } i32 _bzArrayPush(void *arr) { BzArrayHead *head = ARRAY_HEAD(arr); BZ_ASSERT(head->size < head->capacity); i32 insertIdx = head->size; head->size++; return insertIdx; } i32 _bzArrayIns(void *arr, i32 idx) { BzArrayHead *head = ARRAY_HEAD(arr); BZ_ASSERT(idx >= 0 && idx <= head->size); BZ_ASSERT(head->size + 1 <= head->capacity); if (idx != head->size) { bzMemMove((u8 *) arr + (idx + 1) * head->stride, (u8 *) arr + idx * head->stride, head->stride); } head->size++; return idx; } i32 _bzArraySet(void *arr, i32 idx) { BzArrayHead *head = ARRAY_HEAD(arr); BZ_ASSERT(idx >= 0 && idx < head->size); return idx; } i32 _bzArrayPop(void *arr) { BzArrayHead *head = ARRAY_HEAD(arr); BZ_ASSERT(head->size > 0); head->size--; return head->size; }