ucx/list.c

changeset 255
bf19378aed58
parent 110
53895e9a4bbb
child 256
54433cb371df
--- a/ucx/list.c	Fri Nov 18 13:39:20 2016 +0100
+++ b/ucx/list.c	Fri Nov 18 15:27:45 2016 +0100
@@ -1,7 +1,7 @@
 /*
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
  *
- * Copyright 2015 Olaf Wintermann. All rights reserved.
+ * Copyright 2016 Olaf Wintermann. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are met:
@@ -76,6 +76,13 @@
     }
 }
 
+void ucx_list_free_content(UcxList* list, ucx_destructor destr) {
+    while (list != NULL) {
+        destr(list->data);
+        list = list->next;
+    }
+}
+
 UcxList *ucx_list_append(UcxList *l, void *data)  {
     return ucx_list_append_a(ucx_default_allocator(), l, data);
 }
@@ -99,6 +106,41 @@
     }
 }
 
+UcxList *ucx_list_append_once(UcxList *l, void *data,
+        cmp_func cmpfnc, void *cmpdata) {
+    return ucx_list_append_once_a(ucx_default_allocator(), l,
+            data, cmpfnc, cmpdata);
+}
+
+UcxList *ucx_list_append_once_a(UcxAllocator *alloc, UcxList *l, void *data,
+        cmp_func cmpfnc, void *cmpdata) {
+
+    UcxList *last = NULL;
+    {
+        UcxList *e = l;
+        while (e) {
+            if (cmpfnc(e->data, data, cmpdata) == 0) {
+                return l;
+            }
+            last = e;
+            e = e->next;
+        }
+    }
+    
+    UcxList *nl = ucx_list_append_a(alloc, NULL, data);
+    if (!nl) {
+        return NULL;
+    }
+
+    if (last == NULL) {
+        return nl;
+    } else {
+        nl->prev = last;
+        last->next = nl;
+        return l;
+    }
+}
+
 UcxList *ucx_list_prepend(UcxList *l, void *data) {
     return ucx_list_prepend_a(ucx_default_allocator(), l, data);
 }
@@ -117,6 +159,40 @@
     return nl;
 }
 
+UcxList *ucx_list_prepend_once(UcxList *l, void *data,
+        cmp_func cmpfnc, void* cmpdata) {
+    return ucx_list_prepend_once_a(ucx_default_allocator(), l,
+            data, cmpfnc, cmpdata);
+}
+
+UcxList *ucx_list_prepend_once_a(UcxAllocator *alloc, UcxList *l, void *data,
+        cmp_func cmpfnc, void *cmpdata) {
+    
+    if (l) {
+        int found = 0;
+        UcxList *first;
+        {
+            UcxList *e = l;
+            while (e) {
+                found |= (cmpfnc(e->data, data, cmpdata) == 0);
+                first = e;
+                e = e->prev;
+            }
+        }
+
+        if (found) {
+            return first;
+        } else {
+            UcxList *nl = ucx_list_append_a(alloc, NULL, data);
+            nl->next = first;
+            first->prev = nl;
+            return nl;
+        }
+    } else {
+        return ucx_list_append_a(alloc, NULL, data);
+    }
+}
+
 UcxList *ucx_list_concat(UcxList *l1, UcxList *l2) {
     if (l1) {
         UcxList *last = ucx_list_last(l1);

mercurial