ucx/map.c

branch
dav-2
changeset 891
4d58cbcc9efa
parent 889
42cdbf9bbd49
--- a/ucx/map.c	Sun Dec 07 20:16:59 2025 +0100
+++ b/ucx/map.c	Fri Dec 19 17:53:18 2025 +0100
@@ -70,12 +70,14 @@
 CxMap cx_empty_map = {
     {
         NULL,
-        NULL,
         0,
         0,
         NULL,
         NULL,
         NULL,
+        NULL,
+        NULL,
+        NULL,
         false,
         true
     },
@@ -110,11 +112,13 @@
 }
 
 int cx_map_put(CxMap *map, CxHashKey key, void *value) {
-    return map->cl->put(map, key, value) == NULL;
+    return map->cl->put(map, key, value).key == NULL;
 }
 
 void *cx_map_emplace(CxMap *map, CxHashKey key) {
-    return map->cl->put(map, key, NULL);
+    const CxMapEntry entry = map->cl->put(map, key, NULL);
+    if (entry.key == NULL) return NULL;
+    return entry.value;
 }
 
 void *cx_map_get(const CxMap *map, CxHashKey key) {
@@ -140,6 +144,15 @@
     map->collection.advanced_destructor = destr2_bak;
 }
 
+static void* cx_map_shallow_clone_func(void *dst, const void *src, const CxAllocator *al, void *data) {
+    size_t elem_size = *(size_t*)data;
+    if (dst == NULL) dst = cxMalloc(al, elem_size);
+    if (dst != NULL) memcpy(dst, src, elem_size);
+    return dst;
+}
+
+#define use_shallow_clone_func(map) cx_map_shallow_clone_func, NULL, (void*)&((map)->collection.elem_size)
+
 int cxMapClone(CxMap *dst, const CxMap *src, cx_clone_func clone_func,
         const CxAllocator *clone_allocator, void *data) {
     if (clone_allocator == NULL) clone_allocator = cxDefaultAllocator;
@@ -293,3 +306,56 @@
     }
     return 0;
 }
+
+int cxMapCloneShallow(CxMap *dst, const CxMap *src) {
+    return cxMapClone(dst, src, use_shallow_clone_func(src));
+}
+
+int cxMapDifferenceShallow(CxMap *dst, const CxMap *minuend, const CxMap *subtrahend) {
+    return cxMapDifference(dst, minuend, subtrahend, use_shallow_clone_func(minuend));
+}
+
+int cxMapListDifferenceShallow(CxMap *dst, const CxMap *src, const CxList *keys) {
+    return cxMapListDifference(dst, src, keys, use_shallow_clone_func(src));
+}
+
+int cxMapIntersectionShallow(CxMap *dst, const CxMap *src, const CxMap *other) {
+    return cxMapIntersection(dst, src, other, use_shallow_clone_func(src));
+}
+
+int cxMapListIntersectionShallow(CxMap *dst, const CxMap *src, const CxList *keys) {
+    return cxMapListIntersection(dst, src, keys, use_shallow_clone_func(src));
+}
+
+int cxMapUnionShallow(CxMap *dst, const CxMap *src) {
+    return cxMapUnion(dst, src, use_shallow_clone_func(src));
+}
+
+int cxMapCompare(const CxMap *map, const CxMap *other) {
+    // compare map sizes
+    const size_t size_left = cxMapSize(map);
+    const size_t size_right = cxMapSize(other);
+    if (size_left < size_right) {
+        return -1;
+    } else if (size_left > size_right) {
+        return 1;
+    }
+
+    // iterate through the first map
+    CxMapIterator iter = cxMapIterator(map);
+    cx_foreach(const CxMapEntry *, entry, iter) {
+        const void *value_left = entry->value;
+        const void *value_right = cxMapGet(other, *entry->key);
+        // if the other map does not have the key, we are done
+        if (value_right == NULL) {
+            return -1;
+        }
+        // compare the values
+        const int d = cx_invoke_compare_func(map, value_left, value_right);
+        if (d != 0) {
+            return d;
+        }
+    }
+
+    return 0;
+}

mercurial