libdvec-c

C memory vector library
git clone https://git.sinitax.com/sinitax/libdvec-c
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

commit 7c1d102fb7559da3aa34e0457e68148e8f8bb8af
parent f7cdc492f86eee1740d7c40c00e31c9dafd51ff6
Author: Louis Burda <quent.burda@gmail.com>
Date:   Sat, 12 Mar 2022 15:30:47 +0100

Add methods for adding / removing mulitple items at a time

Diffstat:
Minclude/vec.h | 5++++-
Msrc/vec.c | 80+++++++++++++++++++++++++++++++++++++++++++++++++------------------------------
2 files changed, 54 insertions(+), 31 deletions(-)

diff --git a/include/vec.h b/include/vec.h @@ -9,14 +9,17 @@ void vec_free(struct vec *vec); void vec_clear(struct vec *vec); void vec_resize(struct vec *vec, size_t cap); +void vec_add(struct vec *vec, const void *data, size_t count); +void vec_rm(struct vec *vec, size_t count); + void vec_push(struct vec *vec, const void *data); void *vec_pop(struct vec *vec); +void vec_pop_at(struct vec *vec, size_t index); void *vec_at(struct vec *vec, size_t index); bool vec_iter(struct vec *vec, void *p); void vec_set(struct vec *vec, size_t index, const void *data); -void vec_rm(struct vec *vec, size_t index); int vec_empty(struct vec *vec); int vec_len(struct vec *vec); diff --git a/src/vec.c b/src/vec.c @@ -6,6 +6,8 @@ #include <stdarg.h> #include <string.h> +#define OFFSETOF(type, member) ((size_t) &((type *)0)->member) + #define ASSERT(x) assert((x), __FILE__, __LINE__, #x) #define OOM_CHECK(x) assert((x) != NULL, __FILE__, __LINE__, "Out of Memory") @@ -18,7 +20,7 @@ struct vec { static void assert(int cond, const char *file, int line, const char *condstr); -static const size_t vec_data_offset = sizeof(size_t) * 3; +static const size_t vec_data_offset = OFFSETOF(struct vec, data); void assert(int cond, const char *file, int line, const char *condstr) @@ -73,17 +75,40 @@ vec_resize(struct vec *vec, size_t cap) } void -vec_push(struct vec *vec, const void *data) +vec_add(struct vec *vec, const void *data, size_t count) { ASSERT(vec != NULL && data != NULL); - if (vec->count == vec->cap) { + if (vec->count + count > vec->cap) { vec->cap *= 2; + if (vec->count + count > vec->cap) + vec->cap = vec->count + count; vec = realloc(vec, vec_data_offset + vec->cap * vec->dsize); OOM_CHECK(vec); } - vec->count++; - vec_set(vec, vec->count - 1, data); + + memcpy(vec->data + vec->count * vec->dsize, + data, vec->count * vec->dsize); + vec->count += count; +} + +void +vec_rm(struct vec *vec, size_t count) +{ + ASSERT(vec != NULL); + + vec->count -= count; + if (vec->count < vec->cap / 2) { + vec->cap /= 2; + vec = realloc(vec, vec_data_offset + vec->cap * vec->dsize); + OOM_CHECK(vec); + } +} + +void +vec_push(struct vec *vec, const void *data) +{ + vec_add(vec, data, 1); } void * @@ -91,14 +116,31 @@ vec_pop(struct vec *vec) { ASSERT(vec != NULL); + vec_rm(vec, 1); + + return vec->data + vec->dsize * vec->count; +} + +void +vec_pop_at(struct vec *vec, size_t index) +{ + void *start, *end; + + ASSERT(vec != NULL && index < vec->count); + + start = vec->data + index * vec->dsize; + end = vec->data + vec->count * vec->dsize; + if (start + vec->dsize < end) { + memcpy(start, start + vec->dsize, end - start - vec->dsize); + } + vec->count--; - if (vec->count + 1 < vec->cap / 2) { + + if (vec->count < vec->cap / 2) { vec->cap /= 2; vec = realloc(vec, vec_data_offset + vec->cap * vec->dsize); OOM_CHECK(vec); } - - return vec->data + vec->dsize * vec->count; } void * @@ -134,28 +176,6 @@ vec_set(struct vec *vec, size_t index, const void *data) memcpy(vec->data + index * vec->dsize, data, vec->dsize); } -void -vec_rm(struct vec *vec, size_t index) -{ - void *start, *end; - - ASSERT(vec != NULL && index < vec->count); - - start = vec->data + index * vec->dsize; - end = vec->data + vec->count * vec->dsize; - if (start + vec->dsize < end) { - memcpy(start, start + vec->dsize, end - start - vec->dsize); - } - - vec->count--; - - if (vec->count < vec->cap / 4) { - vec->cap /= 2; - vec = realloc(vec, vec_data_offset + vec->cap * vec->dsize); - OOM_CHECK(vec); - } -} - int vec_empty(struct vec *vec) {