ucx/cx/map.h

changeset 888
af685cc9d623
parent 854
1c8401ece69e
--- a/ucx/cx/map.h	Sun Aug 31 14:39:13 2025 +0200
+++ b/ucx/cx/map.h	Sat Nov 08 23:06:11 2025 +0100
@@ -41,6 +41,11 @@
 #include "string.h"
 #include "hash_key.h"
 
+#ifndef UCX_LIST_H
+// forward-declare CxList
+typedef struct cx_list_s CxList;
+#endif
+
 #ifdef    __cplusplus
 extern "C" {
 #endif
@@ -111,16 +116,7 @@
     /**
      * Handle for the source map.
      */
-    union {
-        /**
-         * Access for mutating iterators.
-         */
-        CxMap *m;
-        /**
-         * Access for normal iterators.
-         */
-        const CxMap *c;
-    } map;
+    CxMap *map;
 
     /**
      * Handle for the current element.
@@ -185,20 +181,16 @@
 
     /**
      * Add or overwrite an element.
+     * If the @p value is @c NULL, the implementation
+     * shall only allocate memory instead of adding an existing value to the map.
+     * Returns a pointer to the allocated memory or @c NULL if allocation fails.
      */
-    int (*put)(
-            CxMap *map,
-            CxHashKey key,
-            void *value
-    );
+    void *(*put)(CxMap *map, CxHashKey key, void *value);
 
     /**
      * Returns an element.
      */
-    void *(*get)(
-            const CxMap *map,
-            CxHashKey key
-    );
+    void *(*get)(const CxMap *map, CxHashKey key);
 
     /**
      * Removes an element.
@@ -210,11 +202,7 @@
      * The function SHALL return zero when the @p key was found and
      * non-zero, otherwise. 
      */
-    int (*remove)(
-            CxMap *map,
-            CxHashKey key,
-            void *targetbuf
-    );
+    int (*remove)(CxMap *map, CxHashKey key, void *targetbuf);
 
     /**
      * Creates an iterator for this map.
@@ -227,11 +215,10 @@
  *
  * Writing to that map is not allowed.
  *
- * You can use this is a placeholder for initializing CxMap pointers
+ * You can use this as a placeholder for initializing CxMap pointers
  * for which you do not want to reserve memory right from the beginning.
  */
-cx_attr_export
-extern CxMap *const cxEmptyMap;
+CX_EXPORT extern CxMap *const cxEmptyMap;
 
 /**
  * Deallocates the memory of the specified map.
@@ -240,8 +227,7 @@
  *
  * @param map the map to be freed
  */
-cx_attr_export
-void cxMapFree(CxMap *map);
+CX_EXPORT void cxMapFree(CxMap *map);
 
 
 /**
@@ -252,9 +238,7 @@
  * @param map the map to be cleared
  */
 cx_attr_nonnull
-static inline void cxMapClear(CxMap *map) {
-    map->cl->clear(map);
-}
+CX_EXPORT void cxMapClear(CxMap *map);
 
 /**
  * Returns the number of elements in this map.
@@ -263,9 +247,7 @@
  * @return the number of stored elements
  */
 cx_attr_nonnull
-static inline size_t cxMapSize(const CxMap *map) {
-    return map->collection.size;
-}
+CX_EXPORT size_t cxMapSize(const CxMap *map);
 
 /**
  * Creates a value iterator for a map.
@@ -277,308 +259,66 @@
  * @note An iterator iterates over all elements successively. Therefore, the order
  * highly depends on the map implementation and may change arbitrarily when the contents change.
  *
- * @param map the map to create the iterator for
+ * @param map the map to create the iterator for (can be @c NULL)
  * @return an iterator for the currently stored values
  */
-cx_attr_nonnull
 cx_attr_nodiscard
-static inline CxMapIterator cxMapIteratorValues(const CxMap *map) {
-    return map->cl->iterator(map, CX_MAP_ITERATOR_VALUES);
-}
+CX_EXPORT CxMapIterator cxMapIteratorValues(const CxMap *map);
 
 /**
  * Creates a key iterator for a map.
  *
- * The elements of the iterator are keys of type CxHashKey and the pointer returned
+ * The elements of the iterator are keys of type CxHashKey, and the pointer returned
  * during iterator shall be treated as @c const @c CxHashKey* .
  *
  * @note An iterator iterates over all elements successively. Therefore, the order
  * highly depends on the map implementation and may change arbitrarily when the contents change.
  *
- * @param map the map to create the iterator for
+ * @param map the map to create the iterator for (can be @c NULL)
  * @return an iterator for the currently stored keys
  */
-cx_attr_nonnull
 cx_attr_nodiscard
-static inline CxMapIterator cxMapIteratorKeys(const CxMap *map) {
-    return map->cl->iterator(map, CX_MAP_ITERATOR_KEYS);
-}
+CX_EXPORT CxMapIterator cxMapIteratorKeys(const CxMap *map);
 
 /**
  * Creates an iterator for a map.
  *
- * The elements of the iterator are key/value pairs of type CxMapEntry and the pointer returned
- * during iterator shall be treated as @c const @c CxMapEntry* .
- *
- * @note An iterator iterates over all elements successively. Therefore, the order
- * highly depends on the map implementation and may change arbitrarily when the contents change.
- *
- * @param map the map to create the iterator for
- * @return an iterator for the currently stored entries
- * @see cxMapIteratorKeys()
- * @see cxMapIteratorValues()
- */
-cx_attr_nonnull
-cx_attr_nodiscard
-static inline CxMapIterator cxMapIterator(const CxMap *map) {
-    return map->cl->iterator(map, CX_MAP_ITERATOR_PAIRS);
-}
-
-
-/**
- * Creates a mutating iterator over the values of a map.
- *
- * When the map is storing pointers, those pointers are returned.
- * Otherwise, the iterator iterates over pointers to the memory within the map where the
- * respective elements are stored.
- *
- * @note An iterator iterates over all elements successively. Therefore, the order
- * highly depends on the map implementation and may change arbitrarily when the contents change.
- *
- * @param map the map to create the iterator for
- * @return an iterator for the currently stored values
- */
-cx_attr_nonnull
-cx_attr_nodiscard
-cx_attr_export
-CxMapIterator cxMapMutIteratorValues(CxMap *map);
-
-/**
- * Creates a mutating iterator over the keys of a map.
- *
- * The elements of the iterator are keys of type CxHashKey and the pointer returned
- * during iterator shall be treated as @c const @c CxHashKey* .
- *
- * @note An iterator iterates over all elements successively. Therefore, the order
- * highly depends on the map implementation and may change arbitrarily when the contents change.
- *
- * @param map the map to create the iterator for
- * @return an iterator for the currently stored keys
- */
-cx_attr_nonnull
-cx_attr_nodiscard
-cx_attr_export
-CxMapIterator cxMapMutIteratorKeys(CxMap *map);
-
-/**
- * Creates a mutating iterator for a map.
- *
- * The elements of the iterator are key/value pairs of type CxMapEntry and the pointer returned
+ * The elements of the iterator are key/value pairs of type CxMapEntry, and the pointer returned
  * during iterator shall be treated as @c const @c CxMapEntry* .
  *
  * @note An iterator iterates over all elements successively. Therefore, the order
  * highly depends on the map implementation and may change arbitrarily when the contents change.
  *
- * @param map the map to create the iterator for
+ * @param map the map to create the iterator for (can be @c NULL)
  * @return an iterator for the currently stored entries
- * @see cxMapMutIteratorKeys()
- * @see cxMapMutIteratorValues()
+ * @see cxMapIteratorKeys()
+ * @see cxMapIteratorValues()
+ */
+cx_attr_nodiscard
+CX_EXPORT CxMapIterator cxMapIterator(const CxMap *map);
+
+/**
+ * Puts a key/value-pair into the map.
+ *
+ * A possible existing value will be overwritten.
+ * If destructor functions are specified, they are called for
+ * the overwritten element.
+ *
+ * If this map is storing pointers, the @p value pointer is written
+ * to the map. Otherwise, the memory is copied from @p value with
+ * memcpy().
+ *
+ * The @p key is always copied.
+ *
+ * @param map the map
+ * @param key the key
+ * @param value the value
+ * @retval zero success
+ * @retval non-zero value on memory allocation failure
+ * @see cxMapPut()
  */
 cx_attr_nonnull
-cx_attr_nodiscard
-cx_attr_export
-CxMapIterator cxMapMutIterator(CxMap *map);
-
-#ifdef __cplusplus
-} // end the extern "C" block here, because we want to start overloading
-cx_attr_nonnull
-static inline int cxMapPut(
-        CxMap *map,
-        CxHashKey const &key,
-        void *value
-) {
-    return map->cl->put(map, key, value);
-}
-
-cx_attr_nonnull
-static inline int cxMapPut(
-        CxMap *map,
-        cxstring const &key,
-        void *value
-) {
-    return map->cl->put(map, cx_hash_key_cxstr(key), value);
-}
-
-cx_attr_nonnull
-static inline int cxMapPut(
-        CxMap *map,
-        cxmutstr const &key,
-        void *value
-) {
-    return map->cl->put(map, cx_hash_key_cxstr(key), value);
-}
-
-cx_attr_nonnull
-cx_attr_cstr_arg(2)
-static inline int cxMapPut(
-        CxMap *map,
-        const char *key,
-        void *value
-) {
-    return map->cl->put(map, cx_hash_key_str(key), value);
-}
-
-cx_attr_nonnull
-cx_attr_nodiscard
-static inline void *cxMapGet(
-        const CxMap *map,
-        CxHashKey const &key
-) {
-    return map->cl->get(map, key);
-}
-
-cx_attr_nonnull
-cx_attr_nodiscard
-static inline void *cxMapGet(
-        const CxMap *map,
-        cxstring const &key
-) {
-    return map->cl->get(map, cx_hash_key_cxstr(key));
-}
-
-cx_attr_nonnull
-cx_attr_nodiscard
-static inline void *cxMapGet(
-        const CxMap *map,
-        cxmutstr const &key
-) {
-    return map->cl->get(map, cx_hash_key_cxstr(key));
-}
-
-cx_attr_nonnull
-cx_attr_nodiscard
-cx_attr_cstr_arg(2)
-static inline void *cxMapGet(
-        const CxMap *map,
-        const char *key
-) {
-    return map->cl->get(map, cx_hash_key_str(key));
-}
-
-cx_attr_nonnull
-static inline int cxMapRemove(
-        CxMap *map,
-        CxHashKey const &key
-) {
-    return map->cl->remove(map, key, nullptr);
-}
-
-cx_attr_nonnull
-static inline int cxMapRemove(
-        CxMap *map,
-        cxstring const &key
-) {
-    return map->cl->remove(map, cx_hash_key_cxstr(key), nullptr);
-}
-
-cx_attr_nonnull
-static inline int cxMapRemove(
-        CxMap *map,
-        cxmutstr const &key
-) {
-    return map->cl->remove(map, cx_hash_key_cxstr(key), nullptr);
-}
-
-cx_attr_nonnull
-cx_attr_cstr_arg(2)
-static inline int cxMapRemove(
-        CxMap *map,
-        const char *key
-) {
-    return map->cl->remove(map, cx_hash_key_str(key), nullptr);
-}
-
-cx_attr_nonnull
-cx_attr_access_w(3)
-static inline int cxMapRemoveAndGet(
-        CxMap *map,
-        CxHashKey key,
-        void *targetbuf
-) {
-    return map->cl->remove(map, key, targetbuf);
-}
-
-cx_attr_nonnull
-cx_attr_access_w(3)
-static inline int cxMapRemoveAndGet(
-        CxMap *map,
-        cxstring key,
-        void *targetbuf
-) {
-    return map->cl->remove(map, cx_hash_key_cxstr(key), targetbuf);
-}
-
-cx_attr_nonnull
-cx_attr_access_w(3)
-static inline int cxMapRemoveAndGet(
-        CxMap *map,
-        cxmutstr key,
-        void *targetbuf
-) {
-    return map->cl->remove(map, cx_hash_key_cxstr(key), targetbuf);
-}
-
-cx_attr_nonnull
-cx_attr_access_w(3)
-cx_attr_cstr_arg(2)
-static inline int cxMapRemoveAndGet(
-        CxMap *map,
-        const char *key,
-        void *targetbuf
-) {
-    return map->cl->remove(map, cx_hash_key_str(key), targetbuf);
-}
-
-#else // __cplusplus
-
-/**
- * @copydoc cxMapPut()
- */
-cx_attr_nonnull
-static inline int cx_map_put(
-        CxMap *map,
-        CxHashKey key,
-        void *value
-) {
-    return map->cl->put(map, key, value);
-}
-
-/**
- * @copydoc cxMapPut()
- */
-cx_attr_nonnull
-static inline int cx_map_put_cxstr(
-        CxMap *map,
-        cxstring key,
-        void *value
-) {
-    return map->cl->put(map, cx_hash_key_cxstr(key), value);
-}
-
-/**
- * @copydoc cxMapPut()
- */
-cx_attr_nonnull
-static inline int cx_map_put_mustr(
-        CxMap *map,
-        cxmutstr key,
-        void *value
-) {
-    return map->cl->put(map, cx_hash_key_cxstr(key), value);
-}
-
-/**
- * @copydoc cxMapPut()
- */
-cx_attr_nonnull
-cx_attr_cstr_arg(2)
-static inline int cx_map_put_str(
-        CxMap *map,
-        const char *key,
-        void *value
-) {
-    return map->cl->put(map, cx_hash_key_str(key), value);
-}
+CX_EXPORT int cx_map_put(CxMap *map, CxHashKey key, void *value);
 
 /**
  * Puts a key/value-pair into the map.
@@ -594,67 +334,71 @@
  * The @p key is always copied.
  *
  * @param map (@c CxMap*) the map
- * @param key (@c CxHashKey, @c char*, @c cxstring, or @c cxmutstr) the key
+ * @param key (any supported key type) the key
  * @param value (@c void*) the value
  * @retval zero success
  * @retval non-zero value on memory allocation failure
+ * @see CX_HASH_KEY()
  */
-#define cxMapPut(map, key, value) _Generic((key), \
-    CxHashKey: cx_map_put,                        \
-    cxstring: cx_map_put_cxstr,                   \
-    cxmutstr: cx_map_put_mustr,                   \
-    char*: cx_map_put_str,                        \
-    const char*: cx_map_put_str)                  \
-    (map, key, value)
+#define cxMapPut(map, key, value) cx_map_put(map, CX_HASH_KEY(key), value)
 
 /**
- * @copydoc cxMapGet()
- */
-cx_attr_nonnull
-cx_attr_nodiscard
-static inline void *cx_map_get(
-        const CxMap *map,
-        CxHashKey key
-) {
-    return map->cl->get(map, key);
-}
-
-/**
- * @copydoc cxMapGet()
+ * Allocates memory for a value in the map associated with the specified key.
+ *
+ * A possible existing value will be overwritten.
+ * If destructor functions are specified, they are called for
+ * the overwritten element.
+ *
+ * If the map is storing pointers, this function returns a @c void** pointer,
+ * meaning a pointer to that pointer.
+ *
+ * The @p key is always copied.
+ *
+ * @param map the map
+ * @param key the key
+ * @return the pointer to the allocated memory or @c NULL if allocation fails
+ * @retval zero success
+ * @retval non-zero value on memory allocation failure
+ * @see cxMapEmplace()
  */
 cx_attr_nonnull
-cx_attr_nodiscard
-static inline void *cx_map_get_cxstr(
-        const CxMap *map,
-        cxstring key
-) {
-    return map->cl->get(map, cx_hash_key_cxstr(key));
-}
+CX_EXPORT void *cx_map_emplace(CxMap *map, CxHashKey key);
 
 /**
- * @copydoc cxMapGet()
+ * Allocates memory for a value in the map associated with the specified key.
+ *
+ * A possible existing value will be overwritten.
+ * If destructor functions are specified, they are called for
+ * the overwritten element.
+ *
+ * If the map is storing pointers, this function returns a @c void** pointer,
+ * meaning a pointer to that pointer.
+ *
+ * The @p key is always copied.
+ *
+ * @param map (@c CxMap*) the map
+ * @param key (any supported key type) the key
+ * @return the pointer to the allocated memory or @c NULL if allocation fails
+ * @retval zero success
+ * @retval non-zero value on memory allocation failure
+ * @see CX_HASH_KEY()
  */
-cx_attr_nonnull
-cx_attr_nodiscard
-static inline void *cx_map_get_mustr(
-        const CxMap *map,
-        cxmutstr key
-) {
-    return map->cl->get(map, cx_hash_key_cxstr(key));
-}
+#define cxMapEmplace(map, key) cx_map_emplace(map, CX_HASH_KEY(key))
 
 /**
- * @copydoc cxMapGet()
+ * Retrieves a value by using a key.
+ *
+ * If this map is storing pointers, the stored pointer is returned.
+ * Otherwise, a pointer to the element within the map's memory
+ * is returned (which is valid as long as the element stays in the map).
+ *
+ * @param map the map
+ * @param key the key
+ * @return the value
+ * @see cxMapGet()
  */
-cx_attr_nonnull
-cx_attr_nodiscard
-cx_attr_cstr_arg(2)
-static inline void *cx_map_get_str(
-        const CxMap *map,
-        const char *key
-) {
-    return map->cl->get(map, cx_hash_key_str(key));
-}
+cx_attr_nonnull cx_attr_nodiscard
+CX_EXPORT void *cx_map_get(const CxMap *map, CxHashKey key);
 
 /**
  * Retrieves a value by using a key.
@@ -664,134 +408,55 @@
  * is returned (which is valid as long as the element stays in the map).
  *
  * @param map (@c CxMap*) the map
- * @param key (@c CxHashKey, @c char*, @c cxstring, or @c cxmutstr) the key
- * @return (@c void*) the value
+ * @param key (any supported key type) the key
+ * @return (@c void*) the value or @c NULL when no value with that @p key exists
+ * @see CX_HASH_KEY()
  */
-#define cxMapGet(map, key) _Generic((key), \
-    CxHashKey: cx_map_get,                 \
-    cxstring: cx_map_get_cxstr,            \
-    cxmutstr: cx_map_get_mustr,            \
-    char*: cx_map_get_str,                 \
-    const char*: cx_map_get_str)           \
-    (map, key)
-
-/**
- * @copydoc cxMapRemove()
- */
-cx_attr_nonnull
-static inline int cx_map_remove(
-        CxMap *map,
-        CxHashKey key
-) {
-    return map->cl->remove(map, key, NULL);
-}
+#define cxMapGet(map, key) cx_map_get(map, CX_HASH_KEY(key))
 
 /**
- * @copydoc cxMapRemove()
- */
-cx_attr_nonnull
-static inline int cx_map_remove_cxstr(
-        CxMap *map,
-        cxstring key
-) {
-    return map->cl->remove(map, cx_hash_key_cxstr(key), NULL);
-}
-
-/**
- * @copydoc cxMapRemove()
+ * Checks if a map contains a specific key.
+ *
+ * @param map (@c CxMap*) the map
+ * @param key (any supported key type) the key
+ * @retval true if the key exists in the map
+ * @retval false if the key does not exist in the map
+ * @see CX_HASH_KEY()
  */
-cx_attr_nonnull
-static inline int cx_map_remove_mustr(
-        CxMap *map,
-        cxmutstr key
-) {
-    return map->cl->remove(map, cx_hash_key_cxstr(key), NULL);
-}
-
-/**
- * @copydoc cxMapRemove()
- */
-cx_attr_nonnull
-cx_attr_cstr_arg(2)
-static inline int cx_map_remove_str(
-        CxMap *map,
-        const char *key
-) {
-    return map->cl->remove(map, cx_hash_key_str(key), NULL);
-}
+#define cxMapContains(map, key) (cxMapGet(map, key) != NULL)
 
 /**
  * Removes a key/value-pair from the map by using the key.
  *
- * Always invokes the destructors functions, if any, on the removed element.
+ * Invokes the destructor functions, if any, on the removed element if and only if the
+ * @p targetbuf is @c NULL.
+ *
+ * @param map the map
+ * @param key the key
+ * @param targetbuf the optional buffer where the removed element shall be copied to
+ * @retval zero success
+ * @retval non-zero the key was not found
+ *
+ * @see cxMapRemove()
+ * @see cxMapRemoveAndGet()
+ */
+cx_attr_nonnull_arg(1)
+CX_EXPORT int cx_map_remove(CxMap *map, CxHashKey key, void *targetbuf);
+
+/**
+ * Removes a key/value-pair from the map by using the key.
+ *
+ * Always invokes the destructor functions, if any, on the removed element.
  *
  * @param map (@c CxMap*) the map
- * @param key (@c CxHashKey, @c char*, @c cxstring, or @c cxmutstr) the key
+ * @param key (any supported key type) the key
  * @retval zero success
  * @retval non-zero the key was not found
  * 
  * @see cxMapRemoveAndGet()
- */
-#define cxMapRemove(map, key) _Generic((key), \
-    CxHashKey: cx_map_remove,                 \
-    cxstring: cx_map_remove_cxstr,            \
-    cxmutstr: cx_map_remove_mustr,            \
-    char*: cx_map_remove_str,                 \
-    const char*: cx_map_remove_str)           \
-    (map, key)
-
-/**
- * @copydoc cxMapRemoveAndGet()
- */
-cx_attr_nonnull
-cx_attr_access_w(3)
-static inline int cx_map_remove_and_get(
-        CxMap *map,
-        CxHashKey key,
-        void *targetbuf
-) {
-    return map->cl->remove(map, key, targetbuf);
-}
-
-/**
- * @copydoc cxMapRemoveAndGet()
+ * @see CX_HASH_KEY()
  */
-cx_attr_nonnull
-cx_attr_access_w(3)
-static inline int cx_map_remove_and_get_cxstr(
-        CxMap *map,
-        cxstring key,
-        void *targetbuf
-) {
-    return map->cl->remove(map, cx_hash_key_cxstr(key), targetbuf);
-}
-
-/**
- * @copydoc cxMapRemoveAndGet()
- */
-cx_attr_nonnull
-cx_attr_access_w(3)
-static inline int cx_map_remove_and_get_mustr(
-        CxMap *map,
-        cxmutstr key,
-        void *targetbuf
-) {
-    return map->cl->remove(map, cx_hash_key_cxstr(key), targetbuf);
-}
-
-/**
- * @copydoc cxMapRemoveAndGet()
- */
-cx_attr_nonnull
-cx_attr_access_w(3)
-cx_attr_cstr_arg(2)
-static inline int cx_map_remove_and_get_str(
-        CxMap *map,
-        const char *key,
-        void *targetbuf
-) {
-    return map->cl->remove(map, cx_hash_key_str(key), targetbuf);
-}
+#define cxMapRemove(map, key) cx_map_remove(map, CX_HASH_KEY(key), NULL)
 
 /**
  * Removes a key/value-pair from the map by using the key.
@@ -805,21 +470,141 @@
  * and not the object it points to.
  *
  * @param map (@c CxMap*) the map
- * @param key (@c CxHashKey, @c char*, @c cxstring, or @c cxmutstr) the key
+ * @param key (any supported key type) the key
  * @param targetbuf (@c void*) the buffer where the element shall be copied to
  * @retval zero success
  * @retval non-zero the key was not found
  *
  * @see cxMapRemove()
+ * @see CX_HASH_KEY()
  */
-#define cxMapRemoveAndGet(map, key, targetbuf) _Generic((key), \
-    CxHashKey: cx_map_remove_and_get,               \
-    cxstring: cx_map_remove_and_get_cxstr,          \
-    cxmutstr: cx_map_remove_and_get_mustr,          \
-    char*: cx_map_remove_and_get_str,               \
-    const char*: cx_map_remove_and_get_str)         \
-    (map, key, targetbuf)
+#define cxMapRemoveAndGet(map, key, targetbuf) cx_map_remove(map, CX_HASH_KEY(key), targetbuf)
+
+
+/**
+ * Performs a deep clone of one map into another.
+ *
+ * If the destination map already contains entries, the cloned entries
+ * are added to that map, possibly overwriting existing elements when
+ * the keys already exist.
+ *
+ * When elements in the destination map need to be replaced, any destructor
+ * function is called on the replaced elements before replacing them.
+ *
+ * @attention If the cloned elements need to be destroyed by a destructor
+ * function, you must make sure that the destination map also uses this
+ * destructor function.
+ *
+ * @param dst the destination map
+ * @param src the source map
+ * @param clone_func the clone function for the values
+ * @param clone_allocator the allocator that is passed to the clone function
+ * @param data optional additional data that is passed to the clone function
+ * @retval zero when all elements were successfully cloned
+ * @retval non-zero when an allocation error occurred
+ */
+cx_attr_nonnull_arg(1, 2, 3)
+CX_EXPORT int cxMapClone(CxMap *dst, const CxMap *src,
+        cx_clone_func clone_func, const CxAllocator *clone_allocator, void *data);
+
+
+/**
+ * Clones entries of a map if their key is not present in another map.
+ *
+ * @param dst the destination map
+ * @param minuend the map to subtract the entries from
+ * @param subtrahend the map containing the elements to be subtracted
+ * @param clone_func the clone function for the values
+ * @param clone_allocator the allocator that is passed to the clone function
+ * @param data optional additional data that is passed to the clone function
+ * @retval zero when the elements were successfully cloned
+ * @retval non-zero when an allocation error occurred
+ */
+cx_attr_nonnull_arg(1, 2, 3, 4)
+CX_EXPORT int cxMapDifference(CxMap *dst, const CxMap *minuend, const CxMap *subtrahend,
+        cx_clone_func clone_func, const CxAllocator *clone_allocator, void *data);
 
-#endif // __cplusplus
+/**
+ * Clones entries of a map if their key is not present in a list.
+ *
+ * Note that the list must contain keys of type @c CxKey
+ * (or pointers to such keys) and must use @c cx_hash_key_cmp
+ * as the compare function.
+ * Generic key types cannot be processed in this case.
+ *
+ * @param dst the destination map
+ * @param src the source map
+ * @param keys the list of @c CxKey items
+ * @param clone_func the clone function for the values
+ * @param clone_allocator the allocator that is passed to the clone function
+ * @param data optional additional data that is passed to the clone function
+ * @retval zero when the elements were successfully cloned
+ * @retval non-zero when an allocation error occurred
+ */
+cx_attr_nonnull_arg(1, 2, 3, 4)
+CX_EXPORT int cxMapListDifference(CxMap *dst, const CxMap *src, const CxList *keys,
+        cx_clone_func clone_func, const CxAllocator *clone_allocator, void *data);
+
+
+/**
+ * Clones entries of a map only if their key is present in another map.
+ *
+ * @param dst the destination map
+ * @param src the map to clone the entries from
+ * @param other the map to check for existence of the keys
+ * @param clone_func the clone function for the values
+ * @param clone_allocator the allocator that is passed to the clone function
+ * @param data optional additional data that is passed to the clone function
+ * @retval zero when the elements were successfully cloned
+ * @retval non-zero when an allocation error occurred
+ */
+cx_attr_nonnull_arg(1, 2, 3, 4)
+CX_EXPORT int cxMapIntersection(CxMap *dst, const CxMap *src, const CxMap *other,
+        cx_clone_func clone_func, const CxAllocator *clone_allocator, void *data);
+
+/**
+ * Clones entries of a map only if their key is present in a list.
+ *
+ * Note that the list must contain keys of type @c CxKey
+ * (or pointers to such keys) and must use @c cx_hash_key_cmp
+ * as the compare function.
+ * Generic key types cannot be processed in this case.
+ *
+ * @param dst the destination map
+ * @param src the source map
+ * @param keys the list of @c CxKey items
+ * @param clone_func the clone function for the values
+ * @param clone_allocator the allocator that is passed to the clone function
+ * @param data optional additional data that is passed to the clone function
+ * @retval zero when the elements were successfully cloned
+ * @retval non-zero when an allocation error occurred
+ */
+cx_attr_nonnull_arg(1, 2, 3, 4)
+CX_EXPORT int cxMapListIntersection(CxMap *dst, const CxMap *src, const CxList *keys,
+        cx_clone_func clone_func, const CxAllocator *clone_allocator, void *data);
+
+/**
+ * Clones entries into a map if their key does not exist yet.
+ *
+ * If you want to calculate the union of two maps into a fresh new map,
+ * you can proceed as follows:
+ * 1. Clone the first map into a fresh, empty map.
+ * 2. Use this function to clone the second map into the result from step 1.
+ *
+ * @param dst the destination map
+ * @param src the map to clone the entries from
+ * @param clone_func the clone function for the values
+ * @param clone_allocator the allocator that is passed to the clone function
+ * @param data optional additional data that is passed to the clone function
+ * @retval zero when the elements were successfully cloned
+ * @retval non-zero when an allocation error occurred
+ */
+cx_attr_nonnull_arg(1, 2, 3)
+CX_EXPORT int cxMapUnion(CxMap *dst, const CxMap *src,
+        cx_clone_func clone_func, const CxAllocator *clone_allocator, void *data);
+
+#ifdef    __cplusplus
+} // extern "C"
+#endif
 
 #endif // UCX_MAP_H

mercurial