]> git.lizzy.rs Git - dragonstd.git/blobdiff - list.c
refactoring + documentation + testing + added Map and Refcount
[dragonstd.git] / list.c
diff --git a/list.c b/list.c
index 7388eafab2345c1a657a89e13b9f75b20d9a3ce5..f136706196f7ab65909aa671914a9aea760f4a51 100644 (file)
--- a/list.c
+++ b/list.c
-#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);
 }