Huge refactor, documentation incoming

This commit is contained in:
2020-10-07 17:13:28 +02:00
parent 1e86a8736f
commit 8e29343f3e
7 changed files with 188 additions and 123 deletions

101
src/vector.c Normal file
View File

@@ -0,0 +1,101 @@
#include "vector.h"
Vector vec_new(Destructor destructor)
{
Vector self;
self.length = 0;
self.capacity = INITIAL_CAPACITY;
self.offset = sizeof(void *);
self.elements = (void *)malloc(self.offset * INITIAL_CAPACITY);
self.destroy = destructor;
return self;
}
Vector vec_with_capacity(Destructor t_destructor, size_t t_capacity)
{
Vector self = vec_new(t_destructor);
free(self.elements);
self.elements = (void **)malloc(self.offset * t_capacity);
self.capacity = t_capacity;
return self;
}
void *vec_at(Vector *self, size_t t_index)
{
return self->elements[t_index];
}
void *vec_safe_at(Vector *self, size_t t_index)
{
return (t_index >= vec_length(self)) ? NULL : vec_at(self, t_index);
}
static void vec_maybe_destroy_element(Vector *self, size_t t_index)
{
void *element = vec_at(self, t_index);
if (self->destroy) {
self->destroy(element);
}
}
void *vec_last(Vector *self)
{
return vec_at(self, vec_length(self) - 1);
}
size_t vec_length(Vector *self)
{
return self->length;
}
size_t vec_capacity(Vector *self)
{
return self->capacity;
}
static void vec_realloc(Vector *self)
{
self->capacity *= 2;
self->elements = realloc(self->elements, sizeof(void *) * vec_capacity(self));
if (!self->elements) {
PDEB("Could not reallocate Vectors memory, aborting...", NULL);
exit(ERR_MEM_ALLOC);
}
}
void vec_push(Vector *self, void *t_element)
{
if (vec_length(self) >= vec_capacity(self)) {
vec_realloc(self);
}
self->elements[(*self).length++] = t_element;
}
void vec_pop(Vector *self)
{
if (vec_length(self) <= 0) {
return;
}
vec_maybe_destroy_element(self, vec_length(self) - 1);
--(*self).length;
}
void vec_shrink_to_fit(Vector *self)
{
self->capacity = self->length;
self->elements = realloc(self->elements, sizeof(void *) * vec_capacity(self));
if (!self->elements) {
PDEB("Could not reallocate Vectors memory, aborting...", NULL);
exit(ERR_MEM_ALLOC);
}
}
void vec_delete(Vector *self)
{
if (self->destroy) {
for (size_t i = 0; i < vec_length(self); ++i) {
self->destroy(self->elements[i]);
}
}
free(self->elements);
}

74
src/vector.h Normal file
View File

@@ -0,0 +1,74 @@
#ifndef VECTOR_H
#define VECTOR_H
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#ifndef DEBUG
# define DEBUG 0
#endif
#define ERR_MEM_ALLOC 1
#define NO_COLOR "\x1b[0m"
#define RED "\x1b[31m"
#define GREEN "\x1b[32m"
#define BROWN "\x1b[33m"
#define BLUE "\x1b[34m"
#define MAGENTA "\x1b[35m"
#define CYAN "\x1b[36m"
#define GRAY "\x1b[37m"
#define UNINPLEMENTED printf("%s:%d: Not yet implemented", __FILE__, __LINE__)
#define INITIAL_CAPACITY 4
#define PDEB(format, ...) \
if (DEBUG) { \
fprintf(stderr, \
GREEN "%s:%d\t" NO_COLOR format "\n", \
__FILE__, \
__LINE__, \
__VA_ARGS__); \
}
#define foreach(item, vector) \
for (int keep = 1, \
count = 0, \
size = sizeof(vector->elements) / sizeof vector->elements; \
keep && count != size; \
keep = !keep, count++) \
for (item = \
(void *)((char *)(vector->elements) + (count * sizeof(void *))); \
keep; \
keep = !keep)
#ifndef ARRAY_SIZE
# define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
#endif
// TODO
// `sizeof()' does NOT work with dynamically allocated memory. Vector capacity
// must be tracked manually
/* Destructor typedef */
typedef void (*Destructor)(void *element);
typedef struct Vector_s {
size_t length;
size_t capacity;
size_t offset;
void ** elements;
Destructor destroy;
} Vector;
Vector vec_new(Destructor destructor);
Vector vec_with_capacity(Destructor destructor, size_t capacity);
void * vec_at(Vector *self, size_t index);
void * vec_safe_at(Vector *self, size_t index);
void * vec_last(Vector *self);
size_t vec_length(Vector *self);
size_t vec_capacity(Vector *self);
void vec_push(Vector *self, void *element);
void vec_pop(Vector *self);
void vec_shrink_to_fit(Vector *self);
void vec_delete(Vector *self);
#endif /* VECTOR_H */