Thu, 18 Sep 2025 00:36:42 +0200
implement cx_kv_list_insert()
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 Wed Sep 17 22:45:00 2025 +0200 +++ b/src/cx/kv_list.h Thu Sep 18 00:36:42 2025 +0200 @@ -329,9 +329,9 @@ * @param key (@c CxHashKey, @c char*, @c cxstring, or @c cxmutstr) the key * @param value (@c void*) the value * @retval zero success - * @retval non-zero memory allocation failure or the index is out of bounds + * @retval non-zero memory allocation failure */ -#define cxKvListAdd(list, index, key, value) cxKvListInsert(list, list->collection.size, key, value) +#define cxKvListAdd(list, key, value) cxKvListInsert(list, (list)->collection.size, key, value) #ifdef __cplusplus } // extern "C"
--- a/src/kv_list.c Wed Sep 17 22:45:00 2025 +0200 +++ b/src/kv_list.c Thu Sep 18 00:36:42 2025 +0200 @@ -489,5 +489,26 @@ } int cx_kv_list_insert(CxList *list, size_t index, CxHashKey key, void *value) { - return -1; + cx_kv_list *kv_list = (cx_kv_list*)list; + + // add the new node via emplacement (we don't want to look up the node again) + void *node_data = cxListEmplaceAt(list, index); + if (node_data == NULL) return -1; // LCOV_EXCL_LINE + + // copy the data + if (list->collection.store_pointer) { + memcpy(node_data, &value, sizeof(void*)); + } else { + memcpy(node_data, value, kv_list->list.base.collection.elem_size); + } + + // add the key to the map + kv_list->map_methods->put(&kv_list->map->map_base.base, key, node_data); + // TODO: get rid of the node again, when adding the entry to the map failed + + // write the key to the node + CxHashKey *loc_key = cx_kv_list_loc_key(kv_list, node_data); + *loc_key = key; + + return 0; }
--- a/tests/test_kv_list.c Wed Sep 17 22:45:00 2025 +0200 +++ b/tests/test_kv_list.c Thu Sep 18 00:36:42 2025 +0200 @@ -386,6 +386,59 @@ cxListFree(list); } +CX_TEST(test_kv_list_insert_with_key) { + CxList *list = cxKvListCreateSimple(sizeof(int)); + int x; + CX_TEST_DO { + x = 47; + cxKvListAdd(list, "xyz", &x); + x = 11; + cxKvListAdd(list, "abc", &x); + x = 1337; + cxKvListInsert(list, 1, "efg", &x); + + CX_TEST_ASSERT(cxListSize(list) == 3); + CX_TEST_ASSERT(*(int*)cxListAt(list, 0) == 47); + CX_TEST_ASSERT(*(int*)cxListAt(list, 1) == 1337); + CX_TEST_ASSERT(*(int*)cxListAt(list, 2) == 11); + + CxMap *map = cxKvListAsMap(list); + CX_TEST_ASSERT(cxMapSize(map) == 3); + CX_TEST_ASSERT(*(int*)cxMapGet(map, "xyz") == 47); + CX_TEST_ASSERT(*(int*)cxMapGet(map, "abc") == 11); + CX_TEST_ASSERT(*(int*)cxMapGet(map, "efg") == 1337); + } + cxListFree(list); +} + +CX_TEST(test_kv_list_insert_ptr_with_key) { + CxList *list = cxKvListCreateSimple(CX_STORE_POINTERS); + int x, y, z; + CX_TEST_DO { + x = 15; + cxKvListAdd(list, "xyz", &x); + y = 16; + cxKvListAdd(list, "abc", &y); + z = 17; + cxKvListInsert(list, 1, "efg", &z); + x = 47; + y = 11; + z = 1337; + + CX_TEST_ASSERT(cxListSize(list) == 3); + CX_TEST_ASSERT(*(int*)cxListAt(list, 0) == 47); + CX_TEST_ASSERT(*(int*)cxListAt(list, 1) == 1337); + CX_TEST_ASSERT(*(int*)cxListAt(list, 2) == 11); + + CxMap *map = cxKvListAsMap(list); + CX_TEST_ASSERT(cxMapSize(map) == 3); + CX_TEST_ASSERT(*(int*)cxMapGet(map, "xyz") == 47); + CX_TEST_ASSERT(*(int*)cxMapGet(map, "abc") == 11); + CX_TEST_ASSERT(*(int*)cxMapGet(map, "efg") == 1337); + } + cxListFree(list); +} + CX_TEST(test_kv_list_insert_array_and_set_keys) { CxList *list = cxKvListCreateSimple(sizeof(int)); CX_TEST_DO { @@ -570,6 +623,8 @@ 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_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); cx_test_register(suite, test_kv_list_list_remove_destr_in_list); cx_test_register(suite, test_kv_list_list_remove_destr_in_map);