pgpl/src/vector.c

105 lines
3.5 KiB
C
Raw Normal View History

2025-10-03 20:16:11 +02:00
#include <pgpl.h>
#include <stdlib.h>
#include <string.h>
/* TODO: Further test this file. */
struct PGPL_Vector {
void *data;
uint32_t data_size;
uint32_t length;
uint32_t allocated;
void *last_delete;
};
#define pgpl_vector_internal_conditional_resize(vector) \
if (vector->length > vector->allocated) { \
vector->allocated *= 2; \
vector->data = \
realloc(vector->data, vector->allocated * vector->data_size); \
}
#define pgpl_vector_internal_memcpy_offset(vector, i) \
(char *)vector->data + (vector->data_size * (i))
PGPL_Vector *pgpl_vector_create(uint32_t data_size) {
PGPL_Vector *vector = malloc(sizeof(*vector));
vector->data_size = data_size;
vector->allocated = 1;
vector->length = 0;
vector->last_delete = malloc(vector->data_size);
vector->data = malloc(vector->allocated * vector->data_size);
return vector;
}
void pgpl_vector_destroy(PGPL_Vector *vector) {
free(vector->data);
free(vector->last_delete);
free(vector);
}
void pgpl_vector_push_back(PGPL_Vector *vector, void *data) {
vector->length++;
pgpl_vector_internal_conditional_resize(vector);
memcpy(pgpl_vector_internal_memcpy_offset(vector, vector->length - 1), data,
vector->data_size);
}
void pgpl_vector_push_front(PGPL_Vector *vector, void *data) {
vector->length++;
pgpl_vector_internal_conditional_resize(vector);
memmove(pgpl_vector_internal_memcpy_offset(vector, 1), vector->data,
vector->data_size * vector->length);
memcpy(vector->data, data, vector->data_size);
}
void *pgpl_vector_pop_back(PGPL_Vector *vector) {
memcpy(vector->last_delete,
pgpl_vector_internal_memcpy_offset(vector, vector->length - 1),
vector->data_size);
vector->length--;
return vector->last_delete;
}
void *pgpl_vector_pop_front(PGPL_Vector *vector) {
memcpy(vector->last_delete, vector->data, vector->data_size);
vector->length--;
memmove(vector->data, pgpl_vector_internal_memcpy_offset(vector, 1),
vector->data_size * vector->length);
return vector->last_delete;
}
void *pgpl_vector_peek_back(PGPL_Vector *vector) {
return pgpl_vector_internal_memcpy_offset(vector, vector->length - 1);
}
void *pgpl_vector_peek_front(PGPL_Vector *vector) { return vector->data; }
void *pgpl_vector_delete_index(PGPL_Vector *vector, uint32_t index) {
memcpy(vector->last_delete, pgpl_vector_internal_memcpy_offset(vector, index),
vector->data_size);
memmove(pgpl_vector_internal_memcpy_offset(vector, index),
pgpl_vector_internal_memcpy_offset(vector, index + 1),
vector->data_size * (vector->length - index - 1));
vector->length--;
return vector->last_delete;
}
void pgpl_vector_insert_after_index(PGPL_Vector *vector, uint32_t index,
void *data) {
vector->length++;
pgpl_vector_internal_conditional_resize(vector);
memmove(pgpl_vector_internal_memcpy_offset(vector, index + 2),
pgpl_vector_internal_memcpy_offset(vector, index + 1),
vector->data_size * (vector->length - index - 2));
memcpy(pgpl_vector_internal_memcpy_offset(vector, index + 1), data,
vector->data_size);
}
void *pgpl_vector_get_index(PGPL_Vector *vector, uint32_t index) {
return pgpl_vector_internal_memcpy_offset(vector, index);
}
uint32_t pgpl_vector_get_length(PGPL_Vector *vector) { return vector->length; }