#include #include #include "vec.h" #include "alloc.h" static enum LEO_Vec_Error LEO_Vec_grow(struct 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_Vec_TOO_BIG; vec->capacity = new_capacity; vec->data = vec->allocator.realloc(vec->data, vec->capacity * vec->item_size); if (vec->data == NULL) return LEO_Vec_ALLOCATION_FAILURE; return LEO_Vec_OK; } enum LEO_Vec_Error LEO_Vec_init(struct LEO_Vec *vec, size_t item_size, struct LEO_Allocator allocator) { if (vec == NULL) return LEO_Vec_NULL_VEC_POINTER; if (item_size == 0) return LEO_Vec_INVALID_ITEM_SIZE; 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_Vec_ALLOCATION_FAILURE; return LEO_Vec_OK; } void LEO_Vec_free(struct LEO_Vec *vec) { if (vec == NULL) return; vec->allocator.free(vec->data); vec->data = NULL; } enum LEO_Vec_Error LEO_Vec_push(struct LEO_Vec *vec, const void *item) { if (vec == NULL) return LEO_Vec_NULL_VEC_POINTER; if (item == NULL) return LEO_Vec_NULL_ITEM_POINTER; if (vec->length >= vec->capacity) { enum LEO_Vec_Error result = LEO_Vec_grow(vec); if (result != LEO_Vec_OK) return result; } unsigned char *dest = (unsigned char *)vec->data + (vec->length++) * vec->item_size; memcpy(dest, item, vec->item_size); return LEO_Vec_OK; } enum LEO_Vec_Error LEO_Vec_pop(struct LEO_Vec *vec, void *item) { if (vec == NULL) return LEO_Vec_NULL_VEC_POINTER; if (vec->length == 0) return LEO_Vec_OUT_OF_BOUNDS; void *src = vec->data + (vec->length--) * vec->item_size; memcpy(item, src, vec->item_size); return LEO_Vec_OK; } enum LEO_Vec_Error LEO_Vec_get(struct LEO_Vec *vec, size_t i, void *item) { if (vec == NULL) return LEO_Vec_NULL_VEC_POINTER; if (i >= vec->length) return LEO_Vec_OUT_OF_BOUNDS; unsigned char *src = (unsigned char *) vec->data + i * vec->item_size; memcpy(item, src, vec->item_size); return LEO_Vec_OK; }