ucx/list.c

changeset 750
4d7a2238c5ac
parent 748
49a284f61e8c
--- a/ucx/list.c	Sun May 21 11:52:06 2023 +0200
+++ b/ucx/list.c	Sun May 21 16:34:58 2023 +0200
@@ -195,34 +195,102 @@
 
 // </editor-fold>
 
+// <editor-fold desc="empty list implementation">
+
+static void cx_emptyl_noop(__attribute__((__unused__)) CxList *list) {
+    // this is a noop, but MUST be implemented
+}
+
+static void *cx_emptyl_at(
+        __attribute__((__unused__)) struct cx_list_s const *list,
+        __attribute__((__unused__)) size_t index
+) {
+    return NULL;
+}
+
+static ssize_t cx_emptyl_find(
+        __attribute__((__unused__)) struct cx_list_s const *list,
+        __attribute__((__unused__)) void const *elem
+) {
+    return -1;
+}
+
+static int cx_emptyl_compare(
+        __attribute__((__unused__)) struct cx_list_s const *list,
+        struct cx_list_s const *other
+) {
+    if (other->size == 0) return 0;
+    return -1;
+}
+
+static bool cx_emptyl_iter_valid(__attribute__((__unused__)) void const *iter) {
+    return false;
+}
+
+static CxIterator cx_emptyl_iterator(
+        struct cx_list_s const *list,
+        size_t index,
+        __attribute__((__unused__)) bool backwards
+) {
+    CxIterator iter = {0};
+    iter.src_handle = list;
+    iter.index = index;
+    iter.base.valid = cx_emptyl_iter_valid;
+    return iter;
+}
+
+static cx_list_class cx_empty_list_class = {
+        cx_emptyl_noop,
+        NULL,
+        NULL,
+        NULL,
+        NULL,
+        cx_emptyl_noop,
+        NULL,
+        cx_emptyl_at,
+        cx_emptyl_find,
+        cx_emptyl_noop,
+        cx_emptyl_compare,
+        cx_emptyl_noop,
+        cx_emptyl_iterator,
+};
+
+CxList cx_empty_list = {
+        NULL,
+        NULL,
+        0,
+        0,
+        NULL,
+        NULL,
+        NULL,
+        false,
+        &cx_empty_list_class,
+        NULL
+};
+
+CxList *const cxEmptyList = &cx_empty_list;
+
+// </editor-fold>
+
 void cxListDestroy(CxList *list) {
-    if (list->simple_destructor) {
-        CxIterator iter = cxListIterator(list);
-        cx_foreach(void*, elem, iter) {
-            // already correctly resolved pointer - immediately invoke dtor
-            list->simple_destructor(elem);
-        }
-    }
-    if (list->advanced_destructor) {
-        CxIterator iter = cxListIterator(list);
-        cx_foreach(void*, elem, iter) {
-            // already correctly resolved pointer - immediately invoke dtor
-            list->advanced_destructor(list->destructor_data, elem);
-        }
-    }
-
     list->cl->destructor(list);
-    cxFree(list->allocator, list);
 }
 
 int cxListCompare(
         CxList const *list,
         CxList const *other
 ) {
-    if ((list->store_pointer ^ other->store_pointer) ||
-        ((list->climpl == NULL) ^ (other->climpl != NULL)) ||
+    if (
+        // if one is storing pointers but the other is not
+        (list->store_pointer ^ other->store_pointer) ||
+
+        // if one class is wrapped but the other is not
+        ((list->climpl == NULL) ^ (other->climpl == NULL)) ||
+
+        // if the resolved compare functions are not the same
         ((list->climpl != NULL ? list->climpl->compare : list->cl->compare) !=
-         (other->climpl != NULL ? other->climpl->compare : other->cl->compare))) {
+         (other->climpl != NULL ? other->climpl->compare : other->cl->compare))
+    ) {
         // lists are definitely different - cannot use internal compare function
         if (list->size == other->size) {
             CxIterator left = cxListIterator(list);

mercurial