Sun, 13 Apr 2025 11:09:05 +0200
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);