summaryrefslogtreecommitdiff
path: root/dynarr.h
diff options
context:
space:
mode:
authorkatalx2026-02-01 17:51:43 -0500
committerkatalx2026-02-01 17:51:43 -0500
commitb2c27d7b23208f3d51927406198edd6a2e897391 (patch)
tree04d079ffc817f8cac9bbc848f9b6204c1f771300 /dynarr.h
parentb295d429bf9c503b90c1cbadb950ce419ee02f57 (diff)
request documents from gopher & junk
Diffstat (limited to 'dynarr.h')
-rw-r--r--dynarr.h59
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