shithub: asif

Download patch

ref: 765f64dff7a9c6adef091a8d686be2cf09ad15cb
parent: 87053f0fe08729886e284c4e651c67d575182688
author: qwx <qwx@sciops.net>
date: Wed Jun 21 02:31:17 EDT 2023

add dynar: generic dynamic arrays using macros

combining ideas from klib and stb; having extra memory for a header
prepended to the vector is a good idea used elsewhere (pool, zalloc
here, etc.) which together with sizeof simplifies a lot the api, which
is in turn the biggest problem with klib's kvec.  not psyched about
using macros, but that's the way the cookie crumbles.

--- /dev/null
+++ b/dynar.h
@@ -1,0 +1,21 @@
+/* ideas from klib and stb */
+typedef struct Dyhdr Dyhdr;
+struct Dyhdr{
+	void *buf;
+	usize len;
+	usize sz;
+};
+
+#define dyhdr(a)	((Dyhdr*)(a) - 1)
+#define dyfree(a)	(free(dyhdr(a)))
+#define dylen(a)	((a) == nil ? 0 : dyhdr(a)->len)
+#define dysetsz(a,h,n)	((a) = (void*)((h)+1), h->sz = (n), (a))
+#define dynew(a,h)	((h) = emalloc(4 * sizeof(*(a)) + sizeof(Dyhdr)), dysetsz((a), (h), 4))
+#define dyextend(a,h,n)	((h) = erealloc((h), \
+	2*n + sizeof(Dyhdr), n + sizeof(Dyhdr)), \
+	dysetsz((a), (h), n / sizeof(*(a)) * 2))
+#define dychecksz(a,h)	((a) == nil ? dynew((a),(h)) : \
+	(h)->sz == (h)->len ? dyextend((a), (h), sizeof(*(a)) * h->sz) : \
+	(a))
+#define dypush(a,v)	{Dyhdr*__h = dyhdr(a); (a) = dychecksz(a,__h); (a)[dyhdr(a)->len++] = v;}
+#define dypop(a)	(assert((a) != nil && dyhdr(a)->len > 0), (a)[--dyhdr(a)->len])