99 lines
1.7 KiB
C
99 lines
1.7 KiB
C
#include "list.h"
|
|
|
|
List *
|
|
new_list(Arena *arena)
|
|
{
|
|
List *l = aalloc(arena, sizeof(List));
|
|
if (!l) return nil;
|
|
|
|
l->head = nil;
|
|
l->tail = nil;
|
|
l->count = 0;
|
|
|
|
return l;
|
|
}
|
|
|
|
void *
|
|
node_value(Node *n)
|
|
{
|
|
return (void *)((u8 *)n + sizeof(Node));
|
|
}
|
|
|
|
void *
|
|
list_push(Arena *arena, List *list, void *data, u32 data_size)
|
|
{
|
|
void *ptr = aalloc(arena, sizeof(Node) + data_size);
|
|
Node *node = (Node *)ptr;
|
|
|
|
if (!node) return nil;
|
|
|
|
node->next = nil;
|
|
|
|
if (!list->head) {
|
|
list->head = list->tail = node;
|
|
} else {
|
|
list->tail->next = node;
|
|
list->tail = node;
|
|
}
|
|
|
|
list->count++;
|
|
|
|
void *dest = node_value(node);
|
|
if (data && data_size > 0) {
|
|
mcpy(dest, data, data_size);
|
|
}
|
|
|
|
return dest;
|
|
}
|
|
|
|
void
|
|
list_foreach(List *list, list_iter_fn func)
|
|
{
|
|
if (!list || !func) return;
|
|
|
|
Node *curr = list->head;
|
|
while (curr) {
|
|
func(node_value(curr));
|
|
curr = curr->next;
|
|
}
|
|
}
|
|
|
|
void *
|
|
list_get(List *list, u32 index)
|
|
{
|
|
if (!list || index >= list->count) return nil;
|
|
|
|
Node *curr = list->head;
|
|
// Walk to the desired index
|
|
for (u32 i = 0; i < index; i++) {
|
|
curr = curr->next;
|
|
}
|
|
|
|
return node_value(curr);
|
|
}
|
|
|
|
void
|
|
list_set(List *list, u32 index, const void *data, u32 size)
|
|
{
|
|
void *target = list_get(list, index);
|
|
if (target) {
|
|
mcpy(target, data, size);
|
|
}
|
|
}
|
|
|
|
void *
|
|
list_find(List *list, compare_fn compare, const void *target)
|
|
{
|
|
if (!list || !compare) return nil;
|
|
|
|
Node *curr = list->head;
|
|
while (curr) {
|
|
void *data = node_value(curr);
|
|
if (compare(data, target)) {
|
|
return data;
|
|
}
|
|
curr = curr->next;
|
|
}
|
|
return nil;
|
|
}
|