List un_list_create(u64 start_capacity, u64 element_size, Allocator alloc) { List list; list.count = 0; list.capacity = start_capacity; list.element_size = element_size; list.alloc = alloc; list.data = un_memory_alloc(list.capacity * list.element_size, alloc); if (list.data == NULL) { list.alloc = un_allocator_get_temporary(); list.data = un_memory_alloc(list.capacity * list.element_size, list.alloc); } return list; } void un_list_destroy(List *list, b32 delete_allocator) { if (delete_allocator) { un_memory_destroy(&list->alloc); } UN_CLEAR(*list); } List un_list_clone(List *list, Allocator alloc) { List result; result = *list; result.alloc = alloc; result.data = un_memory_alloc(result.capacity * result.element_size, alloc); assert(result.data != NULL); if (result.data == NULL) { result.alloc = un_allocator_get_temporary(); result.data = un_memory_alloc(result.capacity * result.element_size, result.alloc); } un_memory_copy(result.data, list->data, result.count * result.element_size); return result; } static b32 list_grow_if_needed(List *list) { if ((list->count + 1) <= list->capacity) { return true; } else { void *mem = un_memory_alloc(list->element_size * list->capacity * 2, list->alloc); if (!mem) { return false; } un_memory_copy(mem, list->data, list->element_size * list->capacity); un_memory_free(list->data, list->alloc); list->data = mem; list->capacity *= 2; } return true; } static void un_list_create_if_needed(List *list) { assert(list != NULL); if (list->data != NULL) return; assert(list->capacity == 0); assert(list->element_size != 0); if (!list->data) { Allocator alloc = list->alloc.proc == NULL ? un_allocator_get_standard() : list->alloc; *list = un_list_create(UN_LIST_STANDARD_CAPACITY, list->element_size, alloc); } } b32 un_list_append(List *list, void *data) { un_list_create_if_needed(list); void *addr; if (list_grow_if_needed(list)) { addr = (u8*)list->data + list->count * list->element_size; un_memory_copy(addr, data, list->element_size); list->count++; return true; } else { return false; } } void *un_list_get(List *list, u64 index) { if (index >= list->count) return NULL; assert(list->data != NULL); return (u8*)list->data + index * list->element_size; } void un_list_remove(List *list, u64 index) { void *addr; u64 move_elements; if (index >= list->count) return; assert(list->data != NULL); addr = (u8*)list->data + index * list->element_size; move_elements = list->count - (index + 1); if (move_elements) { un_memory_move(addr, (u8*)addr + list->element_size, move_elements * list->element_size); } list->count--; }