import "common.hff"; import "mem.hff"; import "util.hff"; struct Vec { dat *T, len uint, cap uint, fn push(vec *Vec, x T) void { if vec.len >= vec.cap { vec.cap = (vec.len + 1) > 8 ? (vec.len + 1) * 2 : 8; if vec.dat == #null { vec.dat = xmalloc(vec.cap * sizeof T); } else { vec.dat = xrealloc(vec.dat, vec.cap * sizeof T); } } vec.dat[vec.len++] = x; } fn pop(vec *Vec) T { return vec.dat[--vec.len]; } fn clear(vec *Vec) void { free(vec.dat); *vec = {}; } fn compact(vec *Vec) [#]T { if vec.dat { vec.cap = vec.len; vec.dat = xrealloc(vec.dat, vec.cap * sizeof T); } return vec.dat[0::vec.len]; } fn move(vec *Vec, alloc *Allocator) [#]T { let len = vec.len; let dat *T = alloc->alloc(len * sizeof T, alignof T); memcpy(dat, vec.dat, len * sizeof T); vec->clear(); return dat[0::len]; } fn last(vec *const Vec) T { return vec.dat[vec.len - 1]; } fn lastp(vec *Vec) *T { return &vec.dat[vec.len - 1]; } } defmacro vec_each(x, i, v, &body) [ { let $v = v; for let i = 0u; i < $v.len; ++i { let x = $v.dat[i]; { body } } } ]