libdvec-c

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

commit d5facb4fb6bace7e23ce97831adcecdd19aa0ad6
parent 81bbc02a07bf28a8c08a4977931953b5c05ab8d7
Author: Louis Burda <quent.burda@gmail.com>
Date:   Fri, 17 Mar 2023 16:57:09 +0100

Add copy and swap

Diffstat:
Minclude/dvec.h | 33++++++++++++++++-----------------
Mlibdvec.api | 7+++++--
Mlibdvec.lds | 9++++++---
Msrc/dvec.c | 51++++++++++++++++++++++++++++++++++-----------------
Msrc/test.c | 2+-
5 files changed, 62 insertions(+), 40 deletions(-)

diff --git a/include/dvec.h b/include/dvec.h @@ -16,11 +16,14 @@ void dvec_deinit(struct dvec *dvec); int dvec_alloc(struct dvec **dvec, size_t dsize, size_t cap); void dvec_free(struct dvec *dvec); +int dvec_copy(struct dvec *dst, struct dvec *src); +void dvec_swap(struct dvec *dst, struct dvec *src); + void dvec_clear(struct dvec *dvec); -int dvec_resize(struct dvec *dvec, size_t cap); +int dvec_reserve(struct dvec *dvec, size_t cap); int dvec_shrink(struct dvec *dvec); -int dvec_reserve(struct dvec *dvec, size_t index, size_t count); +int dvec_add(struct dvec *dvec, size_t index, size_t count); void dvec_remove(struct dvec *dvec, size_t index, size_t count); void dvec_replace(struct dvec *dvec, size_t index, const void *data, size_t count); @@ -51,33 +54,29 @@ dvec_empty(struct dvec *dvec) return !dvec->len; } -static inline int -dvec_alloc_slots(struct dvec *dvec, void **out, size_t count) +static inline void * +dvec_add_slots(struct dvec *dvec, int *rc, size_t count) { - int ret; - - ret = dvec_reserve(dvec, dvec->len, count); - if (ret) return ret; + *rc = dvec_add(dvec, dvec->len, count); + if (*rc) return NULL; - *out = dvec->data + (dvec->len - count) * dvec->dsize; - - return 0; + return dvec->data + (dvec->len - count) * dvec->dsize; } -static inline int -dvec_alloc_slot(struct dvec *dvec, void **out) +static inline void * +dvec_add_slot(struct dvec *dvec, int *rc) { - return dvec_alloc_slots(dvec, out, 1); + return dvec_add_slots(dvec, rc, 1); } static inline void -dvec_free_slots(struct dvec *dvec, void *slot, size_t count) +dvec_rm_slots(struct dvec *dvec, void *slot, size_t count) { dvec_remove(dvec, (slot - dvec->data) / dvec->dsize, count); } static inline void -dvec_free_slot(struct dvec *dvec, void *slot) +dvec_rm_slot(struct dvec *dvec, void *slot) { - dvec_free_slots(dvec, slot, 1); + dvec_rm_slots(dvec, slot, 1); } diff --git a/libdvec.api b/libdvec.api @@ -4,11 +4,14 @@ dvec_deinit dvec_alloc dvec_free +dvec_copy +dvec_swap + dvec_clear -dvec_resize +dvec_reserve dvec_shrink -dvec_reserve +dvec_add dvec_remove dvec_replace diff --git a/libdvec.lds b/libdvec.lds @@ -1,4 +1,4 @@ -LIBDVEC_1.0 { +LIBDVEC_1.1 { global: dvec_init; dvec_deinit; @@ -6,11 +6,14 @@ LIBDVEC_1.0 { dvec_alloc; dvec_free; + dvec_copy; + dvec_swap; + dvec_clear; - dvec_resize; + dvec_reserve; dvec_shrink; - dvec_reserve; + dvec_add; dvec_remove; dvec_replace; diff --git a/src/dvec.c b/src/dvec.c @@ -77,6 +77,30 @@ dvec_free(struct dvec *dvec) free(dvec); } +int +dvec_copy(struct dvec *dst, struct dvec *src) +{ + int rc; + + rc = dvec_reserve(dst, src->len); + if (rc) return rc; + + dst->dsize = src->dsize; + dst->len = src->len; + memcpy(dst->data, src->data, src->len * src->dsize); + + return 0; +} + +void +dvec_swap(struct dvec *dst, struct dvec *src) +{ + struct dvec tmp; + + memcpy(&tmp, dst, sizeof(struct dvec)); + memcpy(dst, src, sizeof(struct dvec)); + memcpy(src, &tmp, sizeof(struct dvec)); +} void dvec_clear(struct dvec *dvec) @@ -87,13 +111,14 @@ dvec_clear(struct dvec *dvec) } int -dvec_resize(struct dvec *dvec, size_t cap) +dvec_reserve(struct dvec *dvec, size_t len) { void *alloc; - LIBDVEC_CHECK(dvec != NULL && cap != 0 && dvec->len <= cap); + if (len <= dvec->cap) return 0; - dvec->cap = cap; + dvec->cap *= 2; + if (len > dvec->cap) dvec->cap = len; alloc = realloc(dvec->data, dvec->cap * dvec->dsize); if (!alloc) return -errno; dvec->data = alloc; @@ -109,11 +134,12 @@ dvec_shrink(struct dvec *dvec) LIBDVEC_CHECK(dvec != NULL); if (!dvec->len) { - dvec->cap = 1; - } else { - dvec->cap = dvec->len; + dvec->cap = 0; + free(dvec->data); + return 0; } + dvec->cap = dvec->len; alloc = realloc(dvec->data, dvec->cap * dvec->dsize); if (!alloc) return -errno; dvec->data = alloc; @@ -122,20 +148,11 @@ dvec_shrink(struct dvec *dvec) } int -dvec_reserve(struct dvec *dvec, size_t index, size_t len) +dvec_add(struct dvec *dvec, size_t index, size_t len) { - void *alloc; - LIBDVEC_CHECK(dvec != NULL && index <= dvec->len); - if (dvec->len + len > dvec->cap) { - dvec->cap *= 2; - if (dvec->len + len > dvec->cap) - dvec->cap = dvec->len + len; - alloc = realloc(dvec->data, dvec->cap * dvec->dsize); - if (!alloc) return -errno; - dvec->data = alloc; - } + dvec_reserve(dvec, dvec->len + len); if (index < dvec->len) { memmove(dvec->data + (index + len) * dvec->dsize, diff --git a/src/test.c b/src/test.c @@ -18,7 +18,7 @@ main(int argc, const char **argv) if (rc) LIBDVEC_ERR(rc); for (i = 1; i < argc; i++) { - rc = dvec_alloc_slot(&dvec, (void **)&val); + val = dvec_add_slot(&dvec, &rc); if (rc) LIBDVEC_ERR(rc); *val = atoi(argv[i]); }