Simple ArrayList and FIFO for C projects
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

#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);
}