From 54b10aa8b1951581291ef0bf0fef954860c04191 Mon Sep 17 00:00:00 2001
From: Thomas Voss <mail@thomasvoss.com>
Date: Sat, 31 Dec 2022 01:00:45 +0100
Subject: Add GEVECTOR_DEF, some iter macros, s/append/push

---
 src/gevector.h | 96 +++++++++++++++++++++++++++++++++-------------------------
 1 file changed, 54 insertions(+), 42 deletions(-)

diff --git a/src/gevector.h b/src/gevector.h
index ce47c6a..67f1aed 100644
--- a/src/gevector.h
+++ b/src/gevector.h
@@ -1,76 +1,88 @@
 #ifndef LIBGE_GEVECTOR_H
 #define LIBGE_GEVECTOR_H
 
+#include <stdbool.h>
 #include <stdlib.h>
 
-#define GEVECTOR_API(t, n)                                                      \
-	struct n {                                                              \
-		double gfactor;                                                 \
-		size_t capacity;                                                \
-		size_t length;                                                  \
-		t *items;                                                       \
-	};                                                                      \
+#define GEVECTOR_DEF(t, n)                                                      \
+	GEVECTOR_DEF_API(t, n)                                                  \
+	GEVECTOR_DEF_IMPL(t, n)
+
+#define GEVECTOR_DEF_API(t, n) GEVECTOR_DEF_API_HELPER(t, n, n##_t)
+#define GEVECTOR_DEF_API_HELPER(t, n, n_t)                                      \
+	typedef struct {                                                        \
+		double gfac;                                                    \
+		size_t cap;                                                     \
+		size_t len;                                                     \
+		t *data;                                                        \
+	} n_t;                                                                  \
 	                                                                        \
-	int  n##_new(struct n *, size_t, double);                               \
-	int  n##_append(struct n *, t);                                         \
-	int  n##_insert(struct n *, t, size_t);                                 \
-	void n##_remove(struct n *, size_t);                                    \
-	int  n##_resize(struct n *, size_t);
+	int  n##_new(n_t *, size_t, double);                                    \
+	int  n##_push(n_t *, t);                                                \
+	int  n##_insert(n_t *, t, size_t);                                      \
+	void n##_remove(n_t *, size_t);                                         \
+	int  n##_resize(n_t *, size_t);
 
-#define GEVECTOR_IMPL(t, n)                                                     \
+#define GEVECTOR_DEF_IMPL(t, n) GEVECTOR_DEF_IMPL_HELPER(t, n, n##_t)
+#define GEVECTOR_DEF_IMPL_HELPER(t, n, n_t)                                     \
 	int                                                                     \
-	n##_new(struct n *vec, size_t capacity, double gfactor)                 \
+	n##_new(n_t *vec, size_t cap, double gfac)                              \
 	{                                                                       \
-		*vec = (struct n) {                                             \
-			.gfactor  = gfactor == 0 ? 1.5f : gfactor,              \
-			.capacity = capacity == 0 ? 16 : capacity,              \
-			.length   = 0,                                          \
-			.items    = calloc(capacity == 0 ? 16 : capacity,       \
-			                   sizeof(t))                           \
+		*vec = (n_t) {                                                  \
+			.gfac  = gfac == 0 ? 1.5f : gfac,                       \
+			.cap   = cap == 0 ? 16 : cap,                           \
+			.len   = 0,                                             \
+			.data  = calloc(cap == 0 ? 16 : cap, sizeof(t))         \
 		};                                                              \
-		return vec->items == NULL ? -1 : 0;                             \
+		return vec->data == NULL ? -1 : 0;                              \
 	}                                                                       \
 	                                                                        \
 	int                                                                     \
-	n##_append(struct n *vec, t item)                                       \
+	n##_push(n_t *vec, t elem)                                              \
 	{                                                                       \
-		return n##_insert(vec, item, vec->length);                      \
+		return n##_insert(vec, elem, vec->len);                         \
 	}                                                                       \
 	                                                                        \
 	int                                                                     \
-	n##_insert(struct n *vec, t item, size_t i)                             \
+	n##_insert(n_t *vec, t elem, size_t i)                                  \
 	{                                                                       \
-		if (vec->length == vec->capacity) {                             \
-			size_t new_capacity =                                   \
-				(size_t) (vec->capacity * vec->gfactor);        \
-			if (new_capacity == vec->capacity)                      \
-				new_capacity++;                                 \
-			if (n##_resize(vec, new_capacity) == -1)                \
+		if (vec->len == vec->cap) {                                     \
+			size_t ncap = (size_t) (vec->cap * vec->gfac);          \
+			if (ncap == vec->cap)                                   \
+				ncap++;                                         \
+			if (n##_resize(vec, ncap) == -1)                        \
 				return -1;                                      \
 		}                                                               \
-		for (size_t j = vec->length; j > i; j--)                        \
-			vec->items[j] = vec->items[j - 1];                      \
-		vec->items[i] = item;                                           \
-		vec->length++;                                                  \
+		for (size_t j = vec->len; j > i; j--)                           \
+			vec->data[j] = vec->data[j - 1];                        \
+		vec->data[i] = elem;                                            \
+		vec->len++;                                                     \
 		return 0;                                                       \
 	}                                                                       \
 	                                                                        \
 	void                                                                    \
-	n##_remove(struct n *vec, size_t i)                                     \
+	n##_remove(n_t *vec, size_t i)                                          \
 	{                                                                       \
-		for (size_t j = i; j < vec->length - 1; j++)                    \
-			vec->items[j] = vec->items[j + 1];                      \
-		vec->length--;                                                  \
+		for (size_t j = i; j < vec->len - 1; j++)                       \
+			vec->data[j] = vec->data[j + 1];                        \
+		vec->len--;                                                     \
 	}                                                                       \
 	                                                                        \
 	int                                                                     \
-	n##_resize(struct n *vec, size_t new_capacity)                          \
+	n##_resize(n_t *vec, size_t ncap)                                       \
 	{                                                                       \
-		vec->items = realloc(vec->items, sizeof(t) * new_capacity);     \
-		if (vec->items == NULL)                                         \
+		vec->data = realloc(vec->data, sizeof(t) * ncap);               \
+		if (vec->data == NULL)                                          \
 			return -1;                                              \
-		vec->capacity = new_capacity;                                   \
+		vec->cap = ncap;                                                \
 		return 0;                                                       \
 	}
 
+#define GEVECTOR_ENUMERATE(t, i, e, v)                                          \
+	for (bool __ge_c = true; __ge_c; __ge_c = false)                        \
+		for (t e = (v).data[0]; __ge_c; __ge_c = false)                 \
+			for (size_t i = 0; i < (v).len; e = (v).data[++i])
+
+#define GEVECTOR_FOREACH(t, e, v) GEVECTOR_ENUMERATE(t, __ge_i, e, v)
+
 #endif /* !LIBGE_GEVECTOR_H */
-- 
cgit v1.2.3