libdvec-c

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

commit d33ebe88ade38ff683fbd0fd74bee13f7962406b
parent cace3248f08c52886568830479cfb5b8338ab72c
Author: Louis Burda <quent.burda@gmail.com>
Date:   Mon, 27 Mar 2023 21:12:47 +0200

Minor API improvements

Diffstat:
MMakefile | 7+++++--
Minclude/dvec.h | 72++++++++++++++++++++++++++++--------------------------------------------
Mlibdvec.lds | 2+-
Msrc/dvec.c | 75+++++++++++++++++++++++++++++++++++++--------------------------------------
Msrc/test.c | 16+++++++++++-----
5 files changed, 82 insertions(+), 90 deletions(-)

diff --git a/Makefile b/Makefile @@ -3,10 +3,13 @@ LIBDIR ?= /lib INCLDIR ?= /include CFLAGS = -I include -I lib/liballoc/include -CFLAGS += -Wno-prototype -Wunused-function -Wunused-variable +CFLAGS += -Wunused-function -Wunused-variable -Wno-prototype +CFLAGS += -Wconversion -Wsign-compare -Werror ifeq "$(DEBUG)" "1" -CFLAGS += -g +CFLAGS += -Og -g +else +CFLAGS += -O2 endif ifeq "$(ASSERT_ARGS)" "1" diff --git a/include/dvec.h b/include/dvec.h @@ -5,7 +5,11 @@ #include <stdbool.h> #include <stddef.h> -#define DVEC_ITER(dvec, p) *p = NULL; dvec_iter_fwd(dvec, (void **)(p)); +#define DVEC_ITER(dvec, p) (p) = NULL; ((p) = dvec_iter_fwd((dvec), (p))); +#define DVEC_ITER_BWD(dvec, p) (p) = NULL; ((p) = dvec_iter_bwd((dvec), (p))); + +#define DVEC_STRERR_INIT \ + [DVEC_OK] = "Success" #ifdef LIBDVEC_ASSERT_ARGS #include "stdlib.h" @@ -21,6 +25,10 @@ #define LIBDVEC_ABORT_ON_ALLOC(cond) #endif +enum { + DVEC_OK = 0, +}; + struct dvec { size_t dsize; size_t len, cap; @@ -50,19 +58,27 @@ 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); -bool dvec_iter_fwd(const struct dvec *dvec, void **p); -bool dvec_iter_bwd(const struct dvec *dvec, void **p); +void *dvec_iter_fwd(const struct dvec *dvec, void *p); +void *dvec_iter_bwd(const struct dvec *dvec, void *p); static inline void * -dvec_at(struct dvec *dvec, size_t index) +dvec_at(const struct dvec *dvec, size_t index) { - LIBDVEC_ABORT_ON_ARGS(!dvec); + LIBDVEC_ABORT_ON_ARGS(!dvec || index >= dvec->len); return dvec->data + index * dvec->dsize; } static inline void * -dvec_front(struct dvec *dvec) +dvec_at_back(const struct dvec *dvec, size_t index) +{ + LIBDVEC_ABORT_ON_ARGS(!dvec || !index || index >= dvec->len); + + return dvec->data + (dvec->len - 1 - index) * dvec->dsize; +} + +static inline void * +dvec_front(const struct dvec *dvec) { LIBDVEC_ABORT_ON_ARGS(!dvec); @@ -70,7 +86,7 @@ dvec_front(struct dvec *dvec) } static inline void * -dvec_back(struct dvec *dvec) +dvec_back(const struct dvec *dvec) { LIBDVEC_ABORT_ON_ARGS(!dvec); @@ -78,7 +94,7 @@ dvec_back(struct dvec *dvec) } static inline bool -dvec_empty(struct dvec *dvec) +dvec_empty(const struct dvec *dvec) { LIBDVEC_ABORT_ON_ARGS(!dvec); @@ -86,47 +102,15 @@ dvec_empty(struct dvec *dvec) } static inline size_t -dvec_len(struct dvec *dvec) +dvec_len(const struct dvec *dvec) { LIBDVEC_ABORT_ON_ARGS(!dvec); return dvec->len; } -static inline void * -dvec_add_slots(struct dvec *dvec, int *_rc, size_t count) +static inline int +dvec_add_back(struct dvec *dvec, size_t count) { - int rc; - - LIBDVEC_ABORT_ON_ARGS(!dvec || !count); - - rc = dvec_add(dvec, dvec->len, count); - if (_rc) *_rc = rc; - if (rc) return NULL; - - return dvec->data + (dvec->len - count) * dvec->dsize; -} - -static inline void * -dvec_add_slot(struct dvec *dvec, int *rc) -{ - LIBDVEC_ABORT_ON_ARGS(!dvec); - - return dvec_add_slots(dvec, rc, 1); -} - -static inline void -dvec_rm_slots(struct dvec *dvec, void *slot, size_t count) -{ - LIBDVEC_ABORT_ON_ARGS(!dvec || slot < dvec->data || !count); - - dvec_remove(dvec, ((size_t) (slot - dvec->data)) / dvec->dsize, count); -} - -static inline void -dvec_rm_slot(struct dvec *dvec, void *slot) -{ - LIBDVEC_ABORT_ON_ARGS(!dvec || !slot); - - dvec_rm_slots(dvec, slot, 1); + return dvec_add(dvec, dvec->len, count); } diff --git a/libdvec.lds b/libdvec.lds @@ -1,4 +1,4 @@ -LIBDVEC_1.1 { +LIBDVEC_1.1.1 { global: dvec_init; dvec_deinit; diff --git a/src/dvec.c b/src/dvec.c @@ -46,6 +46,7 @@ dvec_deinit(struct dvec *dvec) rc = dvec->allocator->free(dvec->data); LIBDVEC_ABORT_ON_ALLOC(rc); + return -rc; } @@ -59,7 +60,7 @@ dvec_alloc(struct dvec **dvec, size_t dsize, size_t cap, rc = allocator->alloc((void **)dvec, sizeof(struct dvec)); LIBDVEC_ABORT_ON_ALLOC(rc); - if (!*dvec) return -rc; + if (rc) return -rc; rc = dvec_init(*dvec, dsize, cap, allocator); if (rc) return rc; @@ -155,15 +156,13 @@ dvec_shrink(struct dvec *dvec) rc = dvec->allocator->free(dvec->data); LIBDVEC_ABORT_ON_ALLOC(rc); if (rc) return -rc; - return 0; + } else { + dvec->cap = dvec->len; + rc = dvec->allocator->realloc(&dvec->data, dvec->cap * dvec->dsize); + LIBDVEC_ABORT_ON_ALLOC(rc); + if (rc) return -rc; } - dvec->cap = dvec->len; - - rc = dvec->allocator->realloc(&dvec->data, dvec->cap * dvec->dsize); - LIBDVEC_ABORT_ON_ALLOC(rc); - if (rc) return -rc; - return 0; } @@ -210,42 +209,42 @@ dvec_replace(struct dvec *dvec, size_t index, const void *data, size_t count) memcpy(dvec->data + index * dvec->dsize, data, count * dvec->dsize); } -bool -dvec_iter_fwd(const struct dvec *dvec, void **p) +void * +dvec_iter_fwd(const struct dvec *dvec, void *p) { - void **iter; - - LIBDVEC_ABORT_ON_ARGS(!dvec || !p); - - if (!dvec->len) return false; - - iter = p; - if (*iter == NULL) { - *iter = dvec->data; + LIBDVEC_ABORT_ON_ARGS(!dvec); + LIBDVEC_ABORT_ON_ARGS(p && (p < dvec->data)); + LIBDVEC_ABORT_ON_ARGS(p && (p >= dvec->data + dvec->len * dvec->dsize)); + LIBDVEC_ABORT_ON_ARGS(p && ((size_t) (p - dvec->data) % dvec->dsize)); + + if (p == NULL) { + if (dvec->len > 0) + return dvec->data; + else + return NULL; + } else if (p < dvec->data + dvec->dsize * (dvec->len - 1)) { + return p + dvec->dsize; } else { - *iter += dvec->dsize; + return NULL; } - - return *iter < dvec->data + dvec->dsize * dvec->len; } -bool -dvec_iter_bwd(const struct dvec *dvec, void **p) +void * +dvec_iter_bwd(const struct dvec *dvec, void *p) { - void **iter; - - LIBDVEC_ABORT_ON_ARGS(!dvec || !p); - - if (!dvec->len) return false; - - iter = p; - if (*iter == NULL) { - *iter = dvec->data + (dvec->len - 1) * dvec->dsize; - } else if (*iter > dvec->data) { - *iter -= dvec->dsize; + LIBDVEC_ABORT_ON_ARGS(!dvec); + LIBDVEC_ABORT_ON_ARGS(p && (p < dvec->data)); + LIBDVEC_ABORT_ON_ARGS(p && (p >= dvec->data + dvec->len * dvec->dsize)); + LIBDVEC_ABORT_ON_ARGS(p && ((size_t) (p - dvec->data) % dvec->dsize)); + + if (p == NULL) { + if (dvec->len > 0) + return dvec->data + (dvec->len - 1) * dvec->dsize; + else + return NULL; + } else if (p > dvec->data) { + return p - dvec->dsize; } else { - return false; + return NULL; } - - return true; } diff --git a/src/test.c b/src/test.c @@ -6,7 +6,12 @@ #include <string.h> #include <stdlib.h> -#define LIBDVEC_ERR(rc) errx(1, "libdvec: %s", rc < 0 ? strerror(-rc) : "???") +#define LIBDVEC_ERR(rc) errx(1, "libdvec: %s", \ + rc < 0 ? strerror(-rc) : dvec_err[rc]) + +static const char *dvec_err[] = { + DVEC_STRERR_INIT +}; int main(int argc, const char **argv) @@ -15,17 +20,18 @@ main(int argc, const char **argv) int i, rc; int *val; - rc = dvec_init(&dvec, sizeof(int), 10, &stdlib_heap_allocator); + rc = dvec_init(&dvec, sizeof(int), 16, &stdlib_heap_allocator); if (rc) LIBDVEC_ERR(rc); for (i = 1; i < argc; i++) { - val = dvec_add_slot(&dvec, &rc); + rc = dvec_add_back(&dvec, 1); if (rc) LIBDVEC_ERR(rc); + val = dvec_back(&dvec); *val = atoi(argv[i]); } - for (i = 0; i < dvec.len; i++) - printf("%i\n", *(int *)dvec_at(&dvec, i)); + for (DVEC_ITER(&dvec, val)) + printf("%i\n", *val); printf("dvec len: %lu\n", dvec.len);