summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/gevector.h96
1 files 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 */