diff options
Diffstat (limited to 'dynarr.h')
| -rw-r--r-- | dynarr.h | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/dynarr.h b/dynarr.h new file mode 100644 index 0000000..327d5e7 --- /dev/null +++ b/dynarr.h @@ -0,0 +1,59 @@ +#ifndef DYNARR_H +#define DYNARR_H + +#include <stdlib.h> +#include <string.h> +#include <stdint.h> +#include <err.h> + +#define DYNARR(T) struct { uint32_t n, c_; T *v; } + +#define DA_INIT_CAP 32 +#define DA_ELEM(da, n) ((n) * sizeof(*(da)->v)) +#define DA_BIT_CEIL ( + +static inline uint32_t da_bit_ceil(uint32_t x) { + return x ? 1U << (32 - __builtin_clz(x - 1)) : 0; +} + +/* malloc */ + +#define DA_FIT(da, n) do {\ + if ((n) > (da)->c_) {\ + (da)->c_ = da_bit_ceil((uint32_t)(n));\ + (da)->v = realloc((da)->v, DA_ELEM(da, (da)->c_));\ + }\ + if (!(da)->v) err(1, "dynarr fit");\ +} while(0) +#define DA_GROW(da, n_) DA_FIT(da, (da)->n + (n_)) +#define DA_PUSH(da, ...) do {\ + DA_GROW(da, 1);\ + (da)->v[(da)->n++] = (__VA_ARGS__);\ +} while(0) +#define DA_PUSH_MULT(da, o, n_) do {\ + DA_GROW(da, n_);\ + memcpy((da)->v + (da)->n, (o), DA_ELEM(da, n_));\ + (da)->n += (n_);\ +} while(0) + +/* arena */ + +#define DA_AFIT(da, a, n) do {\ + if ((n) > (da)->c_) {\ + uint32_t da_fit_c = da_bit_ceil((uint32_t)(n));\ + (da)->v = resize(a, (da)->v, (da)->c_, da_fit_c);\ + (da)->c_ = da_fit_c;\ + }\ +} while(0) +#define DA_AGROW(da, a, n_) DA_AFIT(da, a, (da)->n + (n_)) +#define DA_APUSH(da, a, ...) do {\ + DA_AGROW(da, a, 1);\ + (da)->v[(da)->n++] = (__VA_ARGS__);\ +} while(0) +#define DA_APUSH_MULT(da, a, o, n_) do {\ + DA_AGROW(da, a, n_);\ + memcpy((da)->v + (da)->n, (o), DA_ELEM(da, n_));\ + (da)->n += (n_);\ +} while(0) + +#endif |
