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:
M | include/vec.h | | | 5 | ++++- |
M | src/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)
{