add high level list sort and inlines method invocation functions

Wed, 06 Oct 2021 14:10:19 +0200

author
Mike Becker <universe@uap-core.de>
date
Wed, 06 Oct 2021 14:10:19 +0200
changeset 469
0458bff0b1cd
parent 468
75ae1dccd101
child 470
e5a4de4f1e03

add high level list sort and inlines method invocation functions

src/CMakeLists.txt file | annotate | diff | comparison | revisions
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
test/test_list.c file | annotate | diff | comparison | revisions
--- a/src/CMakeLists.txt	Tue Oct 05 16:33:11 2021 +0200
+++ b/src/CMakeLists.txt	Wed Oct 06 14:10:19 2021 +0200
@@ -1,6 +1,5 @@
 set(sources
         allocator.c
-        list.c
         linked_list.c
         tree.c
 )
--- a/src/cx/list.h	Tue Oct 05 16:33:11 2021 +0200
+++ b/src/cx/list.h	Wed Oct 06 14:10:19 2021 +0200
@@ -87,6 +87,11 @@
      * Member function for retrieving the last element.
      */
     void *(*last)(cx_list_s *list);
+
+    /**
+     * Member function for sorting the list in place.
+     */
+    void (*sort)(cx_list_s *list);
 } cx_list_class;
 
 /**
@@ -136,7 +141,9 @@
  * @param elem a pointer to the element to add
  * @return zero on success, non-zero on memory allocation failure
  */
-int cxListAdd(CxList list, void *elem);
+static inline int cxListAdd(CxList list, void *elem) {
+    return list->cl->add(list, elem);
+}
 
 /**
  * Inserts an item at the specified index.
@@ -154,7 +161,9 @@
  * @return zero on success, non-zero on memory allocation failure
  * or when the index is out of bounds
  */
-int cxListInsert(CxList list, size_t index, void *elem);
+static inline int cxListInsert(CxList list, size_t index, void *elem) {
+    return list->cl->insert(list, index, elem);
+}
 
 /**
  * Removes the element at the specified index.
@@ -162,7 +171,9 @@
  * @param index the index of the element
  * @return zero on success, non-zero if the index is out of bounds
  */
-int cxListRemove(CxList list, size_t index);
+static inline int cxListRemove(CxList list, size_t index) {
+    return list->cl->remove(list, index);
+}
 
 /**
  * Returns a pointer to the element at the specified index.
@@ -171,7 +182,9 @@
  * @param index the index of the element
  * @return a pointer to the element or \c NULL if the index is out of bounds
  */
-void *cxListAt(CxList list, size_t index);
+static inline void *cxListAt(CxList list, size_t index) {
+    return list->cl->at(list, index);
+}
 
 /**
  * Returns the index of the first element that equals \p elem.
@@ -182,7 +195,9 @@
  * @param elem the element to find
  * @return the index of the element or \c (size+1) if the element is not found
  */
-size_t cxListFind(CxList list, void *elem);
+static inline size_t cxListFind(CxList list, void *elem) {
+    return list->cl->find(list, elem);
+}
 
 /**
  * Returns a pointer to the last element of the list.
@@ -194,7 +209,20 @@
  * @param list the list
  * @return a pointer to the last element or \c NULL if the list is empty
  */
-void *cxListLast(CxList list);
+static inline void *cxListLast(CxList list) {
+    return list->cl->last(list);
+}
+
+/**
+ * Sorts the list in place.
+ *
+ * \remark The underlying sort algorithm is implementation defined.
+ *
+ * @param list the list
+ */
+static inline void cxListSort(CxList list) {
+    list->cl->sort(list);
+}
 
 #ifdef __cplusplus
 } /* extern "C" */
--- a/src/linked_list.c	Tue Oct 05 16:33:11 2021 +0200
+++ b/src/linked_list.c	Wed Oct 06 14:10:19 2021 +0200
@@ -212,6 +212,7 @@
 
 #define CX_LL_LOC_PREV offsetof(cx_linked_list_node, prev)
 #define CX_LL_LOC_NEXT offsetof(cx_linked_list_node, next)
+#define CX_LL_LOC_DATA offsetof(cx_linked_list_node, payload)
 
 typedef struct {
     cx_list_s base;
@@ -380,13 +381,28 @@
     return last == NULL ? NULL : *(void **) last->payload;
 }
 
+static void cx_ll_sort(cx_list_s *list) {
+    cx_linked_list *ll = (cx_linked_list *) list;
+    cx_linked_list_sort((void **) &ll->begin, (void **) &ll->end,
+                        CX_LL_LOC_PREV, CX_LL_LOC_NEXT, CX_LL_LOC_DATA,
+                        0, list->cmpfunc);
+}
+
+static void cx_pll_sort(cx_list_s *list) {
+    cx_linked_list *ll = (cx_linked_list *) list;
+    cx_linked_list_sort((void **) &ll->begin, (void **) &ll->end,
+                        CX_LL_LOC_PREV, CX_LL_LOC_NEXT, CX_LL_LOC_DATA,
+                        1, list->cmpfunc);
+}
+
 static cx_list_class cx_linked_list_class = {
         cx_ll_add,
         cx_ll_insert,
         cx_ll_remove,
         cx_ll_at,
         cx_ll_find,
-        cx_ll_last
+        cx_ll_last,
+        cx_ll_sort
 };
 
 static cx_list_class cx_pointer_linked_list_class = {
@@ -395,7 +411,8 @@
         cx_ll_remove,
         cx_pll_at,
         cx_pll_find,
-        cx_pll_last
+        cx_pll_last,
+        cx_pll_sort
 };
 
 CxList cxLinkedListCreate(CxAllocator allocator, CxListComparator comparator, size_t item_size) {
--- a/src/list.c	Tue Oct 05 16:33:11 2021 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,53 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2021 Mike Becker, 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:
- *
- *   1. Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *
- *   2. Redistributions in binary form must reproduce the above copyright
- *      notice, this list of conditions and the following disclaimer in the
- *      documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "cx/list.h"
-
-int cxListAdd(CxList list, void *elem) {
-    return list->cl->add(list, elem);
-}
-
-int cxListInsert(CxList list, size_t index, void *elem) {
-    return list->cl->insert(list, index, elem);
-}
-
-int cxListRemove(CxList list, size_t index) {
-    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);
-}
-
-void *cxListLast(CxList list) {
-    return list->cl->last(list);
-}
--- a/test/test_list.c	Tue Oct 05 16:33:11 2021 +0200
+++ b/test/test_list.c	Wed Oct 06 14:10:19 2021 +0200
@@ -393,6 +393,42 @@
     CU_ASSERT_TRUE(cxTestingAllocatorVerify())
 }
 
+void test_hl_linked_list_sort(void) {
+    int expected[] = {
+            14, 30, 151, 163, 227, 300, 315, 317, 363, 398, 417, 424, 438, 446, 508, 555, 605, 713, 716, 759, 761, 880,
+            894, 1034, 1077, 1191, 1231, 1264, 1297, 1409, 1423, 1511, 1544, 1659, 1686, 1707, 1734, 1771, 1874, 1894,
+            1976, 2079, 2124, 2130, 2135, 2266, 2338, 2358, 2430, 2500, 2540, 2542, 2546, 2711, 2733, 2754, 2764, 2797,
+            2888, 2900, 3020, 3053, 3109, 3244, 3275, 3302, 3362, 3363, 3364, 3441, 3515, 3539, 3579, 3655, 3675, 3677,
+            3718, 3724, 3757, 3866, 3896, 3906, 3941, 3984, 3994, 4016, 4085, 4121, 4254, 4319, 4366, 4459, 4514, 4681,
+            4785, 4791, 4801, 4859, 4903, 4973
+    };
+    int scrambled[] = {
+            759, 716, 880, 761, 2358, 2542, 2500, 2540, 2546, 2711, 2430, 1707, 1874, 1771, 1894, 1734, 1976, 2079,
+            2124, 2130, 2135, 2266, 2338, 2733, 2754, 2764, 2797, 3362, 3363, 3364, 3441, 3515, 3539, 3579, 3655, 2888,
+            2900, 3020, 3053, 3109, 3244, 3275, 3302, 438, 446, 508, 555, 605, 713, 14, 30, 151, 163, 227, 300,
+            894, 1034, 1077, 1191, 1231, 1264, 1297, 1409, 1423, 1511, 1544, 1659, 1686, 315, 317, 363, 398, 417, 424,
+            3675, 3677, 3718, 3724, 3757, 3866, 3896, 3906, 3941, 3984, 3994, 4785, 4791, 4801, 4859, 4903, 4973,
+            4016, 4085, 4121, 4254, 4319, 4366, 4459, 4514, 4681
+    };
+
+    cxTestingAllocatorReset();
+
+    CxList list = cxLinkedListCreate(cxTestingAllocator, (CxListComparator) cmp_int, sizeof(int));
+
+    for (int i = 0 ; i < 100 ; i++) {
+        cxListAdd(list, &scrambled[i]);
+    }
+
+    cxListSort(list);
+
+    for (int i = 0 ; i < 100 ; i++) {
+        CU_ASSERT_EQUAL(*(int*)cxListAt(list, i), expected[i])
+    }
+
+    cxLinkedListDestroy(list);
+    CU_ASSERT_TRUE(cxTestingAllocatorVerify())
+}
+
 void test_hl_ptr_linked_list_create(void) {
     cxTestingAllocatorReset();
 
@@ -558,6 +594,42 @@
     CU_ASSERT_TRUE(cxTestingAllocatorVerify())
 }
 
+void test_hl_ptr_linked_list_sort(void) {
+    int expected[] = {
+            14, 30, 151, 163, 227, 300, 315, 317, 363, 398, 417, 424, 438, 446, 508, 555, 605, 713, 716, 759, 761, 880,
+            894, 1034, 1077, 1191, 1231, 1264, 1297, 1409, 1423, 1511, 1544, 1659, 1686, 1707, 1734, 1771, 1874, 1894,
+            1976, 2079, 2124, 2130, 2135, 2266, 2338, 2358, 2430, 2500, 2540, 2542, 2546, 2711, 2733, 2754, 2764, 2797,
+            2888, 2900, 3020, 3053, 3109, 3244, 3275, 3302, 3362, 3363, 3364, 3441, 3515, 3539, 3579, 3655, 3675, 3677,
+            3718, 3724, 3757, 3866, 3896, 3906, 3941, 3984, 3994, 4016, 4085, 4121, 4254, 4319, 4366, 4459, 4514, 4681,
+            4785, 4791, 4801, 4859, 4903, 4973
+    };
+    int scrambled[] = {
+            759, 716, 880, 761, 2358, 2542, 2500, 2540, 2546, 2711, 2430, 1707, 1874, 1771, 1894, 1734, 1976, 2079,
+            2124, 2130, 2135, 2266, 2338, 2733, 2754, 2764, 2797, 3362, 3363, 3364, 3441, 3515, 3539, 3579, 3655, 2888,
+            2900, 3020, 3053, 3109, 3244, 3275, 3302, 438, 446, 508, 555, 605, 713, 14, 30, 151, 163, 227, 300,
+            894, 1034, 1077, 1191, 1231, 1264, 1297, 1409, 1423, 1511, 1544, 1659, 1686, 315, 317, 363, 398, 417, 424,
+            3675, 3677, 3718, 3724, 3757, 3866, 3896, 3906, 3941, 3984, 3994, 4785, 4791, 4801, 4859, 4903, 4973,
+            4016, 4085, 4121, 4254, 4319, 4366, 4459, 4514, 4681
+    };
+
+    cxTestingAllocatorReset();
+
+    CxList list = cxPointerLinkedListCreate(cxTestingAllocator, (CxListComparator) cmp_int);
+
+    for (int i = 0 ; i < 100 ; i++) {
+        cxListAdd(list, &scrambled[i]);
+    }
+
+    cxListSort(list);
+
+    for (int i = 0 ; i < 100 ; i++) {
+        CU_ASSERT_EQUAL(*(int*)cxListAt(list, i), expected[i])
+    }
+
+    cxLinkedListDestroy(list);
+    CU_ASSERT_TRUE(cxTestingAllocatorVerify())
+}
+
 int main() {
     CU_pSuite suite = NULL;
 
@@ -581,6 +653,7 @@
     cu_add_test(suite, test_hl_linked_list_insert);
     cu_add_test(suite, test_hl_linked_list_remove);
     cu_add_test(suite, test_hl_linked_list_find);
+    cu_add_test(suite, test_hl_linked_list_sort);
 
     suite = CU_add_suite("high level pointer linked list", NULL, NULL);
 
@@ -590,6 +663,7 @@
     cu_add_test(suite, test_hl_ptr_linked_list_insert);
     cu_add_test(suite, test_hl_ptr_linked_list_remove);
     cu_add_test(suite, test_hl_ptr_linked_list_find);
+    cu_add_test(suite, test_hl_ptr_linked_list_sort);
 
     CU_basic_set_mode(UCX_CU_BRM);
 

mercurial