#ifndef LIBGE_GEVECTOR_H #define LIBGE_GEVECTOR_H #include #include #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 { \ t *data; \ size_t cap, len; \ double __gfac; \ } n_t; \ \ int n##_new(n_t *, size_t, double); \ int n##_insert(n_t *, t, size_t); \ int n##_push(n_t *, t); \ t n##_pop(n_t *); \ void n##_remove(n_t *, size_t); \ int n##_resize(n_t *, size_t); \ void n##_free(n_t *); #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(n_t *vec, size_t cap, double gfac) \ { \ *vec = (n_t) { \ .len = 0, \ .cap = cap == 0 ? 16 : cap, \ .__gfac = gfac == 0 ? 1.5f : gfac, \ }; \ vec->data = malloc(vec->cap * sizeof(t)); \ return vec->data == NULL ? -1 : 0; \ } \ \ int \ n##_insert(n_t *vec, t elem, size_t i) \ { \ 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->len; j > i; j--) \ vec->data[j] = vec->data[j - 1]; \ vec->data[i] = elem; \ vec->len++; \ return 0; \ } \ \ int \ n##_push(n_t *vec, t elem) \ { \ return n##_insert(vec, elem, vec->len); \ } \ \ t \ n##_pop(n_t *vec) \ { \ return vec->data[--vec->len]; \ } \ \ void \ n##_remove(n_t *vec, size_t i) \ { \ for (size_t j = i; j < vec->len - 1; j++) \ vec->data[j] = vec->data[j + 1]; \ vec->len--; \ } \ \ int \ n##_resize(n_t *vec, size_t ncap) \ { \ vec->data = realloc(vec->data, sizeof(t) * ncap); \ if (vec->data == NULL) \ return -1; \ vec->cap = ncap; \ return 0; \ } \ \ void \ n##_free(n_t *vec) \ { \ free(vec->data); \ } #endif /* !LIBGE_GEVECTOR_H */