Files
tlibc/src/collections/List.c

74 lines
2.3 KiB
C
Executable File

#include "tlibc/collections/List.h"
#include <assert.h>
List_ _List_alloc(u32 initial_capacity, u32 elem_t_size){
assert(elem_t_size != 0);
if(initial_capacity == 0)
return _List_construct(NULL, 0, 0, elem_t_size);
u32 initial_size = initial_capacity * elem_t_size;
u32 aligned_capacity = ALIGN_TO(initial_size, sizeof(void*));
return _List_construct(malloc(aligned_capacity), 0, aligned_capacity, elem_t_size);
}
List_ _List_copy(const List_* src){
assert(src->elem_t_size != 0);
List_ copy = _List_alloc(src->capacity, src->elem_t_size);
if(copy.data != NULL){
memcpy(copy.data, src->data, src->len * src->elem_t_size);
}
return copy;
}
void _List_increaseCapacity(List_* self, u32 len_to_add){
assert(self->elem_t_size != 0);
u32 expanded_len = self->len + len_to_add;
if(self->capacity > expanded_len)
return;
u32 expanded_capacity = self->capacity;
if(expanded_capacity == 0)
expanded_capacity = 32;
while(expanded_capacity < expanded_len){
expanded_capacity *= 2;
}
// if self->data is null, realloc acts like malloc
self->data = realloc(self->data, expanded_capacity * self->elem_t_size);
self->capacity = expanded_capacity;
}
void* _List_expand(List_* self, u32 len_to_add){
assert(self->elem_t_size != 0);
_List_increaseCapacity(self, len_to_add);
u8* empty_cell_ptr = (u8*)self->data + self->len * self->elem_t_size;
self->len += len_to_add;
return empty_cell_ptr;
}
void _List_push(List_* self, void* values, u32 len){
assert(self->elem_t_size != 0);
void* empty_cell_ptr = _List_expand(self, len);
memcpy(empty_cell_ptr, values, len * self->elem_t_size);
}
bool _List_tryRemoveAt(List_* self, u32 i, u32 remove_len){
assert(self->elem_t_size != 0);
if(i >= self->len)
return false;
if(remove_len + i > self->len)
remove_len = self->len - i;
u32 move_back_n_elements = self->len - i - remove_len;
if(move_back_n_elements > 0){
u32 move_back_size = move_back_n_elements * self->elem_t_size;
u8* dst = (u8*)self->data + i * self->elem_t_size;
u8* src = (u8*)self->data + (i + remove_len) * self->elem_t_size;
memmove(dst, src, move_back_size);
}
self->len -= remove_len;
return true;
}