18455734fSStefan Bühler #ifndef LI_VECTOR_H 28455734fSStefan Bühler #define LI_VECTOR_H 38455734fSStefan Bühler #include "first.h" 48455734fSStefan Bühler 55e14db43SGlenn Strauss #include "ck.h" /* ck_assert() ck_calloc() */ 68455734fSStefan Bühler 704d76e7aSGlenn Strauss void vector_free(void *data); 819bc8885SGlenn Strauss 9dde9df43SGlenn Strauss __attribute_returns_nonnull__ 10*5fe8322eSGlenn Strauss void *vector_resize(void *data, size_t elem_size, size_t *size, size_t used, size_t x); 118455734fSStefan Bühler 128455734fSStefan Bühler #define DEFINE_TYPED_VECTOR(name, entry, release) \ 138455734fSStefan Bühler typedef struct vector_ ## name { \ 148455734fSStefan Bühler entry* data; \ 158455734fSStefan Bühler size_t used; \ 168455734fSStefan Bühler size_t size; \ 178455734fSStefan Bühler } vector_ ## name; \ 188455734fSStefan Bühler static inline void vector_ ## name ## _init(vector_ ## name *v) { \ 198455734fSStefan Bühler v->data = NULL; \ 208455734fSStefan Bühler v->used = v->size = 0; \ 218455734fSStefan Bühler } \ 2220a68d73SGlenn Strauss __attribute_malloc__ \ 2320a68d73SGlenn Strauss __attribute_returns_nonnull__ \ 248455734fSStefan Bühler static inline vector_ ## name *vector_ ## name ## _alloc() { \ 255e14db43SGlenn Strauss return ck_calloc(1, sizeof(*v)); \ 268455734fSStefan Bühler } \ 278455734fSStefan Bühler static inline void vector_ ## name ## _clear(vector_ ## name *v) { \ 2820a68d73SGlenn Strauss if (release) for (size_t i = 0; i < v->used; ++i) release(v->data[i]); \ 2920a68d73SGlenn Strauss vector_free(v->data); \ 308455734fSStefan Bühler vector_ ## name ## _init(v); \ 318455734fSStefan Bühler } \ 328455734fSStefan Bühler static inline void vector_ ## name ## _free(vector_ ## name *v) { \ 338455734fSStefan Bühler if (NULL != v) { \ 348455734fSStefan Bühler vector_ ## name ## _clear(v); \ 3504d76e7aSGlenn Strauss vector_free(v); \ 368455734fSStefan Bühler } \ 378455734fSStefan Bühler } \ 388455734fSStefan Bühler static inline void vector_ ## name ## _reserve(vector_ ## name *v, size_t p) { \ 39*5fe8322eSGlenn Strauss if (v->size - v->used < p) \ 40*5fe8322eSGlenn Strauss v->data = vector_resize(v->data, sizeof(entry), &v->size, v->used, p); \ 418455734fSStefan Bühler } \ 428455734fSStefan Bühler static inline void vector_ ## name ## _push(vector_ ## name *v, entry e) { \ 438455734fSStefan Bühler vector_ ## name ## _reserve(v, 1); \ 448455734fSStefan Bühler v->data[v->used++] = e; \ 458455734fSStefan Bühler } \ 468455734fSStefan Bühler static inline entry vector_ ## name ## _pop(vector_ ## name *v) { \ 4769920910SGlenn Strauss ck_assert(v->used > 0); \ 488455734fSStefan Bühler return v->data[--v->used]; \ 498455734fSStefan Bühler } \ 508455734fSStefan Bühler struct vector_ ## name /* expect trailing semicolon */ \ 518455734fSStefan Bühler /* end of DEFINE_TYPED_VECTOR */ 528455734fSStefan Bühler 538455734fSStefan Bühler #define DEFINE_TYPED_VECTOR_NO_RELEASE(name, entry) \ 548455734fSStefan Bühler DEFINE_TYPED_VECTOR(name, entry, ((void(*)(entry)) NULL)) \ 558455734fSStefan Bühler /* end of DEFINE_TYPED_VECTOR_NO_RELEASE */ 568455734fSStefan Bühler 578455734fSStefan Bühler 588455734fSStefan Bühler #endif 59