From 4f62899af7e97501ec081f9268d80ebf87150c2a Mon Sep 17 00:00:00 2001
From: Thomas Voss <mail@thomasvoss.com>
Date: Fri, 10 May 2024 23:27:08 +0200
Subject: Begin work on custom allocators in dynarr.h

---
 include/dynarr.h    | 15 ++++++++++++++-
 lib/dynarr/dapush.c | 22 ++++++++++++++++++++++
 2 files changed, 36 insertions(+), 1 deletion(-)
 create mode 100644 lib/dynarr/dapush.c

diff --git a/include/dynarr.h b/include/dynarr.h
index 7edb035..52cacc5 100644
--- a/include/dynarr.h
+++ b/include/dynarr.h
@@ -3,9 +3,22 @@
 
 #include <string.h>
 
+#include "_alloc_fn.h"
 #include "alloc.h"
 
-#define dynarr(T) struct { T *buf; size_t len, cap; }
+#define dynarr(T)                                                              \
+	struct {                                                                   \
+		T *buf;                                                                \
+		size_t len, cap;                                                       \
+		alloc_fn alloc;                                                        \
+		void *ctx;                                                             \
+	}
+
+void *dapush(void *, void *, size_t, size_t);
+
+#define dapush(da, ...)                                                        \
+	dapush((da), ((typeof(__VA_ARGS__)[1]){__VA_ARGS__}), sizeof(__VA_ARGS__), \
+	       alignof(__VA_ARGS__))
 
 #define DAGROW(da, n)                                                          \
 	do {                                                                       \
diff --git a/lib/dynarr/dapush.c b/lib/dynarr/dapush.c
new file mode 100644
index 0000000..11fde1b
--- /dev/null
+++ b/lib/dynarr/dapush.c
@@ -0,0 +1,22 @@
+#include <errno.h>
+#include <stdbit.h>
+#include <stdint.h>
+#include <string.h>
+
+#include "dynarr.h"
+
+void *
+(dapush)(void *da, void *x, size_t sz, size_t align)
+{
+	dynarr(uint8_t) cpy;
+	memcpy(&cpy, da, sizeof(cpy));
+
+	if (++cpy.len > cpy.cap) {
+		size_t ncap = stdc_bit_ceil(cpy.len);
+		cpy.buf = cpy.alloc(cpy.ctx, cpy.buf, cpy.cap, ncap, sz, align);
+		cpy.cap = ncap;
+	}
+
+	memcpy(cpy.buf + cpy.len * sz - sz, x, sz);
+	return memcpy(da, &cpy, sizeof(cpy));
+}
-- 
cgit v1.2.3