#include "datatypes.h" #include #include 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); }