#ifndef VECTOR_H #define VECTOR_H #include #include "klib/kvec.h" // Wrapper around kvec.h to provide dynamically allocated vectors #define __VECTOR_BASE(name, type) typedef kvec_t(type) name; \ static inline name *name##_new(void) { \ name *array = malloc(sizeof(name)); \ if (array == NULL) return NULL; \ kv_init(*array); \ return array; \ } \ static inline name *name##_new_size(size_t size) { \ name *array = name##_new(); \ kv_resize(type, *array, size); \ return array; \ } \ static inline void name##_push(name *array, type value) { \ kv_push(type, *array, value); \ } \ static inline void name##_extend(name *array, name *other) { \ for (int i = 0; i < other->n; i++) { \ kv_push(type, *array, *(other->a + i)); \ } \ } \ static inline type name##_pop(name *array) { \ return kv_pop(*array); \ } \ static inline void name##_clear(name *array) { \ kv_clear(*array); \ } \ static inline void name##_resize(name *array, size_t size) { \ kv_resize(type, *array, size); \ } \ \ static inline void name##_copy(name *dst, name *src, size_t n) { \ if (dst->m < n) name##_resize(dst, n); \ memcpy(dst->a, src->a, n * sizeof(type)); \ dst->n = n; \ } \ \ static inline name *name##_new_copy(name *vector, size_t n) { \ name *cpy = name##_new_size(n); \ name##_copy(cpy, vector, n); \ return cpy; \ } \ \ #define __VECTOR_DESTROY(name, type) \ static inline void name##_destroy(name *array) { \ if (array == NULL) return; \ kv_destroy(*array); \ free(array); \ } #define __VECTOR_DESTROY_FREE_DATA(name, type, free_func) \ static inline void name##_destroy(name *array) { \ if (array == NULL) return; \ for (int i = 0; i < array->n; i++) { \ free_func(array->a[i]); \ } \ kv_destroy(*array); \ free(array); \ } #define VECTOR_INIT(name, type) \ __VECTOR_BASE(name, type) \ __VECTOR_DESTROY(name, type) #define VECTOR_INIT_FREE_DATA(name, type, free_func) \ __VECTOR_BASE(name, type) \ __VECTOR_DESTROY_FREE_DATA(name, type, free_func) #endif