105 lines
3.5 KiB
C
105 lines
3.5 KiB
C
#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; }
|