From a78acfc09c78fcec7c5791a58b95501187ef8ca2 Mon Sep 17 00:00:00 2001 From: Lucas Schumacher Date: Wed, 2 Oct 2024 21:58:17 -0400 Subject: [PATCH] Initial implementation --- .gitignore | 1 + vec.c | 102 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 103 insertions(+) create mode 100644 .gitignore create mode 100644 vec.c diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..cba7efc --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +a.out diff --git a/vec.c b/vec.c new file mode 100644 index 0000000..02da7b0 --- /dev/null +++ b/vec.c @@ -0,0 +1,102 @@ +#include +#include +#include +#include + +typedef struct vec { + size_t len; + int capacity; + size_t element_size; + void* ptr; +} vec; + +vec vecMalloc(size_t element_size) { + vec new; + new.len = 0; + new.capacity = 32; + new.element_size = element_size; + new.ptr = calloc(new.capacity, element_size); + if (new.ptr == NULL) new.capacity = -1; + return new; +} + +#define vecNew(type) vecMalloc(sizeof(type)) + +void vecFree(vec* v) { + if (v->capacity < 0) return; + v->capacity = -1; + v->len = 0; + free(v->ptr); +} + +// Returns 0 on success +int vecResize(vec* v, int newcap) { + void* newptr = calloc(newcap, v->element_size); + if (newptr == NULL) return 1; + + memcpy(newptr, v->ptr, v->len * v->element_size); + + void *oldptr = v->ptr; + v->ptr = newptr; + v->capacity = newcap; + free(oldptr); + + return 0; +} + +// returns 0 on success +int vecPush(vec* v, void* item) { + if (v->capacity < v->len) return 1; + + if (v->len + 1 >= v->capacity) { + if (vecResize(v, v->capacity * 2)) return 1; + } + + memcpy(v->ptr + (v->element_size * v->len), item, v->element_size); + v->len += 1; + + return 0; +} + +// returns NULL on failure +void* vecAt(vec* v, size_t index) { + if (index >= v->len) return NULL; + return v->ptr + (index * v->element_size); +} + +// NOTE: returns 1 on success, 0 on failure. For use with loops. +int vecAtPtr(vec* v, size_t index, void** ptr) { + if(index >= v->len) return 0; + *ptr = v->ptr + (index * v->element_size); + return 1; +} +#define vecIter(v, type) for(struct{int i; type* item;} iter = {0, NULL}; vecAtPtr(&v, iter.i, (void**)&iter.item); ++iter.i) + +int main(int argc, char *argv[]) { + printf("Hello World!\n"); + char* str = "HI"; + + vec v = vecNew(char); + + if(vecPush(&v, str)) { + printf("Error pushing %c\n", *str); + } else { + printf("Pushed %c\n", *str); + }; + + printf(vecPush(&v, str+1) ? "Error pushing %c\n" : "Pushed %c\n", *(str+1)); + + printf("vec len: %d\n", v.len); + + printf("Iter fn\n"); + vecIter(v, char) { + printf("%d: %c\n", iter.i, *iter.item); + } + + printf("For loop\n"); + for(size_t i = 0; i < v.len; i++) { + char* item = (char*)vecAt(&v, i); + printf("%d: %c\n", i, *item); + } + return EXIT_SUCCESS; +}