Wed, 17 Sep 2025 22:45:00 +0200
implement cxKvListRemoveKey()
relates to #461
src/cx/kv_list.h | file | annotate | diff | comparison | revisions | |
src/kv_list.c | file | annotate | diff | comparison | revisions | |
tests/test_kv_list.c | file | annotate | diff | comparison | revisions |
--- a/src/cx/kv_list.h Tue Sep 16 22:32:23 2025 +0200 +++ b/src/cx/kv_list.h Wed Sep 17 22:45:00 2025 +0200 @@ -213,27 +213,6 @@ } cx_attr_nonnull -static inline int cxKvListRemoveKey(CxList *list, size_t index, CxHashKey key) { - return cx_kv_list_remove_key(list, index, key); -} - -cx_attr_nonnull -static inline int cxKvListRemoveKey(CxList *list, size_t index, cxstring key) { - return cx_kv_list_remove_key(list, index, cx_hash_key_cxstr(key)); -} - -cx_attr_nonnull -static inline int cxKvListRemoveKey(CxList *list, size_t index, cxmutstr key) { - return cx_kv_list_remove_key(list, index, cx_hash_key_cxstr(key)); -} - -cx_attr_nonnull -cx_attr_cstr_arg(3) -static inline int cxKvListRemoveKey(CxList *list, size_t index, const char *key) { - return cx_kv_list_remove_key(list, index, cx_hash_key_str(key)); -} - -cx_attr_nonnull static inline int cxKvListInsert(CxList *list, size_t index, CxHashKey key, void *value) { return cx_kv_list_insert(list, index, key, value); } @@ -292,40 +271,20 @@ } /** - * Removes the key for a list item. + * Removes the key of a list item. + * + * This can be useful if you want to explicitly remove an item from the lookup map. * - * This can be useful if you want to explicitly remove an item from the lookup map, - * for example, when you want to prevent a deletion by cxMapClear(). + * If no key is associated with the item, nothing happens, and this function returns zero. * - * @param list (@c CxList*) the list - * @param index (@c size_t) the index of the element in the list - * @param key (@c CxHashKey, @c char*, @c cxstring, or @c cxmutstr) the key + * @param list the list + * @param index the index of the element in the list * @retval zero success * @retval non-zero the index is out of bounds */ -#define cxKvListRemoveKey(list, index, key) _Generic((key), \ - CxHashKey: cx_kv_list_remove_key, \ - cxstring: cx_kv_list_remove_key_cxstr, \ - cxmutstr: cx_kv_list_remove_key_mustr, \ - char*: cx_kv_list_remove_key_str, \ - const char*: cx_kv_list_remove_key_str) \ - (list, index, key) - cx_attr_nonnull -static inline int cx_kv_list_remove_key_cxstr(CxList *list, size_t index, cxstring key) { - return cx_kv_list_remove_key(list, index, cx_hash_key_cxstr(key)); -} - -cx_attr_nonnull -static inline int cx_kv_list_remove_key_mustr(CxList *list, size_t index, cxmutstr key) { - return cx_kv_list_remove_key(list, index, cx_hash_key_cxstr(key)); -} - -cx_attr_nonnull -cx_attr_cstr_arg(3) -static inline int cx_kv_list_remove_key_str(CxList *list, size_t index, const char *key) { - return cx_kv_list_remove_key(list, index, cx_hash_key_str(key)); -} +cx_attr_export +int cxKvListRemoveKey(CxList *list, size_t index); /** * Inserts an item into the list at the specified index and associates it with the specified key.
--- a/src/kv_list.c Tue Sep 16 22:32:23 2025 +0200 +++ b/src/kv_list.c Wed Sep 17 22:45:00 2025 +0200 @@ -471,8 +471,21 @@ return 0; } -int cx_kv_list_remove_key(CxList *list, size_t index, CxHashKey key) { - return -1; +int cxKvListRemoveKey(CxList *list, size_t index) { + cx_kv_list *kv_list = (cx_kv_list*)list; + void *node_data = kv_list->list_methods->at(list, index); + if (node_data == NULL) { + return 1; + } + CxHashKey *loc_key = cx_kv_list_loc_key(kv_list, node_data); + if (loc_key->hash == 0) { + return 0; + } + kv_list->map_methods->remove(&kv_list->map->map_base.base, *loc_key, NULL); + // also zero the memory in the list node, + // but don't free the key data (that was done by the map remove) + memset(loc_key, 0, sizeof(CxHashKey)); + return 0; } int cx_kv_list_insert(CxList *list, size_t index, CxHashKey key, void *value) {
--- a/tests/test_kv_list.c Tue Sep 16 22:32:23 2025 +0200 +++ b/tests/test_kv_list.c Wed Sep 17 22:45:00 2025 +0200 @@ -350,6 +350,42 @@ cxListFree(list); } +CX_TEST(test_kv_list_remove_key) { + CxList *list = cxKvListCreateSimple(sizeof(int)); + int x; + CX_TEST_DO { + CxMap *map = cxKvListAsMap(list); + + x = 47; + cxMapPut(map, "xyz", &x); + x = 11; + cxMapPut(map, "abc", &x); + x = 1337; + cxMapPut(map, "efg", &x); + CX_TEST_ASSERT(cxMapSize(map) == 3); + + int *y = cxMapGet(map, "abc"); + CX_TEST_ASSERT(y != NULL); + CX_TEST_ASSERT(*y == 11); + + cxKvListRemoveKey(list, 1); + CX_TEST_ASSERT(cxMapGet(map, "abc") == NULL); + CX_TEST_ASSERT(cxMapSize(map) == 2); + CX_TEST_ASSERT(cxListSize(list) == 3); + + CX_TEST_ASSERT(*(int*)cxListAt(list, 1) == 11); + + y = cxMapGet(map, "xyz"); + CX_TEST_ASSERT(y != NULL); + CX_TEST_ASSERT(*y == 47); + + y = cxMapGet(map, "efg"); + CX_TEST_ASSERT(y != NULL); + CX_TEST_ASSERT(*y == 1337); + } + cxListFree(list); +} + CX_TEST(test_kv_list_insert_array_and_set_keys) { CxList *list = cxKvListCreateSimple(sizeof(int)); CX_TEST_DO { @@ -533,6 +569,7 @@ cx_test_register(suite, test_kv_list_map_put_ptr); cx_test_register(suite, test_kv_list_map_remove); cx_test_register(suite, test_kv_list_set_key); + cx_test_register(suite, test_kv_list_remove_key); cx_test_register(suite, test_kv_list_insert_array_and_set_keys); cx_test_register(suite, test_kv_list_list_remove_destr_in_list); cx_test_register(suite, test_kv_list_list_remove_destr_in_map);