#ifndef LIBGE_GEVECTOR_H #define LIBGE_GEVECTOR_H #include #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 == 0 ? 16 : 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++; \ return 0; \ } \ \ 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 */