--- 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; +}