undar-lang/list.c

105 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 *dest;
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++;
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)
{
Node *curr;
if (!list || !func) return;
curr = list->head;
while (curr) {
func(node_value(curr));
curr = curr->next;
}
}
void *
list_get(List *list, u32 index)
{
u32 i;
Node *curr;
if (!list || index >= list->count) return nil;
curr = list->head;
for (i = 0; i < index; i++) {
curr = curr->next;
}
return node_value(curr);
}
void
list_set(List *list, u32 index, void *data, u32 size)
{
void *target = list_get(list, index);
if (target) {
mcpy(target, data, size);
}
}
void *
list_find(List *list, compare_fn compare, void *target)
{
Node *curr;
void *data;
if (!list || !compare) return nil;
curr = list->head;
while (curr) {
data = node_value(curr);
if (compare(data, target)) {
return data;
}
curr = curr->next;
}
return nil;
}