74 lines
2.3 KiB
C
Executable File
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;
|
|
}
|