113 lines
2.9 KiB
C
113 lines
2.9 KiB
C
#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;
|
|
}
|