adds cxListSet() - resolves #642

Sun, 13 Apr 2025 11:09:05 +0200

author
Mike Becker <universe@uap-core.de>
date
Sun, 13 Apr 2025 11:09:05 +0200
changeset 1287
3a3ffc27813f
parent 1286
5492e8ef05f4
child 1288
b41ad5d9bcbf

adds cxListSet() - resolves #642

CHANGELOG file | annotate | diff | comparison | revisions
docs/Writerside/topics/about.md file | annotate | diff | comparison | revisions
docs/Writerside/topics/list.h.md file | annotate | diff | comparison | revisions
src/cx/list.h file | annotate | diff | comparison | revisions
src/list.c file | annotate | diff | comparison | revisions
tests/test_list.c file | annotate | diff | comparison | revisions
--- a/CHANGELOG	Sat Apr 12 21:32:31 2025 +0200
+++ b/CHANGELOG	Sun Apr 13 11:09:05 2025 +0200
@@ -2,6 +2,7 @@
 ------------------------
 
  * adds cxMempoolTransfer() and cxMempoolTransferObject()
+ * adds cxListSet()
  * changes grow strategy for the mempory pool to reduce reallocations
  * fixes implementation of cxBufferTerminate()
  * fixes allocator arguments for some printf.h functions not being const
--- a/docs/Writerside/topics/about.md	Sat Apr 12 21:32:31 2025 +0200
+++ b/docs/Writerside/topics/about.md	Sun Apr 13 11:09:05 2025 +0200
@@ -29,6 +29,7 @@
 ### Version 3.2 - preview {collapsible="true"}
 
 * adds cxMempoolTransfer() and cxMempoolTransferObject()
+* adds cxListSet()
 * changes grow strategy for the mempory pool to reduce reallocations
 * fixes implementation of cxBufferTerminate()
 * fixes allocator arguments for some printf.h functions not being const
--- a/docs/Writerside/topics/list.h.md	Sat Apr 12 21:32:31 2025 +0200
+++ b/docs/Writerside/topics/list.h.md	Sun Apr 13 11:09:05 2025 +0200
@@ -162,6 +162,8 @@
 
 void *cxListAt(const CxList *list, size_t index);
 
+int cxListSet(CxList *list, size_t index, const void *elem);
+
 size_t cxListFind(const CxList *list, const void *elem);
 
 size_t cxListFindRemove(CxList *list, const void *elem);
@@ -176,6 +178,12 @@
 Otherwise, a pointer to element at the specified index is returned.
 If the index is out-of-bounds, the function returns `NULL`.
 
+The function `cxListSet()` allows you to modify elements at a specific index in the list.
+This function replaces the element at the specified `index` with the value pointed to by `elem`.
+If the list is storing values directly (not pointers), the contents at the memory location `elem` will be copied into the list.
+If the list is storing pointers, the pointer value itself will be stored.
+The function returns `0` on success and `1` if the index is out of bounds.
+
 On the other hand, `cxListFind()` searches for the element pointed to by `elem` by comparing each element in the list with the list`s compare function,
 and returns the first index when the element was found.
 Otherwise, the function returns the list size.
--- a/src/cx/list.h	Sat Apr 12 21:32:31 2025 +0200
+++ b/src/cx/list.h	Sun Apr 13 11:09:05 2025 +0200
@@ -689,6 +689,23 @@
     return list->cl->at(list, index);
 }
 
+
+/**
+ * Sets the element at the specified index in the list
+ *
+ * @param list the list to set the element in
+ * @param index the index to set the element at
+ * @param elem element to set
+ * @retval zero on success
+ * @retval non-zero when index is out of bounds
+ */
+cx_attr_nonnull
+int cxListSet(
+        CxList *list,
+        size_t index,
+        const void *elem
+);
+
 /**
  * Returns an iterator pointing to the item at the specified index.
  *
--- a/src/list.c	Sat Apr 12 21:32:31 2025 +0200
+++ b/src/list.c	Sun Apr 13 11:09:05 2025 +0200
@@ -494,3 +494,24 @@
     if (list == NULL) return;
     list->cl->deallocate(list);
 }
+
+int cxListSet(
+        CxList *list,
+        size_t index,
+        const void *elem
+) {
+    if (index >= list->collection.size) {
+        return 1;
+    }
+
+    if (list->collection.store_pointer) {
+        // For pointer collections, always use climpl
+        void **target = list->climpl->at(list, index);
+        *target = (void *)elem;
+    } else {
+        void *target = list->cl->at(list, index);
+        memcpy(target, elem, list->collection.elem_size);
+    }
+
+    return 0;
+}
--- a/tests/test_list.c	Sat Apr 12 21:32:31 2025 +0200
+++ b/tests/test_list.c	Sun Apr 13 11:09:05 2025 +0200
@@ -1628,6 +1628,30 @@
     free(testdata);
 })
 
+roll_out_test_combos(set, {
+    // Add some values
+    int v1 = 42;
+    cxListAdd(list, &v1);
+    int v2 = 100;
+    cxListAdd(list, &v2);
+    int v3 = 47;
+    cxListAdd(list, &v3);
+
+    // Change the first element
+    int v1new = 99;
+    CX_TEST_ASSERT(cxListSet(list, 0, &v1new) == 0);
+    CX_TEST_ASSERT(*(int *) cxListAt(list, 0) == 99);
+
+    // Change the last element
+    int v3new = 101;
+    CX_TEST_ASSERT(cxListSet(list, 2, &v3new) == 0);
+    CX_TEST_ASSERT(*(int *) cxListAt(list, 2) == 101);
+
+    // Try index out of bounds
+    int oob = 1337;
+    CX_TEST_ASSERT(cxListSet(list, 3, &oob) != 0);
+})
+
 roll_out_test_combos_with_defaulted_funcs(swap, {
     int original[16] = array_init(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
     int swapped[16] = array_init(8, 4, 14, 3, 1, 5, 9, 12, 0, 6, 11, 10, 7, 15, 2, 13);
@@ -1981,6 +2005,8 @@
     cx_test_register(suite, test_list_parl_clear);
     cx_test_register(suite, test_list_arl_at);
     cx_test_register(suite, test_list_parl_at);
+    cx_test_register(suite, test_list_arl_set);
+    cx_test_register(suite, test_list_parl_set);
     cx_test_register(suite, test_list_arl_swap);
     cx_test_register(suite, test_list_parl_swap);
     cx_test_register(suite, test_list_arl_swap_no_sbo);
@@ -2080,6 +2106,8 @@
     cx_test_register(suite, test_list_pll_clear);
     cx_test_register(suite, test_list_ll_at);
     cx_test_register(suite, test_list_pll_at);
+    cx_test_register(suite, test_list_ll_set);
+    cx_test_register(suite, test_list_pll_set);
     cx_test_register(suite, test_list_ll_swap);
     cx_test_register(suite, test_list_pll_swap);
     cx_test_register(suite, test_list_ll_find);

mercurial