From 0330027bffc33366e6d179c3febd174d69d877ef Mon Sep 17 00:00:00 2001 From: Lorenzo Torres Date: Sun, 2 Nov 2025 20:01:00 +0100 Subject: [PATCH] implemented vectors --- core/log.h | 15 ++++++++++++++ core/vector.c | 31 +++++++++++++++++++++++++++++ core/vector.h | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++ makefile | 3 ++- 4 files changed, 103 insertions(+), 1 deletion(-) create mode 100644 core/log.h create mode 100644 core/vector.c create mode 100644 core/vector.h diff --git a/core/log.h b/core/log.h new file mode 100644 index 0000000..03173c8 --- /dev/null +++ b/core/log.h @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: BSD-3-Clause +#ifndef LOG_H +#define LOG_H + +#include + +#define log_error_code(msg) do { printf("\x1b[31m" "[ERROR]" "\x1b[0m" "(" __FILE__ ":" __LINE__ "): %s", (msg)); } while (0) +#define log_warning_code(msg) do { printf("\x1b[33m" "[WARN]" "\x1b[0m" "(" __FILE__ ":" __LINE__ "): %s", (msg)); } while (0) +#define log_info_code(msg) do { printf("\x1b[32m" "[INFO]" "\x1b[0m" "(" __FILE__ ":" __LINE__ "): %s", (msg)); } while (0) + +#define log_error(msg) do { printf("\x1b[31m" "[ERROR]" "\x1b[0m: %s", (msg)); } while (0) +#define log_warning(msg) do { printf("\x1b[33m" "[WARN]" "\x1b[0m: %s", (msg)); } while (0) +#define log_info(msg) do { printf("\x1b[32m" "[INFO]" "\x1b[0m: %s", (msg)); } while (0) + +#endif diff --git a/core/vector.c b/core/vector.c new file mode 100644 index 0000000..6c1b3a6 --- /dev/null +++ b/core/vector.c @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: BSD-3-Clause +#include "vector.h" +#include "log.h" + +struct vector *vector_init(usize size, usize element_size) +{ + struct vector *vector = (struct vector *) malloc(sizeof(struct vector)); + vector->length = 0; + vector->size = size; + vector->data = malloc(size * element_size); + return vector; +} + +void *vector_shrink(struct vector *vector, usize element_size) +{ + #ifdef DEBUG + if (vector->length == 0) log_error("Popping from an empty vector.\n"); + #endif + vector->length -= 1; + if (vector->length <= vector->size/3) { + vector->size = vector->length + vector->length/2; + vector->data = realloc(vector->data, vector->size * element_size + 1); + } + return vector->data; +} + +void vector_deinit(struct vector *vector) +{ + free(vector->data); + free(vector); +} diff --git a/core/vector.h b/core/vector.h new file mode 100644 index 0000000..3882eb2 --- /dev/null +++ b/core/vector.h @@ -0,0 +1,55 @@ +// SPDX-License-Identifier: BSD-3-Clause +#ifndef VECTOR_H +#define VECTOR_H + +#include +#include "../types.h" + +/* The vector is a dynamically growing array + * that can be operated as a regular array + * by accessing its `data` member and as a + * stack using `vector_push()` and `vector_pop()`. + */ +struct vector { + usize length, size; + void *data; +}; + +/* + * Create a new vector with starting capacity of `size` + * where each element has size `element_size`. + */ +struct vector *vector_init(usize size, usize element_size); +void vector_deinit(struct vector *vector); + +/* + * This function reduces the lenth of the vector thus + * removing the last element. If the used memory (length) + * is less than 1/3 of the allocated memory (size) the + * memory is reallocated to fit 1.5x the new length. + * Consider using the `vector_pop()` macro instead. + */ +void *vector_shrink(struct vector *vector, usize element_size); + +/* + * Push `value` on the vector. If there isn't enough + * allocated memory, reallocate the internal array + * to be 1.5x the current size and copy all the elements + * to the new allocated memory. + */ +#define vector_push(vec, T, value) do {\ + if (vec->length + 1 >= vec->size) {\ + vec->size += vec->size/2;\ + vec->data = realloc(vec->data, vec->size * sizeof(T));\ + }\ + ((T *)vec->data)[vec->length] = value;\ + vec->length += 1;\ +} while (0) + +/* + * Return the last element of the vector and calls + * `vector_shrink()`. Check out that function description. + */ +#define vector_pop(vector, T) (((T*)vector_shrink((vector), sizeof(T)))[vector->length]) + +#endif diff --git a/makefile b/makefile index 6983ae6..688a2ad 100644 --- a/makefile +++ b/makefile @@ -5,7 +5,8 @@ include config.mk SRC:=\ topaz.c\ linear.c\ - core/arena.c + core/arena.c\ + core/vector.c ifeq (${BACKEND},gl) SRC += gl/gl.c\