#ifndef DYNARR_H #define DYNARR_H #include #include #include #include "zone.h" typedef struct { Zone *zone; ZoneFrame *zf; size_t count, capacity; } ZDarrHeader; #define ZDYNARR(type) type * #define ZDA_HEADER(da) ((ZDarrHeader*)(da) - 1) #define ZDA_INIT_CAP 16 #define ZDA_INIT_SZ(da, z, cap) do {\ ZoneFrame *zda_zf_ptr;\ char *zda_init_ptr = zn_alloc_zf(z, &zda_zf_ptr, sizeof(ZDarrHeader) + cap * sizeof(*da));\ if (!zda_init_ptr) { fprintf(stderr, "dynamic array allocation failed\n"); abort(); }\ da = (void *)(zda_init_ptr + sizeof(ZDarrHeader));\ *ZDA_HEADER(da) = (ZDarrHeader) { 0, cap };\ } while(0) #define ZDA_INIT(da, z) ZDA_INIT_SZ(da, z, ZDA_INIT_CAP) #define ZDA_LEN(da) (ZDA_HEADER(da)->count) #define ZDA_FIT(da, count) do {\ size_t zda_fit_cap = ZA_HEADER(da)->capacity;\ if (count >= zda_fit_cap) {\ ZoneFrame *zda_zf_ptr = (da)->zf;\ while (count >= zda_fit_cap) zda_fit_cap <<= 1;\ char *zda_fit_ptr = zn_zf_realloc((da)->zone, &zda_zf_ptr, ZDA_HEADER(da),\ sizeof(ZDarrHeader) + ZDA_HEADER(da)->capacity * sizeof(*da),\ sizeof(ZDarrHeader) + zda_fit_cap * sizeof(*da));\ if (!zda_fit_ptr) { fprintf(stderr, "dynamic array reallocation failed\n"); abort(); }\ (da) = (void *)(zda_fit_ptr + sizeof(ZDarrHeader));\ ZDA_HEADER(da)->capacity = zda_fit_cap;\ ZDA_HEADER(da)->zf = zda_zf_ptr;\ }\ } while(0) #define ZDA_PUSH(da, ...) do {\ ZDA_FIT(da, ZDA_LEN(da) + 1);\ (da)[ZDA_HEADER(da)->count++] = (__VA_ARGS__);\ } while(0) #define ZDA_PUSH_MULT(da, buf, n) do {\ ZDA_FIT(da, ZDA_LEN(da) + n);\ memcpy(&(da)[ZDA_HEADER(da)->count], buf, n * sizeof(*(da)));\ ZDA_HEADER(da)->count += n;\ } while(0) #define ZDA_FOR(da, name)\ for (typeof(da) name = (da); name < &(da)[ZDA_LEN(da)]; name++) #define ZDA_FORVAL(da, name)\ for (volatile typeof(*(da)) *stdwrm__zda_iter = (da), name; stdwrm__zda_iter < &(da)[ZDA_LEN(da)] && (name = *stdwrm__zda_iter, 1); stdwrm__zda_iter++) #endif