82 lines
No EOL
2.2 KiB
C
82 lines
No EOL
2.2 KiB
C
#ifndef COLLA_DARR_HEADER
|
|
#define COLLA_DARR_HEADER
|
|
|
|
/*
|
|
dynamic chunked array which uses an arena to allocate,
|
|
the structure needs to follow this exact format, if you want
|
|
you can use the macro darr_define(struct_name, item_type) instead:
|
|
|
|
////////////////////////////////////
|
|
|
|
typedef struct arr_t arr_t;
|
|
struct arr_t {
|
|
int *items;
|
|
usize block_size;
|
|
usize count;
|
|
arr_t *next;
|
|
arr_t *head;
|
|
};
|
|
// equivalent to
|
|
|
|
darr_define(arr_t, int);
|
|
|
|
////////////////////////////////////
|
|
|
|
by default a chunk is 64 items long, you can change this default
|
|
by modifying the arr.block_size value before adding to the array,
|
|
or by defining DARRAY_DEFAULT_BLOCK_SIZE
|
|
|
|
usage example:
|
|
|
|
////////////////////////////////////
|
|
|
|
darr_define(arr_t, int);
|
|
|
|
arr_t *arr = NULL;
|
|
|
|
for (int i = 0; i < 100; ++i) {
|
|
darr_push(&arena, arr, i);
|
|
}
|
|
|
|
for_each (chunk, arr) {
|
|
for (int i = 0; i < chunk->count; ++i) {
|
|
info("%d -> %d", i, chunk->items[i]);
|
|
}
|
|
}
|
|
*/
|
|
|
|
#define DARRAY_DEFAULT_BLOCK_SIZE (64)
|
|
|
|
#define darr_define(struct_name, item_type) typedef struct struct_name struct_name; \
|
|
struct struct_name { \
|
|
item_type *items; \
|
|
usize block_size; \
|
|
usize count; \
|
|
struct_name *next; \
|
|
struct_name *head; \
|
|
}
|
|
|
|
#define darr__alloc_first(arena, arr) do { \
|
|
(arr) = (arr) ? (arr) : alloc(arena, typeof(*arr)); \
|
|
(arr)->head = (arr)->head ? (arr)->head : (arr); \
|
|
(arr)->block_size = (arr)->block_size ? (arr)->block_size : DARRAY_DEFAULT_BLOCK_SIZE; \
|
|
(arr)->items = alloc(arena, typeof(*arr->items), arr->block_size); \
|
|
assert((arr)->count == 0); \
|
|
} while (0)
|
|
|
|
#define darr__alloc_block(arena, arr) do { \
|
|
typeof(arr) newarr = alloc(arena, typeof(*arr)); \
|
|
newarr->block_size = arr->block_size; \
|
|
newarr->items = alloc(arena, typeof(*arr->items), arr->block_size); \
|
|
newarr->head = arr->head; \
|
|
arr->next = newarr; \
|
|
arr = newarr; \
|
|
} while (0)
|
|
|
|
#define darr_push(arena, arr, item) do { \
|
|
if (!(arr) || (arr)->items == NULL) darr__alloc_first(arena, arr); \
|
|
if ((arr)->count >= (arr)->block_size) darr__alloc_block(arena, arr); \
|
|
(arr)->items[(arr)->count++] = (item); \
|
|
} while (0)
|
|
|
|
#endif |