summaryrefslogtreecommitdiff
path: root/src/gevector.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/gevector.h')
-rw-r--r--src/gevector.h63
1 files changed, 63 insertions, 0 deletions
diff --git a/src/gevector.h b/src/gevector.h
new file mode 100644
index 0000000..cf0b6f9
--- /dev/null
+++ b/src/gevector.h
@@ -0,0 +1,63 @@
+#ifndef LIBGE_GEVECTOR_H
+#define LIBGE_GEVECTOR_H
+
+#include <stdlib.h>
+
+#define GEVECTOR_API(t, n) \
+ struct n { \
+ double gfactor; \
+ size_t capacity; \
+ size_t size; \
+ t *items; \
+ }; \
+ \
+ int n##_new(struct n *, size_t, double); \
+ int n##_append(struct n *, t); \
+ int n##_insert(struct n *, t, size_t); \
+ int n##_resize(struct n *, size_t);
+
+#define GEVECTOR_IMPL(t, n) \
+ int \
+ n##_new(struct n *vec, size_t capacity, double gfactor) \
+ { \
+ *vec = (struct n) { \
+ .gfactor = gfactor == 0 ? 1.5f : gfactor, \
+ .capacity = capacity, \
+ .size = 0, \
+ .items = calloc(capacity == 0 ? 16 : capacity, \
+ sizeof(t)) \
+ }; \
+ return vec->items == NULL ? -1 : 0; \
+ } \
+ \
+ int \
+ n##_append(struct n *vec, t item) \
+ { \
+ return n##_insert(vec, item, vec->size); \
+ } \
+ \
+ int \
+ n##_insert(struct n *vec, t item, size_t i) \
+ { \
+ if (vec->size == vec->capacity \
+ && n##_resize(vec, (size_t) (vec->capacity \
+ * vec->gfactor)) \
+ == -1) \
+ return -1; \
+ for (size_t j = vec->size; j > i; j--) \
+ vec->items[j] = vec->items[j - 1]; \
+ vec->items[i] = item; \
+ vec->size++; \
+ } \
+ \
+ int \
+ n##_resize(struct n *vec, size_t new_capacity) \
+ { \
+ vec->items = realloc(vec->items, sizeof(t) * new_capacity); \
+ if (vec->items == NULL) \
+ return -1; \
+ vec->capacity = new_capacity; \
+ return 0; \
+ }
+
+#endif /* !LIBGE_GEVECTOR_H */