diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/gevector.h | 96 |
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 */ |