aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMistivia <i@mistivia.com>2025-06-08 18:11:12 +0800
committerMistivia <i@mistivia.com>2025-06-08 18:11:12 +0800
commit445fe6e07e3b8f5343f4a728d7ad96fbbfd0345e (patch)
tree20021b181d1204f7577154e62dfe1f00ef5ee5f9 /src
parentacd6b6fffefc52414ccc8e983b5fe9909f332626 (diff)
add generic vector
Diffstat (limited to 'src')
-rw-r--r--src/vec.c9
-rw-r--r--src/vec.h77
2 files changed, 86 insertions, 0 deletions
diff --git a/src/vec.c b/src/vec.c
new file mode 100644
index 0000000..318d328
--- /dev/null
+++ b/src/vec.c
@@ -0,0 +1,9 @@
+#include "vec.h"
+
+#include <string.h>
+
+VECTOR_IMPL(Char);
+VECTOR_IMPL(Int);
+VECTOR_IMPL(Long);
+VECTOR_IMPL(Float);
+VECTOR_IMPL(Double);
diff --git a/src/vec.h b/src/vec.h
new file mode 100644
index 0000000..3bb4014
--- /dev/null
+++ b/src/vec.h
@@ -0,0 +1,77 @@
+#ifndef ALGDS_VEC_H_
+#define ALGDS_VEC_H_
+
+#include <stdlib.h>
+
+#include "type_alias.h"
+
+#define VECTOR_DEF(T) \
+ typedef struct { \
+ T* buffer; \
+ int size; \
+ int cap; \
+ } T##Vector; \
+ \
+ void T##Vector_init(T##Vector *self); \
+ void T##Vector_push_back(T##Vector *self, T *elem); \
+ void T##Vector_insert_before(T##Vector *self, int n, T *elem); \
+ void T##Vector_pop(T##Vector *self); \
+ void T##Vector_remove(T##Vector *self, size_t n); \
+ size_t T##Vector_len(T##Vector *self); \
+ T* T##Vector_begin(T##Vector *self); \
+ T* T##Vector_end(T##Vector *self); \
+ T* T##Vector_ref(T##Vector *self, size_t n); \
+ void T##Vector_free(T##Vector *self);
+
+#define VECTOR_IMPL(T) \
+ void T##Vector_init(T##Vector *self) { \
+ self->buffer = (T*)malloc(sizeof(T) * 16); \
+ self->cap = 16; \
+ self->size = 0; \
+ } \
+ \
+ void T##Vector_push_back(T##Vector *self, T *elem) { \
+ if (self->size + 1 > self->cap) { \
+ self->buffer = realloc(self->buffer, sizeof(T) * self->cap * 2); \
+ self->cap *= 2; \
+ } \
+ memmove(self->buffer + self->size, elem, sizeof(T)); \
+ self->size += 1; \
+ } \
+ void T##Vector_insert_before(T##Vector *self, int n, T *elem) { \
+ if (n < 0 || n > self->size) { \
+ return; \
+ } \
+ if (self->size + 1 > self->cap) { \
+ self->buffer = malloc(sizeof(T) * self->cap * 2); \
+ self->cap *= 2; \
+ } \
+ if (n != self->size) { \
+ memmove(self->buffer + n + 1, \
+ self->buffer + n, \
+ sizeof(T) * (self->size - n)); \
+ memmove(self->buffer + n, elem, sizeof(T)); \
+ } \
+ } \
+ void T##Vector_pop(T##Vector *self) { \
+ self->size -= 1; \
+ } \
+ void T##Vector_remove(T##Vector *self, size_t n) { \
+ if (n < 0 || n >= self->size) return; \
+ memmove(self->buffer + n, \
+ self->buffer + n + 1, \
+ sizeof(T) * self->size - n - 1); \
+ self->size -= 1; \
+ } \
+ T* T##Vector_begin(T##Vector *self) { return self->buffer; } \
+ T* T##Vector_end(T##Vector *self) { return self->buffer + self->size; } \
+ T* T##Vector_ref(T##Vector *self, size_t n) { return self->buffer + n; } \
+ void T##Vector_free(T##Vector *self) { free(self->buffer); }
+
+VECTOR_DEF(Char);
+VECTOR_DEF(Int);
+VECTOR_DEF(Long);
+VECTOR_DEF(Float);
+VECTOR_DEF(Double);
+
+#endif