-#include <stdlib.h>
-#include <string.h>
+#include <stdlib.h> // for malloc, free
+#include <string.h> // for strcmp
+#include "bits/wrappers.h"
#include "list.h"
-bool list_compare_default(void *v1, void *v2)
-{
- return v1 == v2;
-}
+#define ITER_REFS node = &list->fst; *node != NULL; node = &(*node)->nxt
-bool list_compare_string(void *v1, void *v2)
+void list_ini(List *list)
{
- return strcmp(v1, v2) == 0;
+ list->fst = NULL;
+ list->end = &list->fst;
}
-List list_create(ListComparator cmp)
-{
- return (List) {
- .cmp = cmp ? cmp : list_compare_default,
- .first = NULL,
- };
-}
+WRAP_NODE_FUNCTIONS(List, list_)
-void list_clear(List *list)
+void list_apd(List *list, void *dat)
{
- list_clear_func(list, NULL, NULL);
+ list_nmk(list, list->end, dat);
}
-void list_clear_func(List *list, void (*func)(void *key, void *value, void *arg), void *arg)
+ListNode **list_nfd(List *list, void *key, Comparator cmp)
{
- for (ListPair *pair = list->first; pair != NULL;) {
- ListPair *next = pair->next;
- if (func)
- func(pair->key, pair->value, arg);
- free(pair);
- pair = next;
- }
- list->first = NULL;
-}
+ ListNode **node;
-static ListPair *make_pair(void *key, void *value)
-{
- ListPair *pair = malloc(sizeof(ListPair));
- pair->key = key;
- pair->value = value;
- pair->next = NULL;
- return pair;
+ for (ITER_REFS)
+ if (cmp((*node)->dat, key) == 0)
+ return node;
+
+ return node;
}
-bool list_put(List *list, void *key, void *value)
+void list_nmk(List *list, ListNode **node, void *dat)
{
- ListPair **pairptr;
- for (pairptr = &list->first; *pairptr != NULL; pairptr = &(*pairptr)->next) {
- if (list->cmp((*pairptr)->key, key))
- return false;
- }
- *pairptr = make_pair(key, value);
- return true;
+ *node = malloc(sizeof **node);
+ (*node)->dat = dat;
+ (*node)->nxt = NULL;
+
+ if (list->end == node)
+ list->end = &(*node)->nxt;
}
-void *list_get_cached(List *list, void *key, void *(*provider)(void *key))
+void list_nrm(List *list, ListNode **node)
{
- ListPair **pairptr;
- for (pairptr = &list->first; *pairptr != NULL; pairptr = &(*pairptr)->next) {
- if (list->cmp((*pairptr)->key, key))
- return (*pairptr)->value;
- }
- return (*pairptr = make_pair(key, provider(key)))->value;
+ ListNode *old = *node;
+ *node = old->nxt;
+
+ if (list->end == &old->nxt)
+ list->end = node;
+
+ free(old);
}
-void list_set(List *list, void *key, void *value)
+void list_itr(List *list, Iterator func, void *arg)
{
- ListPair **pairptr;
- for (pairptr = &list->first; *pairptr != NULL; pairptr = &(*pairptr)->next) {
- if (list->cmp((*pairptr)->key, key))
- break;
- }
- *pairptr = make_pair(key, value);
+ LIST_ITERATE(list, node)
+ func(node->dat, arg);
}
-void *list_delete(List *list, void *key)
+void list_clr(List *list, Iterator func, void *arg)
{
- for (ListPair **pairptr = &list->first; *pairptr != NULL; pairptr = &(*pairptr)->next) {
- if (list->cmp((*pairptr)->key, key)) {
- ListPair *pair = *pairptr;
- void *value = (*pairptr)->value;
- *pairptr = pair->next;
- free(pair);
- return value;
- }
+ for (ListNode *node = list->fst; node != NULL;) {
+ ListNode *next = node->nxt;
+
+ if (func)
+ func(node->dat, arg);
+
+ free(node);
+ node = next;
}
- return NULL;
-}
-void *list_get(List *list, void *key)
-{
- for (ListPair *pair = list->first; pair != NULL; pair = pair->next)
- if (list->cmp(pair->key, key))
- return pair->value;
- return NULL;
+ list_ini(list);
}