#include "vec.h" #include #include #include #include vec vecNew(usize type_size, vecDestroyFn destroy) { if (type_size == 0) { type_size = sizeof(u8); } vec out = { .type_size = type_size, .destroy = destroy, }; return out; } error_t vecExpand(vec* vec, usize requested_capacity) { assert(vec != NULL); const usize new_cap = max(vec->capacity * 2, requested_capacity); void* expanded_data = realloc(vec->data, new_cap * vec->type_size); if (expanded_data == NULL) { return ERROR_REALLOCATION_FAILED; } vec->capacity = new_cap; vec->data = expanded_data; return OK; } error_t vecInsert(vec* vec, const usize index, const void* items, const usize n) { assert(vec != NULL); assert(items != NULL); assert(n > 0); assert(index <= vec->length); const uintptr_t vec_data_upper_bound = (uintptr_t)vec->data + (vec->capacity * vec->type_size); assert(((uintptr_t)items < (uintptr_t)vec->data || (uintptr_t)items >= vec_data_upper_bound) && "`items` must not be in the vector's data buffer."); // Make sure we have room const usize needed_capacity = n + vec->length; if (needed_capacity > vec->capacity) { error_t err = vecExpand(vec, needed_capacity); if (err != OK) { return err; } } const usize vec_ptr_offset = index * vec->type_size; const usize item_size = n * vec->type_size; u8* insert_dest = vec->data + vec_ptr_offset; // Shift any items after the insertion point to the right. We want to copy `(length - index)` items, n items over. if (index < vec->length) { const usize move_size = (vec->length - index) * vec->type_size; u8* move_dest = insert_dest + item_size; memmove(move_dest, insert_dest, move_size); } //Copy items memcpy(insert_dest, items, item_size); vec->length += n; return OK; } void* vecGet(vec* vec, const usize index) { assert(vec != NULL); if (index >= vec->length) { return NULL; } return vec->data + (index * vec->type_size); } void vecDestroy(vec* vec) { if (vec == NULL) { return; } vecDestroyFn destroy = vec->destroy; if (destroy != nullptr) { for (usize i = 0; i < vec->length; i++) { destroy(vecGet(vec, i)); } } free(vec->data); vec->data = nullptr; vec->length = 0; vec->capacity = 0; }