summaryrefslogtreecommitdiff
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