#ifndef NGC_VEC_H #define NGC_VEC_H #include #include #include #include typedef vec[any type]() { struct <> { size_t n; size_t s; type *buf; }; typedef type *<>_iter; struct <> <>_create(size_t reserve) { if (reserve == 0) return (struct <>){.n = 0, .s = 0, .buf = NULL}; return (struct <>){ .n = 0, .s = reserve, .buf = malloc(reserve * sizeof(type)) }; } bool <>_uninit(struct <> *v) { return v->buf == NULL; } size_t <>_len(struct <> *v) { return v->n; } type *<>_at(struct <> *v, size_t i) { assert(i < v->n && "out of vector bounds"); return &v->buf[i]; } type *<>_pop(struct <> *v) { assert(v->n && "attempting to pop empty vector"); v->n--; return &v->buf[v->n]; } type* <>_append(struct <> *v, 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(type)); } v->buf[v->n - 1] = n; } void <>_reset(struct <> *v) { v->n = 0; } void <>_destroy(struct <> *v) { free(v->buf); } void <>_reserve(struct <> *v, size_t n) { if (v->n >= n) return; while (v->s < v->n) v->s = v->s == 0 ? 1 : 2 * v->s; v->buf = realloc(v->buf, v->s * sizeof(type)); } void <>_shrink(struct <> *v, size_t n) { assert(v->n >= n); v->n = n; } void <>_remove(struct <> *v, size_t i) { assert(v->n > i); size_t c = sizeof(type) * (v->n - i); memcpy(&v->buf[i], &v->buf[i + 1], c); v->n--; } <>_iter <>_begin(struct <> *v) { return &v->buf[0]; } bool <>_end(struct <> *v, <>_iter i) { return &v->buf[v->n] == i; } <>_iter <>_next(<>_iter i) { return i + 1; } } #endif /* NGC_VEC_H */