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