implement cxKvListRemoveKey()

Wed, 17 Sep 2025 22:45:00 +0200

author
Mike Becker <universe@uap-core.de>
date
Wed, 17 Sep 2025 22:45:00 +0200
changeset 1377
1562bdf948da
parent 1376
0698e573936f
child 1378
1b4fa55f7caa

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

mercurial