summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLouis Burda <quent.burda@gmail.com>2022-03-29 18:11:15 +0200
committerLouis Burda <quent.burda@gmail.com>2022-03-29 18:11:15 +0200
commit7520b04430cfbbb91fa1a3e7bf94995d18655caf (patch)
tree4b5ebf9532b0b24c25b4913b459322060ed90cf0 /src
parent7c1d102fb7559da3aa34e0457e68148e8f8bb8af (diff)
downloadlibdvec-c-7520b04430cfbbb91fa1a3e7bf94995d18655caf.tar.gz
libdvec-c-7520b04430cfbbb91fa1a3e7bf94995d18655caf.zip
Disconnect data buf from struct and make definition public
Diffstat (limited to 'src')
-rw-r--r--src/test.c23
-rw-r--r--src/vec.c165
2 files changed, 111 insertions, 77 deletions
diff --git a/src/test.c b/src/test.c
index 0c33a74..4bb8d6b 100644
--- a/src/test.c
+++ b/src/test.c
@@ -7,21 +7,16 @@
int
main(int argc, const char **argv)
{
- struct vec *vec;
- int *num;
- int i, val;
+ struct vec vec;
+ int *num, i;
- vec = vec_alloc(sizeof(int), 10);
-
- for (i = 1; i < argc; i++) {
- val = atoi(argv[i]);
- vec_push(vec, &val);
- }
+ vec_init(&vec, sizeof(int), 10);
- num = NULL;
- while (vec_iter(vec, &num)) {
- printf("%i\n", *num);
- }
+ for (i = 1; i < argc; i++)
+ VEC_PUSH(&vec, int, atoi(argv[i]));
- vec_free(vec);
+ for (i = 0; i < vec_len(&vec); i++)
+ printf("%i\n", VEC_AT(&vec, int, i));
+
+ vec_deinit(&vec);
}
diff --git a/src/vec.c b/src/vec.c
index a784baa..abc8433 100644
--- a/src/vec.c
+++ b/src/vec.c
@@ -6,22 +6,16 @@
#include <stdarg.h>
#include <string.h>
-#define OFFSETOF(type, member) ((size_t) &((type *)0)->member)
-
+#ifdef LIBVEC_SAFE
#define ASSERT(x) assert((x), __FILE__, __LINE__, #x)
#define OOM_CHECK(x) assert((x) != NULL, __FILE__, __LINE__, "Out of Memory")
-
-struct vec {
- size_t dsize;
- size_t count, cap;
-
- char data[];
-};
+#else
+#define ASSERT(x)
+#define OOM_CHECK(x)
+#endif
static void assert(int cond, const char *file, int line, const char *condstr);
-static const size_t vec_data_offset = OFFSETOF(struct vec, data);
-
void
assert(int cond, const char *file, int line, const char *condstr)
{
@@ -32,18 +26,41 @@ assert(int cond, const char *file, int line, const char *condstr)
exit(1);
}
+void
+vec_init(struct vec *vec, size_t dsize, size_t cap)
+{
+ ASSERT(vec != NULL && dsize > 0 && cap >= 0);
+
+ vec->dsize = dsize;
+ vec->cap = cap;
+
+ vec->len = 0;
+ vec->data = NULL;
+ if (vec->cap) {
+ vec->data = malloc(dsize * cap);
+ OOM_CHECK(vec->data);
+ }
+}
+
+void
+vec_deinit(struct vec *vec)
+{
+ ASSERT(vec != NULL);
+
+ free(vec->data);
+}
+
struct vec *
vec_alloc(size_t dsize, size_t cap)
{
struct vec *vec;
- ASSERT(dsize != 0 && cap != 0);
+ ASSERT(dsize > 0 && cap > 0);
- vec = malloc(vec_data_offset + cap * dsize);
+ vec = malloc(sizeof(struct vec));
OOM_CHECK(vec);
- vec->dsize = dsize;
- vec->count = 0;
- vec->cap = cap;
+
+ vec_init(vec, dsize, cap);
return vec;
}
@@ -53,6 +70,7 @@ vec_free(struct vec *vec)
{
ASSERT(vec != NULL);
+ vec_deinit(vec);
free(vec);
}
@@ -61,50 +79,68 @@ vec_clear(struct vec *vec)
{
ASSERT(vec != NULL);
- vec->count = 0;
+ vec->len = 0;
}
void
vec_resize(struct vec *vec, size_t cap)
{
- ASSERT(vec != NULL && cap != 0 && vec->count <= cap);
+ ASSERT(vec != NULL && cap != 0 && vec->len <= cap);
vec->cap = cap;
- vec = realloc(vec, vec_data_offset + vec->cap * vec->dsize);
- OOM_CHECK(vec);
+ vec->data = realloc(vec->data, vec->cap * vec->dsize);
+ OOM_CHECK(vec->data);
}
void
-vec_add(struct vec *vec, const void *data, size_t count)
+vec_add(struct vec *vec, const void *data, size_t len)
{
ASSERT(vec != NULL && data != NULL);
- if (vec->count + count > vec->cap) {
+ if (vec->len + len > 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);
+ if (vec->len + len > vec->cap)
+ vec->cap = vec->len + len;
+ vec->data = realloc(vec->data, vec->cap * vec->dsize);
+ OOM_CHECK(vec->data);
}
- memcpy(vec->data + vec->count * vec->dsize,
- data, vec->count * vec->dsize);
- vec->count += count;
+ memcpy(vec->data + vec->len * vec->dsize, data, len * vec->dsize);
+ vec->len += len;
}
void
vec_rm(struct vec *vec, size_t count)
{
- ASSERT(vec != NULL);
+ ASSERT(vec != NULL && len >= vec->len);
- vec->count -= count;
- if (vec->count < vec->cap / 2) {
+ vec->len -= count;
+ if (vec->len < vec->cap / 2) {
vec->cap /= 2;
- vec = realloc(vec, vec_data_offset + vec->cap * vec->dsize);
- OOM_CHECK(vec);
+ vec->data = realloc(vec->data, vec->cap * vec->dsize);
+ OOM_CHECK(vec->data);
+ }
+}
+
+void
+vec_rm_at(struct vec *vec, size_t index, size_t count)
+{
+ void *start, *end;
+
+ ASSERT(vec != NULL && index < vec->len
+ && count > 0 && index + count < vec->len);
+
+ if (index + count < vec->len) {
+ start = vec->data + index * vec->dsize;
+ end = vec->data + vec->len * vec->dsize;
+ memcpy(start, start + count * vec->dsize,
+ (vec->len - index - count) * vec->dsize);
}
+
+ vec_rm(vec, count);
}
+
void
vec_push(struct vec *vec, const void *data)
{
@@ -118,35 +154,13 @@ vec_pop(struct vec *vec)
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 < 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->len;
}
void *
vec_at(struct vec *vec, size_t index)
{
- ASSERT(vec != NULL && index < vec->count);
+ ASSERT(vec != NULL && index < vec->len);
return vec->data + vec->dsize * index;
}
@@ -156,7 +170,9 @@ vec_iter(struct vec *vec, void *_p)
{
char **iter;
- ASSERT(vec != NULL && vec != NULL);
+ ASSERT(vec != NULL && p != NULL);
+
+ if (!vec->len) return false;
iter = _p;
if (*iter == NULL) {
@@ -165,23 +181,46 @@ vec_iter(struct vec *vec, void *_p)
*iter += vec->dsize;
}
- return *iter < vec->data + vec->dsize * vec->count;
+ return *iter < vec->data + vec->dsize * vec->len;
}
void
vec_set(struct vec *vec, size_t index, const void *data)
{
- ASSERT(vec != NULL && data != NULL && index < vec->count);
+ ASSERT(vec != NULL && data != NULL && index < vec->len);
memcpy(vec->data + index * vec->dsize, data, vec->dsize);
}
+void
+vec_setbuf(struct vec *vec, void *data)
+{
+ ASSERT(vec != NULL && buf != NULL);
+
+ free(vec->data);
+ vec->data = data;
+}
+
+void *
+vec_popbuf(struct vec *vec)
+{
+ void *data;
+
+ ASSERT(vec != NULL);
+
+ data = vec->data;
+ vec->data = NULL;
+ vec->len = 0;
+
+ return data;
+}
+
int
vec_empty(struct vec *vec)
{
ASSERT(vec != NULL);
- return vec->count == 0;
+ return vec->len == 0;
}
int
@@ -189,5 +228,5 @@ vec_len(struct vec *vec)
{
ASSERT(vec != NULL);
- return vec->count;
+ return vec->len;
}