--- 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), \