#ifndef VEC_TYPE #error "Need vector type" #endif #ifndef VEC_NAME #error "Need vector name" #endif #include #include #include #include #include "conts.h" #define VEC(a) CONTS_JOIN(VEC_NAME, a) #define VEC_STRUCT VEC_NAME struct VEC_STRUCT { size_t n; size_t s; VEC_TYPE *buf; }; static inline struct VEC_STRUCT VEC(create)(size_t reserve) { if (reserve == 0) return (struct VEC_STRUCT) {.n = 0, .s = 0, .buf = NULL}; return (struct VEC_STRUCT) { .n = 0, .s = reserve, .buf = malloc(reserve * sizeof(VEC_TYPE)), }; } static inline bool VEC(uninit)(struct VEC_STRUCT *v) { return v->buf == NULL; } static inline size_t VEC(len)(struct VEC_STRUCT *v) { return v->n; } static inline VEC_TYPE *VEC(at)(struct VEC_STRUCT *v, size_t i) { assert(i < v->n && "out of vector bounds"); return &v->buf[i]; } static inline VEC_TYPE *VEC(back)(struct VEC_STRUCT *v) { assert(v->n); return &v->buf[v->n - 1]; } static inline VEC_TYPE *VEC(pop)(struct VEC_STRUCT *v) { assert(v->n && "attempting to pop empty vector"); v->n--; return &v->buf[v->n]; } static inline void VEC(append)(struct VEC_STRUCT *v, VEC_TYPE n) { v->n++; if (v->n >= v->s) { v->s = v->s == 0 ? 1 : 2 * v->s; v->buf = realloc(v->buf, v->s * sizeof(VEC_TYPE)); } v->buf[v->n - 1] = n; } static inline void VEC(reset)(struct VEC_STRUCT *v) { v->n = 0; } static inline void VEC(destroy)(struct VEC_STRUCT *v) { free(v->buf); } typedef int (*VEC(comp_t))(VEC_TYPE *a, VEC_TYPE *b); static inline void VEC(sort)(struct VEC_STRUCT *v, VEC(comp_t) comp) { qsort(v->buf, v->n, sizeof(VEC_TYPE), (__compar_fn_t)comp); } static inline void VEC(reserve)(struct VEC_STRUCT *v, size_t n) { if (v->n >= n) return; v->n = n; if (v->s >= v->n) return; while (v->s < v->n) v->s = v->s == 0 ? 1 : 2 * v->s; v->buf = realloc(v->buf, v->s * sizeof(VEC_TYPE)); } static inline void VEC(shrink)(struct VEC_STRUCT *v, size_t n) { assert(v->n >= n); v->n = n; } static inline void VEC(remove)(struct VEC_STRUCT *v, size_t i) { assert(v->n > i); size_t c = sizeof(VEC_TYPE) * (v->n - i); memcpy(&v->buf[i], &v->buf[i + 1], c); v->n--; } static inline VEC_TYPE *VEC(begin)(struct VEC_STRUCT *v) { return &v->buf[0]; } static inline bool VEC(end)(struct VEC_STRUCT *v, VEC_TYPE *i) { return &v->buf[v->n] == i; } static inline VEC_TYPE *VEC(next)(VEC_TYPE *i) { return i + 1; } #undef VEC #undef VEC_TYPE #undef VEC_NAME #undef VEC_STRUCT