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) { UN_CLEAR(list); } return list; } void un_list_destroy(List *list) { un_memory_free(list->data, 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); if (result.data == NULL) { UN_CLEAR(list); } else { memcpy(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; } memcpy(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_alloc_std_get() : 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; memcpy(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) { memmove(addr, (u8*)addr + list->element_size, move_elements * list->element_size); } list->count--; }