implement cx_kv_list_insert()

Thu, 18 Sep 2025 00:36:42 +0200

author
Mike Becker <universe@uap-core.de>
date
Thu, 18 Sep 2025 00:36:42 +0200
changeset 1378
1b4fa55f7caa
parent 1377
1562bdf948da
child 1379
9ad4a7011528

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);

mercurial