#include #include #include /* 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; }