diff options
Diffstat (limited to 'util/arr.c')
-rw-r--r-- | util/arr.c | 67 |
1 files changed, 41 insertions, 26 deletions
@@ -1,28 +1,43 @@ -#define arr_declaration(arr_type, type, prefix) typedef struct { \ - type *data; \ - size_t cap; \ - size_t len; \ - } arr_type; \ - static void prefix##create(arr_type *arr) { \ - arr->data = NULL; \ - arr->cap = 0; \ - arr->len = 0; \ - } \ - static void prefix##reserve(arr_type *arr, size_t n) { \ - arr->data = err_realloc(arr->data, n * sizeof(*arr->data)); \ - arr->cap = n; \ - } \ - static void prefix##add(arr_type *arr, type *item) { \ - if (arr->len >= arr->cap) { \ - prefix##reserve(arr, 2 * arr->len + 2); \ - } \ - arr->data[arr->len++] = *item; \ - } \ - static void prefix##clear(arr_type *arr) { \ - free(arr->data); \ - arr->data = NULL; \ - arr->cap = 0; \ - arr->len = 0; \ +typedef struct { + void *data; + void *last; + size_t len; + size_t cap; + size_t item_sz; +} Array; + +void arr_create(Array *arr, size_t item_sz) { + arr->len = arr->cap = 0; + arr->item_sz = item_sz; + arr->data = NULL; + arr->last = NULL; +} + +void arr_reserve(Array *arr, size_t n) { + arr->cap = n; + arr->data = realloc(arr->data, arr->item_sz * arr->cap); + arr->last = (void*)((char*)arr->data + arr->item_sz * (arr->len - 1)); +} + +void *arr_add(Array *arr) { + if (arr->len >= arr->cap) { + arr_reserve(arr, (arr->cap + 2) * 2); } + arr->len++; + arr->last = (char*)arr->last + arr->item_sz; + void *item = arr->last; + return item; +} + +void arr_free(Array *arr) { + free(arr->data); +} + +void arr_clear(Array *arr) { + free(arr->data); + arr->len = arr->cap = 0; + arr->data = NULL; + arr->last = NULL; +} -#define arr_foreach(arr, type, var) for (type *var = (arr).data, *arr_iterate_last_ = (arr).data + ((arr).len - 1); var; (var == arr_iterate_last_) ? var = NULL : var++) +#define arr_foreach(arr, type, var) for (type *var = (arr)->data; var; var == (arr)->last ? var = NULL : var++) |