add high-level function cxListAt()

Mon, 27 Sep 2021 18:50:07 +0200

author
Mike Becker <universe@uap-core.de>
date
Mon, 27 Sep 2021 18:50:07 +0200
changeset 439
9a5adedd6de6
parent 438
cd3069757010
child 440
003aa0a78e1e

add high-level function cxListAt()

src/cx/list.h file | annotate | diff | comparison | revisions
src/linked_list.c file | annotate | diff | comparison | revisions
src/list.c file | annotate | diff | comparison | revisions
--- a/src/cx/list.h	Mon Sep 27 18:33:30 2021 +0200
+++ b/src/cx/list.h	Mon Sep 27 18:50:07 2021 +0200
@@ -47,6 +47,8 @@
 
     int (*remove)(cx_list_s *list, size_t index);
 
+    void *(*at)(cx_list_s *list, size_t index);
+
     size_t (*find)(cx_list_s *list, void *elem);
 
     void *(*last)(cx_list_s *list);
@@ -69,6 +71,8 @@
 
 int cxListRemove(CxList list, size_t index);
 
+void *cxListAt(CxList list, size_t index);
+
 size_t cxListFind(CxList list, void *elem);
 
 void *cxListLast(CxList list);
--- a/src/linked_list.c	Mon Sep 27 18:33:30 2021 +0200
+++ b/src/linked_list.c	Mon Sep 27 18:50:07 2021 +0200
@@ -99,6 +99,9 @@
     char payload[];
 };
 
+#define CX_LL_LOC_PREV offsetof(struct cx_linked_list_node, prev)
+#define CX_LL_LOC_NEXT offsetof(struct cx_linked_list_node, next)
+
 typedef struct {
     cx_list_s base;
     void *begin;
@@ -120,8 +123,7 @@
 
     int ret = cx_linked_list_add(
             &ll->begin, &ll->end,
-            offsetof(struct cx_linked_list_node, prev),
-            offsetof(struct cx_linked_list_node, next),
+            CX_LL_LOC_PREV, CX_LL_LOC_NEXT,
             node
     );
     if (ret == 0) {
@@ -147,6 +149,17 @@
     return 0;
 }
 
+static void *cx_ll_at(cx_list_s *list, size_t index) {
+    cx_linked_list *ll = (cx_linked_list *) list;
+    struct cx_linked_list_node *node;
+    if (index > list->size / 2) {
+        node = cx_linked_list_at(ll->begin, 0, CX_LL_LOC_NEXT, index);
+    } else {
+        node = cx_linked_list_at(ll->end, list->size, CX_LL_LOC_PREV, index);
+    }
+    return &node->payload;
+}
+
 static size_t cx_ll_find(cx_list_s *list, void *elem) {
     CxListComparator cmp = list->cmpfunc;
     cx_linked_list *ll = (cx_linked_list *) list;
@@ -164,9 +177,8 @@
 }
 
 static void *cx_ll_last(cx_list_s *list) {
-    cx_linked_list *linkedList = (cx_linked_list *) list;
-    struct cx_linked_list_node *last = cx_linked_list_last(
-            NULL, &linkedList->end, offsetof(struct cx_linked_list_node, next));
+    cx_linked_list *ll = (cx_linked_list *) list;
+    struct cx_linked_list_node *last = cx_linked_list_last(NULL, &ll->end, CX_LL_LOC_NEXT);
     return &last->payload;
 }
 
@@ -174,6 +186,7 @@
         cx_ll_add,
         cx_ll_insert,
         cx_ll_remove,
+        cx_ll_at,
         cx_ll_find,
         cx_ll_last
 };
@@ -190,8 +203,8 @@
     list->base.capacity = SIZE_MAX;
 
     list->begin = NULL;
-    list->loc_prev = offsetof(struct cx_linked_list_node, prev);
-    list->loc_next = offsetof(struct cx_linked_list_node, next);
+    list->loc_prev = CX_LL_LOC_PREV;
+    list->loc_next = CX_LL_LOC_NEXT;
 
     CxList result = (CxList) list;
     cxLinkedListRecalculateSize(result);
--- a/src/list.c	Mon Sep 27 18:33:30 2021 +0200
+++ b/src/list.c	Mon Sep 27 18:50:07 2021 +0200
@@ -40,6 +40,10 @@
     return list->cl->remove(list, index);
 }
 
+void *cxListAt(CxList list, size_t index) {
+    return list->cl->at(list, index);
+}
+
 size_t cxListFind(CxList list, void *elem) {
     return list->cl->find(list, elem);
 }

mercurial