#include #include #include #include "vec.h" #include "alloc.h" static LEO_Error LEO_Vec_grow(LEO_Vec *vec) { size_t new_capacity = vec->capacity * LEO_Vec_GROWTH_FACTOR_NUMER / LEO_Vec_GROWTH_FACTOR_DENOM; if (new_capacity <= vec->capacity) return LEO_Error_AllocationFailure; vec->capacity = new_capacity; vec->data = vec->allocator.realloc(vec->data, vec->capacity * vec->item_size); if (vec->data == NULL) return LEO_Error_AllocationFailure; return LEO_Error_Ok; } LEO_Error LEO_Vec_init(LEO_Vec *vec, size_t item_size, LEO_Allocator allocator) { assert(vec != NULL); assert(item_size != 0); vec->allocator = allocator; vec->item_size = item_size; vec->length = 0; vec->capacity = LEO_Vec_DEFAULT_CAPACITY; vec->data = vec->allocator.alloc(vec->capacity * vec->item_size); if (!vec->data) return LEO_Error_AllocationFailure; return LEO_Error_Ok; } void LEO_Vec_free(LEO_Vec *vec) { if (vec == NULL) return; vec->allocator.free(vec->data); vec->data = NULL; } LEO_Error LEO_Vec_push(LEO_Vec *vec, const void *item) { assert(vec != NULL); assert(item != NULL); if (vec->length >= vec->capacity) { LEO_Error result = LEO_Vec_grow(vec); if (result != LEO_Error_Ok) return result; } unsigned char *dest = (unsigned char *)vec->data + (vec->length++) * vec->item_size; memcpy(dest, item, vec->item_size); return LEO_Error_Ok; } LEO_Error LEO_Vec_pop(LEO_Vec *vec, void *item) { assert(vec != NULL); if (vec->length == 0) return LEO_Error_OutOfBounds; void *src = vec->data + (vec->length--) * vec->item_size; memcpy(item, src, vec->item_size); return LEO_Error_Ok; } LEO_Error LEO_Vec_get(LEO_Vec *vec, size_t i, void *item) { assert(vec != NULL); if (i >= vec->length) return LEO_Error_OutOfBounds; unsigned char *src = (unsigned char *) vec->data + i * vec->item_size; memcpy(item, src, vec->item_size); return LEO_Error_Ok; }