You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
159 lines
3.6 KiB
159 lines
3.6 KiB
#include "datatypes.h" |
|
#include <string.h> |
|
#include <stdlib.h> |
|
|
|
ArrayList new_arlst(int num_elems) { |
|
ArrayList new_list; |
|
new_list.free = NULL; |
|
new_list.size = 0; |
|
new_list.capacity = num_elems; |
|
new_list.items = calloc(num_elems, sizeof(void *)); |
|
|
|
return new_list; |
|
} |
|
|
|
ArrayList new_arlst_wfree(int num_elems, void (*nfree)(void *ptr)) { |
|
ArrayList new_list = new_arlst(num_elems); |
|
new_list.free = nfree; |
|
return new_list; |
|
} |
|
|
|
ArrayList new_arlst_using_array(void **array, int length) { |
|
ArrayList l = new_arlst(length); |
|
free(l.items); |
|
l.items = array; |
|
return l; |
|
} |
|
|
|
ArrayList new_arlst_using_array_wfree(void **array, int length, |
|
void (*f)(void *)) { |
|
ArrayList l = new_arlst_using_array(array, length); |
|
l.free = f; |
|
return l; |
|
} |
|
|
|
ArrayList new_arlst_from_array(void *array, size_t elem_size, int length) { |
|
ArrayList l = new_arlst(length); |
|
l.free = free; |
|
|
|
for (int i = 0; i < length; i++) { |
|
void *item = calloc(1, elem_size); |
|
void *start = array + i * elem_size; |
|
memmove(item, start, elem_size); |
|
arlst_add(&l, item); |
|
} |
|
return l; |
|
} |
|
|
|
void *arlst_get(ArrayList *l, int id) { |
|
// out of bounds |
|
if (id < 0 || id >= l->size) { |
|
return 0; |
|
} |
|
|
|
return l->items[id]; |
|
} |
|
|
|
void * arlst_del(ArrayList *l, int id) { |
|
void *item = arlst_get(l, id); |
|
|
|
if (!item) { |
|
return NULL; |
|
} |
|
|
|
l->size--; |
|
// move elements backward |
|
for (int i = id; i < l->size; i++) { |
|
l->items[i] = l->items[i+1]; |
|
} |
|
|
|
|
|
// shrink capacity if neccessary |
|
if (D_SHRINK_THRESHOLD != 0 |
|
|| l->size < (100 / D_SHRINK_THRESHOLD) * l->capacity) { |
|
|
|
size_t new_size = l-> size + (l->capacity * (100 / D_SHRINK_THRESHOLD) * |
|
100 / D_GROW_AMOUNT); |
|
|
|
// l->items = reallocarray(l->items, new_size, sizeof(void *)); |
|
l->items = realloc(l->items, new_size * sizeof(void *)); |
|
} |
|
|
|
return item; |
|
} |
|
|
|
int arlst_add(ArrayList *l, void *item) { |
|
int item_index = l->size; |
|
|
|
// grow if neccessary |
|
if (l->size == l->capacity) { |
|
size_t new_size = l->capacity + (100 / D_GROW_AMOUNT) * l->capacity; |
|
l->capacity = new_size; |
|
//l->items = (void **)reallocarray(l->items, new_size, sizeof(void *)); |
|
l->items = (void **)realloc(l->items, new_size * sizeof(void *)); |
|
} |
|
|
|
l->items[item_index] = item; |
|
l->size++; |
|
|
|
return 0; |
|
} |
|
|
|
void * arlst_pop(ArrayList *l) { |
|
l->size--; |
|
return l->items[l->size]; |
|
} |
|
|
|
int arlst_push(ArrayList *l, void *item) { |
|
return arlst_add(l, item); |
|
} |
|
|
|
int arlst_destroy(ArrayList *l) { |
|
if (l->free != NULL) { |
|
for (int i = 0; i < l->size; i++) { |
|
l->free(l->items[i]); |
|
} |
|
} |
|
free(l->items); |
|
return 0; |
|
} |
|
|
|
|
|
ListFiFo new_fifo(int start_size) { |
|
ListFiFo l; |
|
memset(&l, 0, sizeof(ListFiFo)); |
|
l.inner = new_arlst(start_size); |
|
l.size = &l.inner.size; |
|
return l; |
|
} |
|
|
|
void *fifo_get(ListFiFo *l) { |
|
if (l->fifo_head >= l->inner.size) { |
|
return NULL; |
|
} |
|
|
|
void *value = arlst_get(&l->inner, l->fifo_head); |
|
|
|
if (value != NULL) { |
|
l->fifo_head++; |
|
} |
|
|
|
if (l->fifo_head == l->inner.capacity |
|
|| (l->fifo_head == l->inner.size |
|
&& l->inner.size >= D_MAX_QUEUE_LEN)) { |
|
// start rewriting from the beginning |
|
l->inner.size = 0; |
|
l->fifo_head = 0; |
|
// memset(l->inner.items, 0, sizeof(void *) * l->inner.capacity); |
|
} |
|
return value; |
|
} |
|
|
|
/* It is up to the caller to free any data stored */ |
|
int fifo_add(ListFiFo *l, void *i) { |
|
if (l->inner.size >= D_MAX_QUEUE_LEN) { |
|
return -1; |
|
} |
|
return arlst_add(&l->inner, i); |
|
} |
|
|
|
|