ucx/cx/map.h

changeset 16
04c9f8d8f03b
parent 11
0aa8cbd7912e
child 22
112b85020dc9
--- a/ucx/cx/map.h	Sun Feb 16 17:38:07 2025 +0100
+++ b/ucx/cx/map.h	Tue Feb 25 21:12:11 2025 +0100
@@ -26,11 +26,11 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 /**
- * \file map.h
- * \brief Interface for map implementations.
- * \author Mike Becker
- * \author Olaf Wintermann
- * \copyright 2-Clause BSD License
+ * @file map.h
+ * @brief Interface for map implementations.
+ * @author Mike Becker
+ * @author Olaf Wintermann
+ * @copyright 2-Clause BSD License
  */
 
 #ifndef UCX_MAP_H
@@ -51,6 +51,9 @@
 /** Type for a map entry. */
 typedef struct cx_map_entry_s CxMapEntry;
 
+/** Type for a map iterator. */
+typedef struct cx_map_iterator_s CxMapIterator;
+
 /** Type for map class definitions. */
 typedef struct cx_map_class_s cx_map_class;
 
@@ -65,6 +68,20 @@
 };
 
 /**
+ * A map entry.
+ */
+struct cx_map_entry_s {
+    /**
+     * A pointer to the key.
+     */
+    const CxHashKey *key;
+    /**
+     * A pointer to the value.
+     */
+    void *value;
+};
+
+/**
  * The type of iterator for a map.
  */
 enum cx_map_iterator_type {
@@ -83,25 +100,92 @@
 };
 
 /**
+ * Internal iterator struct - use CxMapIterator.
+ */
+struct cx_map_iterator_s {
+    /**
+     * Inherited common data for all iterators.
+     */
+    CX_ITERATOR_BASE;
+
+    /**
+     * Handle for the source map.
+     */
+    union {
+        /**
+         * Access for mutating iterators.
+         */
+        CxMap *m;
+        /**
+         * Access for normal iterators.
+         */
+        const CxMap *c;
+    } map;
+
+    /**
+     * Handle for the current element.
+     *
+     * @attention Depends on the map implementation, do not assume a type (better: do not use!).
+     */
+    void *elem;
+
+    /**
+     * Reserved memory for a map entry.
+     *
+     * If a map implementation uses an incompatible layout, the iterator needs something
+     * to point to during iteration which @em is compatible.
+     */
+    CxMapEntry entry;
+
+    /**
+     * Field for storing the current slot number.
+     *
+     * (Used internally)
+     */
+    size_t slot;
+
+    /**
+     * Counts the elements successfully.
+     * It usually does not denote a stable index within the map as it would be for arrays.
+     */
+    size_t index;
+
+    /**
+     * The size of a value stored in this map.
+     */
+    size_t elem_size;
+
+    /**
+     * May contain the total number of elements, if known.
+     * Set to @c SIZE_MAX when the total number is unknown during iteration.
+     *
+     * @remark The UCX implementations of #CxMap always know the number of elements they store.
+     */
+    size_t elem_count;
+
+    /**
+     * The type of this iterator.
+     */
+    enum cx_map_iterator_type type;
+};
+
+/**
  * The class definition for arbitrary maps.
  */
 struct cx_map_class_s {
     /**
      * Deallocates the entire memory.
      */
-    cx_attr_nonnull
     void (*deallocate)(struct cx_map_s *map);
 
     /**
      * Removes all elements.
      */
-    cx_attr_nonnull
     void (*clear)(struct cx_map_s *map);
 
     /**
      * Add or overwrite an element.
      */
-    cx_attr_nonnull
     int (*put)(
             CxMap *map,
             CxHashKey key,
@@ -111,8 +195,6 @@
     /**
      * Returns an element.
      */
-    cx_attr_nonnull
-    cx_attr_nodiscard
     void *(*get)(
             const CxMap *map,
             CxHashKey key
@@ -121,15 +203,13 @@
     /**
      * Removes an element.
      *
-     * Implementations SHALL check if \p targetbuf is set and copy the elements
+     * Implementations SHALL check if @p targetbuf is set and copy the elements
      * to the buffer without invoking any destructor.
-     * When \p targetbuf is not set, the destructors SHALL be invoked.
+     * When @p targetbuf is not set, the destructors SHALL be invoked.
      *
-     * The function SHALL return zero when the \p key was found and
+     * The function SHALL return zero when the @p key was found and
      * non-zero, otherwise. 
      */
-    cx_attr_nonnull_arg(1)
-    cx_attr_access_w(3)
     int (*remove)(
             CxMap *map,
             CxHashKey key,
@@ -139,90 +219,36 @@
     /**
      * Creates an iterator for this map.
      */
-    cx_attr_nonnull
-    cx_attr_nodiscard
-    CxIterator (*iterator)(const CxMap *map, enum cx_map_iterator_type type);
-};
-
-/**
- * A map entry.
- */
-struct cx_map_entry_s {
-    /**
-     * A pointer to the key.
-     */
-    const CxHashKey *key;
-    /**
-     * A pointer to the value.
-     */
-    void *value;
+    CxMapIterator (*iterator)(const CxMap *map, enum cx_map_iterator_type type);
 };
 
 /**
  * A shared instance of an empty map.
  *
  * Writing to that map is not allowed.
- */
-extern CxMap *const cxEmptyMap;
-
-/**
- * Advises the map to store copies of the objects (default mode of operation).
  *
- * Retrieving objects from this map will yield pointers to the copies stored
- * within this list.
- *
- * @param map the map
- * @see cxMapStorePointers()
+ * You can use this is a placeholder for initializing CxMap pointers
+ * for which you do not want to reserve memory right from the beginning.
  */
-cx_attr_nonnull
-static inline void cxMapStoreObjects(CxMap *map) {
-    map->collection.store_pointer = false;
-}
-
-/**
- * Advises the map to only store pointers to the objects.
- *
- * Retrieving objects from this list will yield the original pointers stored.
- *
- * @note This function forcibly sets the element size to the size of a pointer.
- * Invoking this function on a non-empty map that already stores copies of
- * objects is undefined.
- *
- * @param map the map
- * @see cxMapStoreObjects()
- */
-cx_attr_nonnull
-static inline void cxMapStorePointers(CxMap *map) {
-    map->collection.store_pointer = true;
-    map->collection.elem_size = sizeof(void *);
-}
-
-/**
- * Returns true, if this map is storing pointers instead of the actual data.
- *
- * @param map
- * @return true, if this map is storing pointers
- * @see cxMapStorePointers()
- */
-cx_attr_nonnull
-static inline bool cxMapIsStoringPointers(const CxMap *map) {
-    return map->collection.store_pointer;
-}
+cx_attr_export
+extern CxMap *const cxEmptyMap;
 
 /**
  * Deallocates the memory of the specified map.
  *
+ * Also calls the content destructor functions for each element, if specified.
+ *
  * @param map the map to be freed
  */
-static inline void cxMapFree(CxMap *map) {
-    if (map == NULL) return;
-    map->cl->deallocate(map);
-}
+cx_attr_export
+void cxMapFree(CxMap *map);
 
 
 /**
  * Clears a map by removing all elements.
  *
+ * Also calls the content destructor functions for each element, if specified.
+ *
  * @param map the map to be cleared
  */
 cx_attr_nonnull
@@ -241,13 +267,14 @@
     return map->collection.size;
 }
 
-
-// TODO: set-like map operations (union, intersect, difference)
-
 /**
  * Creates a value iterator for a map.
  *
- * \note An iterator iterates over all elements successively. Therefore, the order
+ * 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
@@ -255,16 +282,17 @@
  */
 cx_attr_nonnull
 cx_attr_nodiscard
-static inline CxIterator cxMapIteratorValues(const CxMap *map) {
+static inline CxMapIterator cxMapIteratorValues(const CxMap *map) {
     return map->cl->iterator(map, CX_MAP_ITERATOR_VALUES);
 }
 
 /**
  * Creates a key iterator for a map.
  *
- * The elements of the iterator are keys of type CxHashKey.
+ * 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
+ * @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
@@ -272,16 +300,17 @@
  */
 cx_attr_nonnull
 cx_attr_nodiscard
-static inline CxIterator cxMapIteratorKeys(const CxMap *map) {
+static inline CxMapIterator cxMapIteratorKeys(const CxMap *map) {
     return map->cl->iterator(map, CX_MAP_ITERATOR_KEYS);
 }
 
 /**
  * Creates an iterator for a map.
  *
- * The elements of the iterator are key/value pairs of type CxMapEntry.
+ * 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
+ * @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
@@ -291,7 +320,7 @@
  */
 cx_attr_nonnull
 cx_attr_nodiscard
-static inline CxIterator cxMapIterator(const CxMap *map) {
+static inline CxMapIterator cxMapIterator(const CxMap *map) {
     return map->cl->iterator(map, CX_MAP_ITERATOR_PAIRS);
 }
 
@@ -299,7 +328,11 @@
 /**
  * Creates a mutating iterator over the values of a map.
  *
- * \note An iterator iterates over all elements successively. Therefore, the order
+ * 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
@@ -307,14 +340,16 @@
  */
 cx_attr_nonnull
 cx_attr_nodiscard
-CxIterator cxMapMutIteratorValues(CxMap *map);
+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.
+ * 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
+ * @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
@@ -322,14 +357,16 @@
  */
 cx_attr_nonnull
 cx_attr_nodiscard
-CxIterator cxMapMutIteratorKeys(CxMap *map);
+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.
+ * 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
+ * @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
@@ -339,19 +376,11 @@
  */
 cx_attr_nonnull
 cx_attr_nodiscard
-CxIterator cxMapMutIterator(CxMap *map);
+cx_attr_export
+CxMapIterator cxMapMutIterator(CxMap *map);
 
 #ifdef __cplusplus
 } // end the extern "C" block here, because we want to start overloading
-
-/**
- * Puts a key/value-pair into the map.
- *
- * @param map the map
- * @param key the key
- * @param value the value
- * @return 0 on success, non-zero value on failure
- */
 cx_attr_nonnull
 static inline int cxMapPut(
         CxMap *map,
@@ -361,15 +390,6 @@
     return map->cl->put(map, key, value);
 }
 
-
-/**
- * Puts a key/value-pair into the map.
- *
- * @param map the map
- * @param key the key
- * @param value the value
- * @return 0 on success, non-zero value on failure
- */
 cx_attr_nonnull
 static inline int cxMapPut(
         CxMap *map,
@@ -379,14 +399,6 @@
     return map->cl->put(map, cx_hash_key_cxstr(key), value);
 }
 
-/**
- * Puts a key/value-pair into the map.
- *
- * @param map the map
- * @param key the key
- * @param value the value
- * @return 0 on success, non-zero value on failure
- */
 cx_attr_nonnull
 static inline int cxMapPut(
         CxMap *map,
@@ -396,14 +408,6 @@
     return map->cl->put(map, cx_hash_key_cxstr(key), value);
 }
 
-/**
- * Puts a key/value-pair into the map.
- *
- * @param map the map
- * @param key the key
- * @param value the value
- * @return 0 on success, non-zero value on failure
- */
 cx_attr_nonnull
 cx_attr_cstr_arg(2)
 static inline int cxMapPut(
@@ -414,13 +418,6 @@
     return map->cl->put(map, cx_hash_key_str(key), value);
 }
 
-/**
- * Retrieves a value by using a key.
- *
- * @param map the map
- * @param key the key
- * @return the value
- */
 cx_attr_nonnull
 cx_attr_nodiscard
 static inline void *cxMapGet(
@@ -430,13 +427,6 @@
     return map->cl->get(map, key);
 }
 
-/**
- * Retrieves a value by using a key.
- *
- * @param map the map
- * @param key the key
- * @return the value
- */
 cx_attr_nonnull
 cx_attr_nodiscard
 static inline void *cxMapGet(
@@ -446,13 +436,6 @@
     return map->cl->get(map, cx_hash_key_cxstr(key));
 }
 
-/**
- * Retrieves a value by using a key.
- *
- * @param map the map
- * @param key the key
- * @return the value
- */
 cx_attr_nonnull
 cx_attr_nodiscard
 static inline void *cxMapGet(
@@ -462,13 +445,6 @@
     return map->cl->get(map, cx_hash_key_cxstr(key));
 }
 
-/**
- * Retrieves a value by using a key.
- *
- * @param map the map
- * @param key the key
- * @return the value
- */
 cx_attr_nonnull
 cx_attr_nodiscard
 cx_attr_cstr_arg(2)
@@ -479,17 +455,6 @@
     return map->cl->get(map, cx_hash_key_str(key));
 }
 
-/**
- * Removes a key/value-pair from the map by using the key.
- *
- * Always invokes the destructors functions, if any, on the removed element.
- *
- * @param map the map
- * @param key the key
- * @return zero on success, non-zero if the key was not found
- * 
- * @see cxMapRemoveAndGet()
- */
 cx_attr_nonnull
 static inline int cxMapRemove(
         CxMap *map,
@@ -498,17 +463,6 @@
     return map->cl->remove(map, key, nullptr);
 }
 
-/**
- * Removes a key/value-pair from the map by using the key.
- *
- * Always invokes the destructors functions, if any, on the removed element.
- *
- * @param map the map
- * @param key the key
- * @return zero on success, non-zero if the key was not found
- * 
- * @see cxMapRemoveAndGet()
- */
 cx_attr_nonnull
 static inline int cxMapRemove(
         CxMap *map,
@@ -517,17 +471,6 @@
     return map->cl->remove(map, cx_hash_key_cxstr(key), nullptr);
 }
 
-/**
- * Removes a key/value-pair from the map by using the key.
- *
- * Always invokes the destructors functions, if any, on the removed element.
- *
- * @param map the map
- * @param key the key
- * @return zero on success, non-zero if the key was not found
- * 
- * @see cxMapRemoveAndGet()
- */
 cx_attr_nonnull
 static inline int cxMapRemove(
         CxMap *map,
@@ -536,17 +479,6 @@
     return map->cl->remove(map, cx_hash_key_cxstr(key), nullptr);
 }
 
-/**
- * Removes a key/value-pair from the map by using the key.
- *
- * Always invokes the destructors functions, if any, on the removed element.
- *
- * @param map the map
- * @param key the key
- * @return zero on success, non-zero if the key was not found
- * 
- * @see cxMapRemoveAndGet()
- */
 cx_attr_nonnull
 cx_attr_cstr_arg(2)
 static inline int cxMapRemove(
@@ -556,24 +488,6 @@
     return map->cl->remove(map, cx_hash_key_str(key), nullptr);
 }
 
-/**
- * Removes a key/value-pair from the map by using the key.
- *
- * This function will copy the contents to the target buffer
- * which must be guaranteed to be large enough to hold the element.
- * The destructor functions, if any, will \em not be called.
- *
- * If this map is storing pointers, the element is the pointer itself
- * and not the object it points to.
- *
- * @param map the map
- * @param key the key
- * @param targetbuf the buffer where the element shall be copied to
- * @return zero on success, non-zero if the key was not found
- * 
- * @see cxMapStorePointers()
- * @see cxMapRemove()
- */
 cx_attr_nonnull
 cx_attr_access_w(3)
 static inline int cxMapRemoveAndGet(
@@ -584,24 +498,6 @@
     return map->cl->remove(map, key, targetbuf);
 }
 
-/**
- * Removes a key/value-pair from the map by using the key.
- *
- * This function will copy the contents to the target buffer
- * which must be guaranteed to be large enough to hold the element.
- * The destructor functions, if any, will \em not be called.
- *
- * If this map is storing pointers, the element is the pointer itself
- * and not the object it points to.
- *
- * @param map the map
- * @param key the key
- * @param targetbuf the buffer where the element shall be copied to
- * @return zero on success, non-zero if the key was not found
- * 
- * @see cxMapStorePointers()
- * @see cxMapRemove()
- */
 cx_attr_nonnull
 cx_attr_access_w(3)
 static inline int cxMapRemoveAndGet(
@@ -612,24 +508,6 @@
     return map->cl->remove(map, cx_hash_key_cxstr(key), targetbuf);
 }
 
-/**
- * Removes a key/value-pair from the map by using the key.
- *
- * This function will copy the contents to the target buffer
- * which must be guaranteed to be large enough to hold the element.
- * The destructor functions, if any, will \em not be called.
- *
- * If this map is storing pointers, the element is the pointer itself
- * and not the object it points to.
- *
- * @param map the map
- * @param key the key
- * @param targetbuf the buffer where the element shall be copied to
- * @return zero on success, non-zero if the key was not found
- * 
- * @see cxMapStorePointers()
- * @see cxMapRemove()
- */
 cx_attr_nonnull
 cx_attr_access_w(3)
 static inline int cxMapRemoveAndGet(
@@ -640,24 +518,6 @@
     return map->cl->remove(map, cx_hash_key_cxstr(key), targetbuf);
 }
 
-/**
- * Removes a key/value-pair from the map by using the key.
- *
- * This function will copy the contents to the target buffer
- * which must be guaranteed to be large enough to hold the element.
- * The destructor functions, if any, will \em not be called.
- *
- * If this map is storing pointers, the element is the pointer itself
- * and not the object it points to.
- *
- * @param map the map
- * @param key the key
- * @param targetbuf the buffer where the element shall be copied to
- * @return zero on success, non-zero if the key was not found
- * 
- * @see cxMapStorePointers()
- * @see cxMapRemove()
- */
 cx_attr_nonnull
 cx_attr_access_w(3)
 cx_attr_cstr_arg(2)
@@ -672,12 +532,7 @@
 #else // __cplusplus
 
 /**
- * Puts a key/value-pair into the map.
- *
- * @param map the map
- * @param key the key
- * @param value the value
- * @return 0 on success, non-zero value on failure
+ * @copydoc cxMapPut()
  */
 cx_attr_nonnull
 static inline int cx_map_put(
@@ -689,12 +544,7 @@
 }
 
 /**
- * Puts a key/value-pair into the map.
- *
- * @param map the map
- * @param key the key
- * @param value the value
- * @return 0 on success, non-zero value on failure
+ * @copydoc cxMapPut()
  */
 cx_attr_nonnull
 static inline int cx_map_put_cxstr(
@@ -706,12 +556,7 @@
 }
 
 /**
- * Puts a key/value-pair into the map.
- *
- * @param map the map
- * @param key the key
- * @param value the value
- * @return 0 on success, non-zero value on failure
+ * @copydoc cxMapPut()
  */
 cx_attr_nonnull
 static inline int cx_map_put_mustr(
@@ -723,12 +568,7 @@
 }
 
 /**
- * Puts a key/value-pair into the map.
- *
- * @param map the map
- * @param key the key
- * @param value the value
- * @return 0 on success, non-zero value on failure
+ * @copydoc cxMapPut()
  */
 cx_attr_nonnull
 cx_attr_cstr_arg(2)
@@ -743,10 +583,21 @@
 /**
  * Puts a key/value-pair into the map.
  *
- * @param map the map
- * @param key the key
- * @param value the value
- * @return 0 on success, non-zero value on failure
+ * 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 (@c CxMap*) the map
+ * @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 value on memory allocation failure
  */
 #define cxMapPut(map, key, value) _Generic((key), \
     CxHashKey: cx_map_put,                        \
@@ -757,11 +608,7 @@
     (map, key, value)
 
 /**
- * Retrieves a value by using a key.
- *
- * @param map the map
- * @param key the key
- * @return the value
+ * @copydoc cxMapGet()
  */
 cx_attr_nonnull
 cx_attr_nodiscard
@@ -773,11 +620,7 @@
 }
 
 /**
- * Retrieves a value by using a key.
- *
- * @param map the map
- * @param key the key
- * @return the value
+ * @copydoc cxMapGet()
  */
 cx_attr_nonnull
 cx_attr_nodiscard
@@ -789,11 +632,7 @@
 }
 
 /**
- * Retrieves a value by using a key.
- *
- * @param map the map
- * @param key the key
- * @return the value
+ * @copydoc cxMapGet()
  */
 cx_attr_nonnull
 cx_attr_nodiscard
@@ -805,11 +644,7 @@
 }
 
 /**
- * Retrieves a value by using a key.
- *
- * @param map the map
- * @param key the key
- * @return the value
+ * @copydoc cxMapGet()
  */
 cx_attr_nonnull
 cx_attr_nodiscard
@@ -824,9 +659,13 @@
 /**
  * Retrieves a value by using a key.
  *
- * @param map the map
- * @param key the key
- * @return the value
+ * 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 (@c CxMap*) the map
+ * @param key (@c CxHashKey, @c char*, @c cxstring, or @c cxmutstr) the key
+ * @return (@c void*) the value
  */
 #define cxMapGet(map, key) _Generic((key), \
     CxHashKey: cx_map_get,                 \
@@ -837,13 +676,7 @@
     (map, key)
 
 /**
- * Removes a key/value-pair from the map by using the key.
- *
- * Always invokes the destructors functions, if any, on the removed element.
- *
- * @param map the map
- * @param key the key
- * @return zero on success, non-zero if the key was not found
+ * @copydoc cxMapRemove()
  */
 cx_attr_nonnull
 static inline int cx_map_remove(
@@ -854,13 +687,7 @@
 }
 
 /**
- * Removes a key/value-pair from the map by using the key.
- *
- * Always invokes the destructors functions, if any, on the removed element.
- *
- * @param map the map
- * @param key the key
- * @return zero on success, non-zero if the key was not found
+ * @copydoc cxMapRemove()
  */
 cx_attr_nonnull
 static inline int cx_map_remove_cxstr(
@@ -871,13 +698,7 @@
 }
 
 /**
- * Removes a key/value-pair from the map by using the key.
- *
- * Always invokes the destructors functions, if any, on the removed element.
- *
- * @param map the map
- * @param key the key
- * @return zero on success, non-zero if the key was not found
+ * @copydoc cxMapRemove()
  */
 cx_attr_nonnull
 static inline int cx_map_remove_mustr(
@@ -888,13 +709,7 @@
 }
 
 /**
- * Removes a key/value-pair from the map by using the key.
- *
- * Always invokes the destructors functions, if any, on the removed element.
- *
- * @param map the map
- * @param key the key
- * @return zero on success, non-zero if the key was not found
+ * @copydoc cxMapRemove()
  */
 cx_attr_nonnull
 cx_attr_cstr_arg(2)
@@ -910,9 +725,10 @@
  *
  * Always invokes the destructors functions, if any, on the removed element.
  *
- * @param map the map
- * @param key the key
- * @return zero on success, non-zero if the key was not found
+ * @param map (@c CxMap*) the map
+ * @param key (@c CxHashKey, @c char*, @c cxstring, or @c cxmutstr) the key
+ * @retval zero success
+ * @retval non-zero the key was not found
  * 
  * @see cxMapRemoveAndGet()
  */
@@ -925,19 +741,7 @@
     (map, key)
 
 /**
- * Removes a key/value-pair from the map by using the key.
- *
- * This function will copy the contents to the target buffer
- * which must be guaranteed to be large enough to hold the element.
- * The destructor functions, if any, will \em not be called.
- *
- * If this map is storing pointers, the element is the pointer itself
- * and not the object it points to.
- *
- * @param map the map
- * @param key the key
- * @param targetbuf the buffer where the element shall be copied to
- * @return zero on success, non-zero if the key was not found
+ * @copydoc cxMapRemoveAndGet()
  */
 cx_attr_nonnull
 cx_attr_access_w(3)
@@ -950,19 +754,7 @@
 }
 
 /**
- * Removes a key/value-pair from the map by using the key.
- *
- * This function will copy the contents to the target buffer
- * which must be guaranteed to be large enough to hold the element.
- * The destructor functions, if any, will \em not be called.
- *
- * If this map is storing pointers, the element is the pointer itself
- * and not the object it points to.
- *
- * @param map the map
- * @param key the key
- * @param targetbuf the buffer where the element shall be copied to
- * @return zero on success, non-zero if the key was not found
+ * @copydoc cxMapRemoveAndGet()
  */
 cx_attr_nonnull
 cx_attr_access_w(3)
@@ -975,19 +767,7 @@
 }
 
 /**
- * Removes a key/value-pair from the map by using the key.
- *
- * This function will copy the contents to the target buffer
- * which must be guaranteed to be large enough to hold the element.
- * The destructor functions, if any, will \em not be called.
- *
- * If this map is storing pointers, the element is the pointer itself
- * and not the object it points to.
- *
- * @param map the map
- * @param key the key
- * @param targetbuf the buffer where the element shall be copied to
- * @return zero on success, non-zero if the key was not found
+ * @copydoc cxMapRemoveAndGet()
  */
 cx_attr_nonnull
 cx_attr_access_w(3)
@@ -1000,19 +780,7 @@
 }
 
 /**
- * Removes a key/value-pair from the map by using the key.
- *
- * This function will copy the contents to the target buffer
- * which must be guaranteed to be large enough to hold the element.
- * The destructor functions, if any, will \em not be called.
- *
- * If this map is storing pointers, the element is the pointer itself
- * and not the object it points to.
- *
- * @param map the map
- * @param key the key
- * @param targetbuf the buffer where the element shall be copied to
- * @return zero on success, non-zero if the key was not found
+ * @copydoc cxMapRemoveAndGet()
  */
 cx_attr_nonnull
 cx_attr_access_w(3)
@@ -1028,19 +796,20 @@
 /**
  * Removes a key/value-pair from the map by using the key.
  *
- * This function will copy the contents to the target buffer
- * which must be guaranteed to be large enough to hold the element.
- * The destructor functions, if any, will \em not be called.
+ * This function will copy the contents of the removed element
+ * to the target buffer, which must be guaranteed to be large enough
+ * to hold the element (the map's element size).
+ * The destructor functions, if any, will @em not be called.
  *
  * If this map is storing pointers, the element is the pointer itself
  * and not the object it points to.
  *
- * @param map the map
- * @param key the key
- * @param targetbuf the buffer where the element shall be copied to
- * @return zero on success, non-zero if the key was not found
- * 
- * @see cxMapStorePointers()
+ * @param map (@c CxMap*) the map
+ * @param key (@c CxHashKey, @c char*, @c cxstring, or @c cxmutstr) 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()
  */
 #define cxMapRemoveAndGet(map, key, targetbuf) _Generic((key), \

mercurial