summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--dynarr.h40
1 files changed, 21 insertions, 19 deletions
diff --git a/dynarr.h b/dynarr.h
index c86f146..321325b 100644
--- a/dynarr.h
+++ b/dynarr.h
@@ -5,38 +5,40 @@
 #include <stdint.h>
 #include <err.h>
 
-#define DYNARR(type) struct {\
-	type *data;\
-	size_t count;\
-	size_t capacity;\
-}\
+typedef struct { size_t count, capacity; } DynArrHeader;
+
+#define DYNARR(type) type *
+#define DA_HEADER(da) ((DynArrHeader*)(da) - 1)
 
 #define DA_INIT_CAP 16
 #define DA_INIT(da) {\
-	(da)->count = 0;\
-	(da)->capacity = DA_INIT_CAP;\
-	(da)->data = malloc((da)->capacity * sizeof((da)->data[0]));\
+	char *da_init_ptr = ((char*)malloc(sizeof(DynArrHeader) + DA_INIT_CAP * sizeof(*da)));\
+	if (!da_init_ptr) err(1, "dynamic array allocation failed");\
+	da = (void *)(da_init_ptr + sizeof(DynArrHeader));\
+	*DA_HEADER(da) = (DynArrHeader) { 0, DA_INIT_CAP };\
 }
 
+#define DA_FREE(da)\
+	free(DA_HEADER(da))
+
+#define DA_LEN(da) (DA_HEADER(da)->count)
 #define DA_FIT(da, count)\
-	if (count >= (da)->capacity) {\
-		while (count >= (da)->capacity) (da)->capacity <<= 1;\
-		(da)->data = realloc((da)->data, (da)->capacity * sizeof((da)->data[0]));\
-		if (!(da)->data) err(1, "dynamic array reallocation failed");\
+	if (count >= DA_HEADER(da)->capacity) {\
+		while (count >= DA_HEADER(da)->capacity) DA_HEADER(da)->capacity <<= 1;\
+		char *da_fit_ptr = realloc(DA_HEADER(da), sizeof(DynArrHeader) + DA_HEADER(da)->capacity * sizeof(*da));\
+		if (!da_fit_ptr) err(1, "dynamic array reallocation failed");\
+		(da) = (void *)(da_fit_ptr + sizeof(DynArrHeader));\
 	}
 
-#define DA_FREE(da)\
-	free((da)->data)
-
 #define DA_PUSH(da, item) {\
-	DA_FIT(da, (da)->count + 1);\
-	(da)->data[(da)->count++] = item;\
+	DA_FIT(da, DA_LEN(da) + 1);\
+	(da)[DA_HEADER(da)->count++] = item;\
 }
 
 #define DA_FOR(da, type, name)\
-	for (type *name = (da)->data; name < &(da)->data[(da)->count]; name++)
+	for (type *name = (da); name < &(da)[DA_LEN(da)]; name++)
 
 #define DA_FORVAL(da, type, name)\
-	for (type *da_iter = (da)->data, name; da_iter < &(da)->data[(da)->count] && (name = *da_iter); da_iter++)
+	for (volatile type *da_iter = (da), name; da_iter < &(da)[DA_LEN(da)] && (name = *da_iter, 1); da_iter++)
 
 #endif