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:
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]);
}