diff -r 80f9d007cb52 -r 0aa8cbd7912e ucx/cx/map.h --- a/ucx/cx/map.h Fri Jan 03 21:40:57 2025 +0100 +++ b/ucx/cx/map.h Sat Jan 04 13:03:01 2025 +0100 @@ -89,19 +89,19 @@ /** * Deallocates the entire memory. */ - __attribute__((__nonnull__)) - void (*destructor)(struct cx_map_s *map); + cx_attr_nonnull + void (*deallocate)(struct cx_map_s *map); /** * Removes all elements. */ - __attribute__((__nonnull__)) + cx_attr_nonnull void (*clear)(struct cx_map_s *map); /** * Add or overwrite an element. */ - __attribute__((__nonnull__)) + cx_attr_nonnull int (*put)( CxMap *map, CxHashKey key, @@ -111,27 +111,37 @@ /** * Returns an element. */ - __attribute__((__nonnull__, __warn_unused_result__)) + cx_attr_nonnull + cx_attr_nodiscard void *(*get)( - CxMap const *map, + const CxMap *map, CxHashKey key ); /** * Removes an element. + * + * 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. + * + * The function SHALL return zero when the \p key was found and + * non-zero, otherwise. */ - __attribute__((__nonnull__)) - void *(*remove)( + cx_attr_nonnull_arg(1) + cx_attr_access_w(3) + int (*remove)( CxMap *map, CxHashKey key, - bool destroy + void *targetbuf ); /** * Creates an iterator for this map. */ - __attribute__((__nonnull__, __warn_unused_result__)) - CxIterator (*iterator)(CxMap const *map, enum cx_map_iterator_type type); + cx_attr_nonnull + cx_attr_nodiscard + CxIterator (*iterator)(const CxMap *map, enum cx_map_iterator_type type); }; /** @@ -141,7 +151,7 @@ /** * A pointer to the key. */ - CxHashKey const *key; + const CxHashKey *key; /** * A pointer to the value. */ @@ -151,7 +161,7 @@ /** * A shared instance of an empty map. * - * Writing to that map is undefined. + * Writing to that map is not allowed. */ extern CxMap *const cxEmptyMap; @@ -164,7 +174,7 @@ * @param map the map * @see cxMapStorePointers() */ -__attribute__((__nonnull__)) +cx_attr_nonnull static inline void cxMapStoreObjects(CxMap *map) { map->collection.store_pointer = false; } @@ -181,7 +191,7 @@ * @param map the map * @see cxMapStoreObjects() */ -__attribute__((__nonnull__)) +cx_attr_nonnull static inline void cxMapStorePointers(CxMap *map) { map->collection.store_pointer = true; map->collection.elem_size = sizeof(void *); @@ -194,19 +204,19 @@ * @return true, if this map is storing pointers * @see cxMapStorePointers() */ -__attribute__((__nonnull__)) -static inline bool cxMapIsStoringPointers(CxMap const *map) { +cx_attr_nonnull +static inline bool cxMapIsStoringPointers(const CxMap *map) { return map->collection.store_pointer; } /** * Deallocates the memory of the specified map. * - * @param map the map to be destroyed + * @param map the map to be freed */ -__attribute__((__nonnull__)) -static inline void cxMapDestroy(CxMap *map) { - map->cl->destructor(map); +static inline void cxMapFree(CxMap *map) { + if (map == NULL) return; + map->cl->deallocate(map); } @@ -215,7 +225,7 @@ * * @param map the map to be cleared */ -__attribute__((__nonnull__)) +cx_attr_nonnull static inline void cxMapClear(CxMap *map) { map->cl->clear(map); } @@ -226,8 +236,8 @@ * @param map the map * @return the number of stored elements */ -__attribute__((__nonnull__)) -static inline size_t cxMapSize(CxMap const *map) { +cx_attr_nonnull +static inline size_t cxMapSize(const CxMap *map) { return map->collection.size; } @@ -237,14 +247,15 @@ /** * Creates a value iterator for a map. * - * \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 * @return an iterator for the currently stored values */ -__attribute__((__nonnull__, __warn_unused_result__)) -static inline CxIterator cxMapIteratorValues(CxMap const *map) { +cx_attr_nonnull +cx_attr_nodiscard +static inline CxIterator cxMapIteratorValues(const CxMap *map) { return map->cl->iterator(map, CX_MAP_ITERATOR_VALUES); } @@ -253,14 +264,15 @@ * * The elements of the iterator are keys of type 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 * @return an iterator for the currently stored keys */ -__attribute__((__nonnull__, __warn_unused_result__)) -static inline CxIterator cxMapIteratorKeys(CxMap const *map) { +cx_attr_nonnull +cx_attr_nodiscard +static inline CxIterator cxMapIteratorKeys(const CxMap *map) { return map->cl->iterator(map, CX_MAP_ITERATOR_KEYS); } @@ -269,7 +281,7 @@ * * The elements of the iterator are key/value pairs of type 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 @@ -277,8 +289,9 @@ * @see cxMapIteratorKeys() * @see cxMapIteratorValues() */ -__attribute__((__nonnull__, __warn_unused_result__)) -static inline CxIterator cxMapIterator(CxMap const *map) { +cx_attr_nonnull +cx_attr_nodiscard +static inline CxIterator cxMapIterator(const CxMap *map) { return map->cl->iterator(map, CX_MAP_ITERATOR_PAIRS); } @@ -286,13 +299,14 @@ /** * Creates a mutating iterator over the values of a map. * - * \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 * @return an iterator for the currently stored values */ -__attribute__((__nonnull__, __warn_unused_result__)) +cx_attr_nonnull +cx_attr_nodiscard CxIterator cxMapMutIteratorValues(CxMap *map); /** @@ -300,13 +314,14 @@ * * The elements of the iterator are keys of type 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 * @return an iterator for the currently stored keys */ -__attribute__((__nonnull__, __warn_unused_result__)) +cx_attr_nonnull +cx_attr_nodiscard CxIterator cxMapMutIteratorKeys(CxMap *map); /** @@ -314,7 +329,7 @@ * * The elements of the iterator are key/value pairs of type 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 @@ -322,7 +337,8 @@ * @see cxMapMutIteratorKeys() * @see cxMapMutIteratorValues() */ -__attribute__((__nonnull__, __warn_unused_result__)) +cx_attr_nonnull +cx_attr_nodiscard CxIterator cxMapMutIterator(CxMap *map); #ifdef __cplusplus @@ -336,7 +352,7 @@ * @param value the value * @return 0 on success, non-zero value on failure */ -__attribute__((__nonnull__)) +cx_attr_nonnull static inline int cxMapPut( CxMap *map, CxHashKey const &key, @@ -354,7 +370,7 @@ * @param value the value * @return 0 on success, non-zero value on failure */ -__attribute__((__nonnull__)) +cx_attr_nonnull static inline int cxMapPut( CxMap *map, cxstring const &key, @@ -371,7 +387,7 @@ * @param value the value * @return 0 on success, non-zero value on failure */ -__attribute__((__nonnull__)) +cx_attr_nonnull static inline int cxMapPut( CxMap *map, cxmutstr const &key, @@ -388,10 +404,11 @@ * @param value the value * @return 0 on success, non-zero value on failure */ -__attribute__((__nonnull__)) +cx_attr_nonnull +cx_attr_cstr_arg(2) static inline int cxMapPut( CxMap *map, - char const *key, + const char *key, void *value ) { return map->cl->put(map, cx_hash_key_str(key), value); @@ -404,9 +421,10 @@ * @param key the key * @return the value */ -__attribute__((__nonnull__, __warn_unused_result__)) +cx_attr_nonnull +cx_attr_nodiscard static inline void *cxMapGet( - CxMap const *map, + const CxMap *map, CxHashKey const &key ) { return map->cl->get(map, key); @@ -419,9 +437,10 @@ * @param key the key * @return the value */ -__attribute__((__nonnull__, __warn_unused_result__)) +cx_attr_nonnull +cx_attr_nodiscard static inline void *cxMapGet( - CxMap const *map, + const CxMap *map, cxstring const &key ) { return map->cl->get(map, cx_hash_key_cxstr(key)); @@ -434,9 +453,10 @@ * @param key the key * @return the value */ -__attribute__((__nonnull__, __warn_unused_result__)) +cx_attr_nonnull +cx_attr_nodiscard static inline void *cxMapGet( - CxMap const *map, + const CxMap *map, cxmutstr const &key ) { return map->cl->get(map, cx_hash_key_cxstr(key)); @@ -449,10 +469,12 @@ * @param key the key * @return the value */ -__attribute__((__nonnull__, __warn_unused_result__)) +cx_attr_nonnull +cx_attr_nodiscard +cx_attr_cstr_arg(2) static inline void *cxMapGet( - CxMap const *map, - char const *key + const CxMap *map, + const char *key ) { return map->cl->get(map, cx_hash_key_str(key)); } @@ -460,285 +482,191 @@ /** * Removes a key/value-pair from the map by using the key. * - * Always invokes the destructor function, if any, on the removed element. - * If this map is storing pointers and you just want to retrieve the pointer - * without invoking the destructor, use cxMapRemoveAndGet(). - * If you just want to detach the element from the map without invoking the - * destructor or returning the element, use cxMapDetach(). + * 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() - * @see cxMapDetach() */ -__attribute__((__nonnull__)) -static inline void cxMapRemove( +cx_attr_nonnull +static inline int cxMapRemove( CxMap *map, CxHashKey const &key ) { - (void) map->cl->remove(map, key, true); + return map->cl->remove(map, key, nullptr); } /** * Removes a key/value-pair from the map by using the key. * - * Always invokes the destructor function, if any, on the removed element. - * If this map is storing pointers and you just want to retrieve the pointer - * without invoking the destructor, use cxMapRemoveAndGet(). - * If you just want to detach the element from the map without invoking the - * destructor or returning the element, use cxMapDetach(). + * 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() - * @see cxMapDetach() */ -__attribute__((__nonnull__)) -static inline void cxMapRemove( +cx_attr_nonnull +static inline int cxMapRemove( CxMap *map, cxstring const &key ) { - (void) map->cl->remove(map, cx_hash_key_cxstr(key), true); + 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 destructor function, if any, on the removed element. - * If this map is storing pointers and you just want to retrieve the pointer - * without invoking the destructor, use cxMapRemoveAndGet(). - * If you just want to detach the element from the map without invoking the - * destructor or returning the element, use cxMapDetach(). + * 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() - * @see cxMapDetach() */ -__attribute__((__nonnull__)) -static inline void cxMapRemove( +cx_attr_nonnull +static inline int cxMapRemove( CxMap *map, cxmutstr const &key ) { - (void) map->cl->remove(map, cx_hash_key_cxstr(key), true); + 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( + CxMap *map, + const char *key +) { + return map->cl->remove(map, cx_hash_key_str(key), nullptr); } /** * Removes a key/value-pair from the map by using the key. * - * Always invokes the destructor function, if any, on the removed element. - * If this map is storing pointers and you just want to retrieve the pointer - * without invoking the destructor, use cxMapRemoveAndGet(). - * If you just want to detach the element from the map without invoking the - * destructor or returning the element, use cxMapDetach(). - * - * @param map the map - * @param key the key - * @see cxMapRemoveAndGet() - * @see cxMapDetach() - */ -__attribute__((__nonnull__)) -static inline void cxMapRemove( - CxMap *map, - char const *key -) { - (void) map->cl->remove(map, cx_hash_key_str(key), true); -} - -/** - * Detaches a key/value-pair from the map by using the key - * without invoking the destructor. + * 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. * - * In general, you should only use this function if the map does not own - * the data and there is a valid reference to the data somewhere else - * in the program. In all other cases it is preferable to use - * cxMapRemove() or cxMapRemoveAndGet(). - * - * @param map the map - * @param key the key - * @see cxMapRemove() - * @see cxMapRemoveAndGet() - */ -__attribute__((__nonnull__)) -static inline void cxMapDetach( - CxMap *map, - CxHashKey const &key -) { - (void) map->cl->remove(map, key, false); -} - -/** - * Detaches a key/value-pair from the map by using the key - * without invoking the destructor. - * - * In general, you should only use this function if the map does not own - * the data and there is a valid reference to the data somewhere else - * in the program. In all other cases it is preferable to use - * cxMapRemove() or cxMapRemoveAndGet(). + * 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() - * @see cxMapRemoveAndGet() - */ -__attribute__((__nonnull__)) -static inline void cxMapDetach( - CxMap *map, - cxstring const &key -) { - (void) map->cl->remove(map, cx_hash_key_cxstr(key), false); -} - -/** - * Detaches a key/value-pair from the map by using the key - * without invoking the destructor. - * - * In general, you should only use this function if the map does not own - * the data and there is a valid reference to the data somewhere else - * in the program. In all other cases it is preferable to use - * cxMapRemove() or cxMapRemoveAndGet(). - * - * @param map the map - * @param key the key - * @see cxMapRemove() - * @see cxMapRemoveAndGet() */ -__attribute__((__nonnull__)) -static inline void cxMapDetach( +cx_attr_nonnull +cx_attr_access_w(3) +static inline int cxMapRemoveAndGet( CxMap *map, - cxmutstr const &key + CxHashKey key, + void *targetbuf ) { - (void) map->cl->remove(map, cx_hash_key_cxstr(key), false); -} - -/** - * Detaches a key/value-pair from the map by using the key - * without invoking the destructor. - * - * In general, you should only use this function if the map does not own - * the data and there is a valid reference to the data somewhere else - * in the program. In all other cases it is preferable to use - * cxMapRemove() or cxMapRemoveAndGet(). - * - * @param map the map - * @param key the key - * @see cxMapRemove() - * @see cxMapRemoveAndGet() - */ -__attribute__((__nonnull__)) -static inline void cxMapDetach( - CxMap *map, - char const *key -) { - (void) map->cl->remove(map, cx_hash_key_str(key), false); + return map->cl->remove(map, key, targetbuf); } /** * Removes a key/value-pair from the map by using the key. * - * This function can be used when the map is storing pointers, - * in order to retrieve the pointer from the map without invoking - * any destructor function. Sometimes you do not want the pointer - * to be returned - in that case (instead of suppressing the "unused - * result" warning) you can use cxMapDetach(). + * 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 not storing pointers, this function behaves like - * cxMapRemove() and returns \c NULL. + * 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 - * @return the stored pointer or \c NULL if either the key is not present - * in the map or the map is not storing pointers + * @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 cxMapDetach() + * @see cxMapRemove() */ -__attribute__((__nonnull__, __warn_unused_result__)) -static inline void *cxMapRemoveAndGet( +cx_attr_nonnull +cx_attr_access_w(3) +static inline int cxMapRemoveAndGet( CxMap *map, - CxHashKey key + cxstring key, + void *targetbuf ) { - return map->cl->remove(map, key, !map->store_pointer); + 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 can be used when the map is storing pointers, - * in order to retrieve the pointer from the map without invoking - * any destructor function. Sometimes you do not want the pointer - * to be returned - in that case (instead of suppressing the "unused - * result" warning) you can use cxMapDetach(). + * 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 not storing pointers, this function behaves like - * cxMapRemove() and returns \c NULL. + * 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 - * @return the stored pointer or \c NULL if either the key is not present - * in the map or the map is not storing pointers + * @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 cxMapDetach() + * @see cxMapRemove() */ -__attribute__((__nonnull__, __warn_unused_result__)) -static inline void *cxMapRemoveAndGet( +cx_attr_nonnull +cx_attr_access_w(3) +static inline int cxMapRemoveAndGet( CxMap *map, - cxstring key + cxmutstr key, + void *targetbuf ) { - return map->cl->remove(map, cx_hash_key_cxstr(key), !map->store_pointer); + 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 can be used when the map is storing pointers, - * in order to retrieve the pointer from the map without invoking - * any destructor function. Sometimes you do not want the pointer - * to be returned - in that case (instead of suppressing the "unused - * result" warning) you can use cxMapDetach(). + * 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 not storing pointers, this function behaves like - * cxMapRemove() and returns \c NULL. + * 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 - * @return the stored pointer or \c NULL if either the key is not present - * in the map or the map is not storing pointers + * @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 cxMapDetach() + * @see cxMapRemove() */ -__attribute__((__nonnull__, __warn_unused_result__)) -static inline void *cxMapRemoveAndGet( +cx_attr_nonnull +cx_attr_access_w(3) +cx_attr_cstr_arg(2) +static inline int cxMapRemoveAndGet( CxMap *map, - cxmutstr key + const char *key, + void *targetbuf ) { - return map->cl->remove(map, cx_hash_key_cxstr(key), !map->store_pointer); -} - -/** - * Removes a key/value-pair from the map by using the key. - * - * This function can be used when the map is storing pointers, - * in order to retrieve the pointer from the map without invoking - * any destructor function. Sometimes you do not want the pointer - * to be returned - in that case (instead of suppressing the "unused - * result" warning) you can use cxMapDetach(). - * - * If this map is not storing pointers, this function behaves like - * cxMapRemove() and returns \c NULL. - * - * @param map the map - * @param key the key - * @return the stored pointer or \c NULL if either the key is not present - * in the map or the map is not storing pointers - * @see cxMapStorePointers() - * @see cxMapDetach() - */ -__attribute__((__nonnull__, __warn_unused_result__)) -static inline void *cxMapRemoveAndGet( - CxMap *map, - char const *key -) { - return map->cl->remove(map, cx_hash_key_str(key), !map->store_pointer); + return map->cl->remove(map, cx_hash_key_str(key), targetbuf); } #else // __cplusplus @@ -751,7 +679,7 @@ * @param value the value * @return 0 on success, non-zero value on failure */ -__attribute__((__nonnull__)) +cx_attr_nonnull static inline int cx_map_put( CxMap *map, CxHashKey key, @@ -768,7 +696,7 @@ * @param value the value * @return 0 on success, non-zero value on failure */ -__attribute__((__nonnull__)) +cx_attr_nonnull static inline int cx_map_put_cxstr( CxMap *map, cxstring key, @@ -785,7 +713,7 @@ * @param value the value * @return 0 on success, non-zero value on failure */ -__attribute__((__nonnull__)) +cx_attr_nonnull static inline int cx_map_put_mustr( CxMap *map, cxmutstr key, @@ -802,10 +730,11 @@ * @param value the value * @return 0 on success, non-zero value on failure */ -__attribute__((__nonnull__)) +cx_attr_nonnull +cx_attr_cstr_arg(2) static inline int cx_map_put_str( CxMap *map, - char const *key, + const char *key, void *value ) { return map->cl->put(map, cx_hash_key_str(key), value); @@ -824,7 +753,7 @@ cxstring: cx_map_put_cxstr, \ cxmutstr: cx_map_put_mustr, \ char*: cx_map_put_str, \ - char const*: cx_map_put_str) \ + const char*: cx_map_put_str) \ (map, key, value) /** @@ -834,9 +763,10 @@ * @param key the key * @return the value */ -__attribute__((__nonnull__, __warn_unused_result__)) +cx_attr_nonnull +cx_attr_nodiscard static inline void *cx_map_get( - CxMap const *map, + const CxMap *map, CxHashKey key ) { return map->cl->get(map, key); @@ -849,9 +779,10 @@ * @param key the key * @return the value */ -__attribute__((__nonnull__, __warn_unused_result__)) +cx_attr_nonnull +cx_attr_nodiscard static inline void *cx_map_get_cxstr( - CxMap const *map, + const CxMap *map, cxstring key ) { return map->cl->get(map, cx_hash_key_cxstr(key)); @@ -864,9 +795,10 @@ * @param key the key * @return the value */ -__attribute__((__nonnull__, __warn_unused_result__)) +cx_attr_nonnull +cx_attr_nodiscard static inline void *cx_map_get_mustr( - CxMap const *map, + const CxMap *map, cxmutstr key ) { return map->cl->get(map, cx_hash_key_cxstr(key)); @@ -879,10 +811,12 @@ * @param key the key * @return the value */ -__attribute__((__nonnull__, __warn_unused_result__)) +cx_attr_nonnull +cx_attr_nodiscard +cx_attr_cstr_arg(2) static inline void *cx_map_get_str( - CxMap const *map, - char const *key + const CxMap *map, + const char *key ) { return map->cl->get(map, cx_hash_key_str(key)); } @@ -899,259 +833,223 @@ cxstring: cx_map_get_cxstr, \ cxmutstr: cx_map_get_mustr, \ char*: cx_map_get_str, \ - char const*: cx_map_get_str) \ + const char*: cx_map_get_str) \ (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 */ -__attribute__((__nonnull__)) -static inline void cx_map_remove( +cx_attr_nonnull +static inline int cx_map_remove( CxMap *map, CxHashKey key ) { - (void) map->cl->remove(map, key, true); + return map->cl->remove(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. + * * @param map the map * @param key the key + * @return zero on success, non-zero if the key was not found */ -__attribute__((__nonnull__)) -static inline void cx_map_remove_cxstr( +cx_attr_nonnull +static inline int cx_map_remove_cxstr( CxMap *map, cxstring key ) { - (void) map->cl->remove(map, cx_hash_key_cxstr(key), true); + return map->cl->remove(map, cx_hash_key_cxstr(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. + * * @param map the map * @param key the key + * @return zero on success, non-zero if the key was not found */ -__attribute__((__nonnull__)) -static inline void cx_map_remove_mustr( +cx_attr_nonnull +static inline int cx_map_remove_mustr( CxMap *map, cxmutstr key ) { - (void) map->cl->remove(map, cx_hash_key_cxstr(key), true); + return map->cl->remove(map, cx_hash_key_cxstr(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. + * * @param map the map * @param key the key + * @return zero on success, non-zero if the key was not found */ -__attribute__((__nonnull__)) -static inline void cx_map_remove_str( +cx_attr_nonnull +cx_attr_cstr_arg(2) +static inline int cx_map_remove_str( CxMap *map, - char const *key + const char *key ) { - (void) map->cl->remove(map, cx_hash_key_str(key), true); + return map->cl->remove(map, cx_hash_key_str(key), NULL); } /** * Removes a key/value-pair from the map by using the key. * - * Always invokes the destructor function, if any, on the removed element. - * If this map is storing pointers and you just want to retrieve the pointer - * without invoking the destructor, use cxMapRemoveAndGet(). - * If you just want to detach the element from the map without invoking the - * destructor or returning the element, use cxMapDetach(). + * 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() - * @see cxMapDetach() */ #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, \ - char const*: cx_map_remove_str) \ - (map, key) - -/** - * Detaches a key/value-pair from the map by using the key - * without invoking the destructor. - * - * @param map the map - * @param key the key - */ -__attribute__((__nonnull__)) -static inline void cx_map_detach( - CxMap *map, - CxHashKey key -) { - (void) map->cl->remove(map, key, false); -} - -/** - * Detaches a key/value-pair from the map by using the key - * without invoking the destructor. - * - * @param map the map - * @param key the key - */ -__attribute__((__nonnull__)) -static inline void cx_map_detach_cxstr( - CxMap *map, - cxstring key -) { - (void) map->cl->remove(map, cx_hash_key_cxstr(key), false); -} - -/** - * Detaches a key/value-pair from the map by using the key - * without invoking the destructor. - * - * @param map the map - * @param key the key - */ -__attribute__((__nonnull__)) -static inline void cx_map_detach_mustr( - CxMap *map, - cxmutstr key -) { - (void) map->cl->remove(map, cx_hash_key_cxstr(key), false); -} - -/** - * Detaches a key/value-pair from the map by using the key - * without invoking the destructor. - * - * @param map the map - * @param key the key - */ -__attribute__((__nonnull__)) -static inline void cx_map_detach_str( - CxMap *map, - char const *key -) { - (void) map->cl->remove(map, cx_hash_key_str(key), false); -} - -/** - * Detaches a key/value-pair from the map by using the key - * without invoking the destructor. - * - * In general, you should only use this function if the map does not own - * the data and there is a valid reference to the data somewhere else - * in the program. In all other cases it is preferable to use - * cxMapRemove() or cxMapRemoveAndGet(). - * - * @param map the map - * @param key the key - * @see cxMapRemove() - * @see cxMapRemoveAndGet() - */ -#define cxMapDetach(map, key) _Generic((key), \ - CxHashKey: cx_map_detach, \ - cxstring: cx_map_detach_cxstr, \ - cxmutstr: cx_map_detach_mustr, \ - char*: cx_map_detach_str, \ - char const*: cx_map_detach_str) \ + const char*: cx_map_remove_str) \ (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 - * @return the stored pointer or \c NULL if either the key is not present - * in the map or the map is not storing pointers + * @param targetbuf the buffer where the element shall be copied to + * @return zero on success, non-zero if the key was not found */ -__attribute__((__nonnull__, __warn_unused_result__)) -static inline void *cx_map_remove_and_get( +cx_attr_nonnull +cx_attr_access_w(3) +static inline int cx_map_remove_and_get( CxMap *map, - CxHashKey key + CxHashKey key, + void *targetbuf ) { - return map->cl->remove(map, key, !map->collection.store_pointer); + 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 - * @return the stored pointer or \c NULL if either the key is not present - * in the map or the map is not storing pointers + * @param targetbuf the buffer where the element shall be copied to + * @return zero on success, non-zero if the key was not found */ -__attribute__((__nonnull__, __warn_unused_result__)) -static inline void *cx_map_remove_and_get_cxstr( +cx_attr_nonnull +cx_attr_access_w(3) +static inline int cx_map_remove_and_get_cxstr( CxMap *map, - cxstring key + cxstring key, + void *targetbuf ) { - return map->cl->remove(map, cx_hash_key_cxstr(key), !map->collection.store_pointer); + 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 - * @return the stored pointer or \c NULL if either the key is not present - * in the map or the map is not storing pointers + * @param targetbuf the buffer where the element shall be copied to + * @return zero on success, non-zero if the key was not found */ -__attribute__((__nonnull__, __warn_unused_result__)) -static inline void *cx_map_remove_and_get_mustr( +cx_attr_nonnull +cx_attr_access_w(3) +static inline int cx_map_remove_and_get_mustr( CxMap *map, - cxmutstr key + cxmutstr key, + void *targetbuf ) { - return map->cl->remove(map, cx_hash_key_cxstr(key), !map->collection.store_pointer); + 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 - * @return the stored pointer or \c NULL if either the key is not present - * in the map or the map is not storing pointers + * @param targetbuf the buffer where the element shall be copied to + * @return zero on success, non-zero if the key was not found */ -__attribute__((__nonnull__, __warn_unused_result__)) -static inline void *cx_map_remove_and_get_str( +cx_attr_nonnull +cx_attr_access_w(3) +cx_attr_cstr_arg(2) +static inline int cx_map_remove_and_get_str( CxMap *map, - char const *key + const char *key, + void *targetbuf ) { - return map->cl->remove(map, cx_hash_key_str(key), !map->collection.store_pointer); + return map->cl->remove(map, cx_hash_key_str(key), targetbuf); } /** * Removes a key/value-pair from the map by using the key. * - * This function can be used when the map is storing pointers, - * in order to retrieve the pointer from the map without invoking - * any destructor function. Sometimes you do not want the pointer - * to be returned - in that case (instead of suppressing the "unused - * result" warning) you can use cxMapDetach(). + * 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 not storing pointers, this function behaves like - * cxMapRemove() and returns \c NULL. + * 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 - * @return the stored pointer or \c NULL if either the key is not present - * in the map or the map is not storing pointers + * @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 cxMapDetach() + * @see cxMapRemove() */ -#define cxMapRemoveAndGet(map, key) _Generic((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, \ - char const*: cx_map_remove_and_get_str) \ - (map, key) + const char*: cx_map_remove_and_get_str) \ + (map, key, targetbuf) #endif // __cplusplus