--- a/src/cx/map.h Tue Nov 26 22:16:27 2024 +0100 +++ b/src/cx/map.h Wed Nov 27 22:33:30 2024 +0100 @@ -120,12 +120,20 @@ /** * 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. */ - cx_attr_nonnull - void *(*remove)( + cx_attr_nonnull_arg(1) + cx_attr_access_w(3) + int (*remove)( CxMap *map, CxHashKey key, - bool destroy + void *targetbuf ); /** @@ -474,292 +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() */ cx_attr_nonnull -static inline void cxMapRemove( +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() */ cx_attr_nonnull -static inline void cxMapRemove( +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() */ cx_attr_nonnull -static inline void cxMapRemove( +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() - */ -cx_attr_nonnull -cx_attr_cstr_arg(2) -static inline void cxMapRemove( - CxMap *map, - const char *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() - */ -cx_attr_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() - */ -cx_attr_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() */ cx_attr_nonnull -static inline void cxMapDetach( +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() - */ -cx_attr_nonnull -cx_attr_cstr_arg(2) -static inline void cxMapDetach( - CxMap *map, - const char *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() */ cx_attr_nonnull -cx_attr_nodiscard -static inline void *cxMapRemoveAndGet( +cx_attr_access_w(3) +static inline int cxMapRemoveAndGet( CxMap *map, - CxHashKey key + cxstring key, + void *targetbuf ) { - return map->cl->remove(map, 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 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() */ cx_attr_nonnull -cx_attr_nodiscard -static inline void *cxMapRemoveAndGet( +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->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 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() */ cx_attr_nonnull -cx_attr_nodiscard -static inline void *cxMapRemoveAndGet( +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->collection.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() - */ -cx_attr_nonnull -cx_attr_nodiscard -cx_attr_cstr_arg(2) -static inline void *cxMapRemoveAndGet( - CxMap *map, - const char *key -) { - 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); } #else // __cplusplus @@ -932,73 +839,82 @@ /** * 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 */ cx_attr_nonnull -static inline void cx_map_remove( +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 */ cx_attr_nonnull -static inline void cx_map_remove_cxstr( +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 */ cx_attr_nonnull -static inline void cx_map_remove_mustr( +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 */ cx_attr_nonnull cx_attr_cstr_arg(2) -static inline void cx_map_remove_str( +static inline int cx_map_remove_str( CxMap *map, 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, \ @@ -1009,183 +925,131 @@ (map, key) /** - * Detaches a key/value-pair from the map by using the key - * without invoking the destructor. + * Removes a key/value-pair from the map by using the key. * - * @param map the map - * @param key the key - */ -cx_attr_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. + * 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. * - * @param map the map - * @param key the key - */ -cx_attr_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. + * 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 - */ -cx_attr_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 + * @param targetbuf the buffer where the element shall be copied to + * @return zero on success, non-zero if the key was not found */ cx_attr_nonnull -cx_attr_cstr_arg(2) -static inline void cx_map_detach_str( +cx_attr_access_w(3) +static inline int cx_map_remove_and_get( CxMap *map, - const char *key + CxHashKey key, + void *targetbuf ) { - (void) map->cl->remove(map, cx_hash_key_str(key), false); + return map->cl->remove(map, key, targetbuf); } /** - * 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, \ - const char*: cx_map_detach_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 */ cx_attr_nonnull -cx_attr_nodiscard -static inline void *cx_map_remove_and_get( +cx_attr_access_w(3) +static inline int cx_map_remove_and_get_cxstr( CxMap *map, - CxHashKey key + cxstring key, + void *targetbuf ) { - return map->cl->remove(map, 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. * - * @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 - */ -cx_attr_nonnull -cx_attr_nodiscard -static inline void *cx_map_remove_and_get_cxstr( - CxMap *map, - cxstring key -) { - return map->cl->remove(map, cx_hash_key_cxstr(key), !map->collection.store_pointer); -} - -/** - * 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 */ cx_attr_nonnull -cx_attr_nodiscard -static inline void *cx_map_remove_and_get_mustr( +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 */ cx_attr_nonnull -cx_attr_nodiscard +cx_attr_access_w(3) cx_attr_cstr_arg(2) -static inline void *cx_map_remove_and_get_str( +static inline int cx_map_remove_and_get_str( CxMap *map, - const char *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, \ const char*: cx_map_remove_and_get_str) \ - (map, key) + (map, key, targetbuf) #endif // __cplusplus