|
|
|
|
@@ -1,158 +0,0 @@
|
|
|
|
|
typedef struct arr_header_t arr_header_t;
|
|
|
|
|
struct arr_header_t {
|
|
|
|
|
i64 len;
|
|
|
|
|
i64 cap;
|
|
|
|
|
ma_arena_t *arena;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
#define arr_header(arr) ((arr_header_t *)(arr) - 1)
|
|
|
|
|
#define arr_len(arr) (arr_header(arr)->len)
|
|
|
|
|
#define arr_cap(arr) (arr_header(arr)->cap)
|
|
|
|
|
#define arr_add(arr, x) (arr_grow(&(arr), sizeof(*(arr)), 1), (arr)[arr_len(arr)++] = (x))
|
|
|
|
|
#define arr_addn(arr, count) (arr_grow(&(arr), sizeof(*(arr)), (count)), arr_len(arr) += (count), &(arr)[arr_len(arr) - (count)])
|
|
|
|
|
#define arr_set_len(arr, x) (arr_len(arr) = (x))
|
|
|
|
|
#define arr_set_cap(arr, x) (arr__set_cap(&(arr), sizeof(*(arr)), (x)))
|
|
|
|
|
#define arr_pop(arr) ((arr)[--arr_len(arr)])
|
|
|
|
|
#define arr_swapdel(arr, i) (assert_expr((i) < arr_len(arr)), (arr)[(i)] = (arr)[--arr_len(arr)])
|
|
|
|
|
#define arr_del(arr, i) arr__del((arr), sizeof(*(arr)), (i), 1)
|
|
|
|
|
#define arr_deln(arr, i, count) arr__del((arr), sizeof(*(arr)), (i), (count))
|
|
|
|
|
#define arr_insert(arr, i, x) (arr__insert(&arr, sizeof(*(arr)), (i)), (arr)[(i)] = (x))
|
|
|
|
|
#define arr_create(arena, type, count) (type *)(arr__create((arena), sizeof(type), (count)) + 1)
|
|
|
|
|
#define arr_copy(arena, arr) arr__copy((arena), (arr), sizeof(*(arr)))
|
|
|
|
|
|
|
|
|
|
fn arr_header_t *arr__create(ma_arena_t *arena, i64 item_size, i64 item_count) {
|
|
|
|
|
arr_header_t *hdr = (arr_header_t *)ma_push_size(arena, item_size * item_count + sizeof(arr_header_t));
|
|
|
|
|
hdr->arena = arena;
|
|
|
|
|
hdr->cap = item_count;
|
|
|
|
|
return hdr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn void *arr__copy(ma_arena_t *arena, void *arr, i64 item_size) {
|
|
|
|
|
arr_header_t *hdr = arr_header(arr);
|
|
|
|
|
arr_header_t *new_hdr = arr__create(arena, item_size, hdr->cap);
|
|
|
|
|
new_hdr->len = hdr->len;
|
|
|
|
|
memory_copy(new_hdr + 1, hdr + 1, new_hdr->len * item_size);
|
|
|
|
|
return new_hdr + 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn void arr__set_cap(void **arr, i64 item_size, i64 item_count) {
|
|
|
|
|
assert(item_count >= 0);
|
|
|
|
|
arr_header_t *hdr = arr_header(*arr);
|
|
|
|
|
arr_header_t *new_hdr = arr__create(hdr->arena, item_size, item_count);
|
|
|
|
|
new_hdr->len = CLAMP(hdr->len, 0, item_count);
|
|
|
|
|
memory_copy(new_hdr + 1, hdr + 1, new_hdr->len * item_size);
|
|
|
|
|
*arr = new_hdr + 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn void arr_grow(void **arr, i64 item_size, i64 increment) {
|
|
|
|
|
assert(increment >= 1);
|
|
|
|
|
arr_header_t *hdr = arr_header(*arr);
|
|
|
|
|
if (hdr->len + increment > hdr->cap) {
|
|
|
|
|
arr_header_t *new_hdr = arr__create(hdr->arena, item_size, (hdr->cap + increment - 1) * 2);
|
|
|
|
|
memory_copy(new_hdr + 1, hdr + 1, hdr->len * item_size);
|
|
|
|
|
new_hdr->len = hdr->len;
|
|
|
|
|
*arr = new_hdr + 1;
|
|
|
|
|
// dealloc(hdr);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn void arr__insert(void **arr, i64 item_size, i64 idx) {
|
|
|
|
|
arr_grow(arr, item_size, 1);
|
|
|
|
|
arr_header_t *hdr = arr_header(*arr);
|
|
|
|
|
assert(idx <= hdr->len);
|
|
|
|
|
assert(idx >= 0);
|
|
|
|
|
|
|
|
|
|
u8 *arr8 = (u8 *)*arr;
|
|
|
|
|
i64 right_len = hdr->len - idx;
|
|
|
|
|
memory_move(arr8 + (idx + 1)*item_size, arr8 + idx*item_size, item_size * right_len);
|
|
|
|
|
hdr->len += 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn void arr__del(void *arr, i64 item_size, i64 idx, i64 count) {
|
|
|
|
|
arr_header_t *hdr = arr_header(arr);
|
|
|
|
|
assert(idx >= 0 && idx < hdr->len);
|
|
|
|
|
assert((idx + count) > 0 && (idx + count) <= hdr->len);
|
|
|
|
|
i64 right_len = hdr->len - idx - count;
|
|
|
|
|
u8 *arr8 = (u8 *)arr;
|
|
|
|
|
memmove(arr8+idx*item_size, arr8+(idx+count)*item_size, right_len*item_size);
|
|
|
|
|
hdr->len -= count;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn_test void test_arr(void) {
|
|
|
|
|
ma_temp_t scratch = ma_begin_scratch();
|
|
|
|
|
int *arr = arr_create(scratch.arena, int, 2);
|
|
|
|
|
for (int i = 0; i < 512; i += 1) {
|
|
|
|
|
arr_add(arr, i);
|
|
|
|
|
}
|
|
|
|
|
for (int i = 0; i < 512; i += 1) {
|
|
|
|
|
assert(arr[i] == i);
|
|
|
|
|
}
|
|
|
|
|
assert(arr_len(arr) == 512);
|
|
|
|
|
assert(arr_cap(arr) == 512);
|
|
|
|
|
for (int i = 511; i >= 0; i -= 1) {
|
|
|
|
|
int a = arr_pop(arr);
|
|
|
|
|
assert(a == i);
|
|
|
|
|
}
|
|
|
|
|
assert(arr_len(arr) == 0);
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
int *a = arr_addn(arr, 4);
|
|
|
|
|
assert(arr == a);
|
|
|
|
|
assert(arr_header(arr)->len == 4);
|
|
|
|
|
|
|
|
|
|
int *b = arr_addn(arr, 12);
|
|
|
|
|
assert(arr + 4 == b);
|
|
|
|
|
assert(arr_header(arr)->len == 16);
|
|
|
|
|
|
|
|
|
|
arr_set_len(arr, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
for (int i = 0; i < 512; i += 1) {
|
|
|
|
|
arr_add(arr, i);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
arr_swapdel(arr, 3);
|
|
|
|
|
assert(arr[3] == 511);
|
|
|
|
|
assert(arr_len(arr) == 511);
|
|
|
|
|
|
|
|
|
|
arr_set_len(arr, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
for (int i = 0; i < 512; i += 1) {
|
|
|
|
|
arr_add(arr, i);
|
|
|
|
|
}
|
|
|
|
|
arr_set_cap(arr, 256);
|
|
|
|
|
assert(arr_len(arr) == 256);
|
|
|
|
|
assert(arr_cap(arr) == 256);
|
|
|
|
|
|
|
|
|
|
arr_insert(arr, 256, 111);
|
|
|
|
|
assert(arr_len(arr) == 257);
|
|
|
|
|
assert(arr_cap(arr) > 256);
|
|
|
|
|
assert(arr[256] == 111);
|
|
|
|
|
|
|
|
|
|
arr_insert(arr, 4, 222);
|
|
|
|
|
assert(arr_len(arr) == 258);
|
|
|
|
|
assert(arr_cap(arr) > 256);
|
|
|
|
|
assert(arr[4] == 222);
|
|
|
|
|
assert(arr[3] == 3);
|
|
|
|
|
assert(arr[5] == 4);
|
|
|
|
|
|
|
|
|
|
arr_set_len(arr, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
for (int i = 0; i < 512; i += 1) {
|
|
|
|
|
arr_add(arr, i);
|
|
|
|
|
}
|
|
|
|
|
arr_deln(arr, 1, 10);
|
|
|
|
|
assert(arr[0] == 0);
|
|
|
|
|
assert(arr[1] == 11);
|
|
|
|
|
assert(arr_len(arr) == (512 - 10));
|
|
|
|
|
arr_del(arr, 0);
|
|
|
|
|
assert(arr[0] == 11);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ma_end_scratch(scratch);
|
|
|
|
|
}
|