diff options
Diffstat (limited to 'dynarr.h')
| -rw-r--r-- | dynarr.h | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/dynarr.h b/dynarr.h new file mode 100644 index 0000000..fb577ef --- /dev/null +++ b/dynarr.h @@ -0,0 +1,71 @@ +#ifndef DYNARR_H +#define DYNARR_H + +#include "arena.h" + +#define DYNARR(t) struct { t *data; ptrdiff_t len, cap; } + +#define ZDA_FIT(da, c, zn) ((typeof((da)->data))\ + zda_fit((void **)&(da)->data, sizeof((da)->data[0]),\ + _Alignof(typeof((da)->data[0])), \ + c, &(da)->cap, zn)) + +#define ZDA_FIT_ALIGN(da, c, a, zn) ((typeof((da)->data))\ + zda_fit((void **)&(da)->data, sizeof((da)->data[0]), a,\ + c, &(da)->cap, zn)) + +#define ZDA_GROW(da, n, zn) ZDA_FIT(da, (da)->len + n, zn) + +#define ZDA_PUSH(da, v, zn)\ + (ZDA_GROW(da, 1, zn)[(da)->len++] = (v)) + +#define ZDA_INIT_CAP 32 + +#define DA_FIT(da, c) ((typeof((da)->data))\ + da_fit((void **)&(da)->data, sizeof((da)->data[0]), c, &(da)->cap)) + +#define DA_FIT_ALIGN(da, c, a) ((typeof((da)->data))\ + da_fit((void **)&(da)->data, sizeof((da)->data[0]), a, c, &(da)->cap) + +#define DA_GROW(da, n) DA_FIT(da, (da)->len + n) +#define DA_PUSH(da, ...) (DA_GROW(da, 1)[(da)->len++] = (__VA_ARGS__)) +#define DA_INIT_CAP 32 + +void *da_fit(void **data, ptrdiff_t size, ptrdiff_t fit, ptrdiff_t *cap); +void *zda_fit(void **data, ptrdiff_t size, ptrdiff_t align, ptrdiff_t fit, ptrdiff_t *cap, Arena *a); + +#ifdef DYNARR_IMPL + +#include <stdio.h> +#include <stdlib.h> + +void *da_fit(void **data, ptrdiff_t size, ptrdiff_t fit, ptrdiff_t *cap) { + ptrdiff_t c = *cap; + if (c >= fit) return *data; + if (!c) c = DA_INIT_CAP; + while (c < fit) c <<= 1; + size_t sz = c * size; + void *p = *data ? realloc(*data, sz) : malloc(sz); + if (!p) { + fprintf(stderr, "dynamic array resize failure\n"); + abort(); + } + *cap = c; + *data = p; + return p; +} + +void *zda_fit(void **data, ptrdiff_t size, ptrdiff_t align, ptrdiff_t fit, ptrdiff_t *cap, Arena *a) { + ptrdiff_t C = *cap; + ptrdiff_t c = C; + if (c >= fit) return *data; + if (!c) c = ZDA_INIT_CAP; + while (c < fit) c <<= 1; + void *p = arena_realloc(a, *data, C * size, c * size, align); + *cap = c; + *data = p; + return p; +} + +#endif +#endif |
