Thu, 25 Sep 2025 14:30:28 +0200
add cxKvListGetKey()
resolves #461
--- a/docs/Writerside/topics/kv_list.h.md Wed Sep 24 23:52:36 2025 +0200 +++ b/docs/Writerside/topics/kv_list.h.md Thu Sep 25 14:30:28 2025 +0200 @@ -58,6 +58,8 @@ int cxKvListRemoveKey(CxList *list, size_t index); +const CxHashKey *cxKvListGetKey(CxList *list, size_t index); + int cxKvListAdd(CxList *list, KeyType key, void *value); int cxKvListInsert(CxList *list, size_t index, @@ -73,6 +75,8 @@ They return zero on success and non-zero on failure. A failure can happen when the index is out of bounds or when a memory allocation failed. The `cxKvListSetKey()` function also returns non-zero if the key already exists for _another_ element. +With `cxKvListGetKey()`, you can retrieve the key of an element. +This function returns `NULL` when an element has no key assigned or the index is out of bounds. With the `cxKvListAdd()` and `cxKvListInsert()` functions, you can add a new element to the list and immediately assign a key to it. The `cxKvListAdd()` function will add the element at the end of the list,
--- a/src/cx/kv_list.h Wed Sep 24 23:52:36 2025 +0200 +++ b/src/cx/kv_list.h Thu Sep 25 14:30:28 2025 +0200 @@ -283,6 +283,17 @@ int cxKvListRemoveKey(CxList *list, size_t index); /** + * Returns the key of a list item. + * + * @param list the list + * @param index the index of the element in the list + * @return a pointer to the key or @c NULL when the index is out of bounds or the item does not have a key + */ +cx_attr_nonnull +cx_attr_export +const CxHashKey *cxKvListGetKey(CxList *list, size_t index); + +/** * Inserts an item into the list at the specified index and associates it with the specified key. * * @param list (@c CxList*) the list
--- a/src/kv_list.c Wed Sep 24 23:52:36 2025 +0200 +++ b/src/kv_list.c Thu Sep 25 14:30:28 2025 +0200 @@ -649,6 +649,19 @@ return 0; } +const CxHashKey *cxKvListGetKey(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 NULL; + } + CxHashKey *key = cx_kv_list_loc_key(kv_list, node_data); + if (key->hash == 0) { + return NULL; + } + return key; +} + int cx_kv_list_insert(CxList *list, size_t index, CxHashKey key, void *value) { // assume we are losing the sorted property list->collection.sorted = false;
--- a/tests/test_kv_list.c Wed Sep 24 23:52:36 2025 +0200 +++ b/tests/test_kv_list.c Thu Sep 25 14:30:28 2025 +0200 @@ -542,6 +542,40 @@ cxListFree(list); } +CX_TEST(test_kv_list_get_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); + + const CxHashKey *key = cxKvListGetKey(list, 1); + int *y = cxMapGet(map, *key); + CX_TEST_ASSERT(y != NULL); + CX_TEST_ASSERT(*y == 11); + + // removing the element + CX_TEST_ASSERT(0 == cxMapRemove(map, cx_strn(key->data, key->len))); + key = cxKvListGetKey(list, 1); + CX_TEST_ASSERT(0 == cx_strcmp(CX_STR("efg"), cx_strn(key->data, key->len))); + + // remove the key of element + CX_TEST_ASSERT(0 == cxKvListRemoveKey(list, 1)); + CX_TEST_ASSERT(NULL == cxKvListGetKey(list, 1)); + + // index out of bounds: + CX_TEST_ASSERT(NULL == cxKvListGetKey(list, 3)); + } + cxListFree(list); +} + CX_TEST(test_kv_list_insert_with_key) { CxList *list = cxKvListCreateSimple(sizeof(int)); int x; @@ -993,6 +1027,7 @@ cx_test_register(suite, test_kv_list_set_key_already_exists); cx_test_register(suite, test_kv_list_set_key_again); cx_test_register(suite, test_kv_list_remove_key); + cx_test_register(suite, test_kv_list_get_key); cx_test_register(suite, test_kv_list_insert_with_key); cx_test_register(suite, test_kv_list_insert_ptr_with_key); cx_test_register(suite, test_kv_list_insert_array_and_set_keys);