#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 { \ size_t len; \ double __gfac; \ size_t __cap; \ t *__data; \ } n_t; \ \ int n##_new(n_t *, size_t, double); \ t n##_get(n_t *, size_t); \ 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); \ size_t n##_len(n_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, \ .__gfac = gfac == 0 ? 1.5f : gfac, \ .__cap = cap == 0 ? 16 : cap, \ }; \ vec->__data = malloc(vec->__cap * sizeof(t)); \ return vec->__data == NULL ? -1 : 0; \ } \ \ t \ n##_get(n_t *vec, size_t i) \ { \ return vec->__data[i]; \ } \ \ 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]; \ } \ \ 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; \ } \ \ 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 */