universe@549: /* universe@549: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. universe@549: * universe@549: * Copyright 2021 Mike Becker, Olaf Wintermann All rights reserved. universe@549: * universe@549: * Redistribution and use in source and binary forms, with or without universe@549: * modification, are permitted provided that the following conditions are met: universe@549: * universe@549: * 1. Redistributions of source code must retain the above copyright universe@549: * notice, this list of conditions and the following disclaimer. universe@549: * universe@549: * 2. Redistributions in binary form must reproduce the above copyright universe@549: * notice, this list of conditions and the following disclaimer in the universe@549: * documentation and/or other materials provided with the distribution. universe@549: * universe@549: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" universe@549: * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE universe@549: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE universe@549: * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE universe@549: * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR universe@549: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF universe@549: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS universe@549: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN universe@549: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) universe@549: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE universe@549: * POSSIBILITY OF SUCH DAMAGE. universe@549: */ universe@549: /** universe@549: * \file map.h universe@549: * \brief Interface for map implementations. universe@549: * \author Mike Becker universe@549: * \author Olaf Wintermann universe@549: * \version 3.0 universe@549: * \copyright 2-Clause BSD License universe@549: */ universe@549: universe@549: #ifndef UCX_MAP_H universe@549: #define UCX_MAP_H universe@549: universe@681: #include "common.h" universe@677: #include "collection.h" universe@691: #include "string.h" universe@563: #include "hash_key.h" universe@549: universe@549: #ifdef __cplusplus universe@549: extern "C" { universe@549: #endif universe@549: universe@549: /** Type for the UCX map. */ universe@549: typedef struct cx_map_s CxMap; universe@549: universe@549: /** Type for a map entry. */ universe@549: typedef struct cx_map_entry_s CxMapEntry; universe@549: universe@549: /** Type for map class definitions. */ universe@549: typedef struct cx_map_class_s cx_map_class; universe@549: universe@549: /** Structure for the UCX map. */ universe@549: struct cx_map_s { universe@685: CX_COLLECTION_MEMBERS universe@549: /** The map class definition. */ universe@549: cx_map_class *cl; universe@549: }; universe@549: universe@549: /** universe@709: * The type of iterator for a map. universe@709: */ universe@709: enum cx_map_iterator_type { universe@709: /** universe@709: * Iterates over key/value pairs. universe@709: */ universe@709: CX_MAP_ITERATOR_PAIRS, universe@709: /** universe@709: * Iterates over keys only. universe@709: */ universe@709: CX_MAP_ITERATOR_KEYS, universe@709: /** universe@709: * Iterates over values only. universe@709: */ universe@709: CX_MAP_ITERATOR_VALUES universe@709: }; universe@709: universe@709: /** universe@549: * The class definition for arbitrary maps. universe@549: */ universe@549: struct cx_map_class_s { universe@549: /** universe@549: * Deallocates the entire memory. universe@549: */ universe@549: __attribute__((__nonnull__)) universe@549: void (*destructor)(struct cx_map_s *map); universe@549: universe@549: /** universe@549: * Removes all elements. universe@549: */ universe@549: __attribute__((__nonnull__)) universe@549: void (*clear)(struct cx_map_s *map); universe@549: universe@549: /** universe@549: * Add or overwrite an element. universe@549: */ universe@549: __attribute__((__nonnull__)) universe@549: int (*put)( universe@549: CxMap *map, universe@563: CxHashKey key, universe@550: void *value universe@549: ); universe@549: universe@549: /** universe@549: * Returns an element. universe@549: */ universe@549: __attribute__((__nonnull__, __warn_unused_result__)) universe@549: void *(*get)( universe@549: CxMap const *map, universe@563: CxHashKey key universe@549: ); universe@549: universe@549: /** universe@549: * Removes an element. universe@549: */ universe@659: __attribute__((__nonnull__)) universe@549: void *(*remove)( universe@550: CxMap *map, universe@686: CxHashKey key, universe@686: bool destroy universe@549: ); universe@549: universe@549: /** universe@709: * Creates an iterator for this map. universe@549: */ universe@549: __attribute__((__nonnull__, __warn_unused_result__)) universe@709: CxIterator (*iterator)(CxMap const *map, enum cx_map_iterator_type type); universe@549: }; universe@549: universe@549: /** universe@549: * A map entry. universe@549: */ universe@549: struct cx_map_entry_s { universe@549: /** universe@551: * A pointer to the key. universe@549: */ universe@563: CxHashKey const *key; universe@549: /** universe@551: * A pointer to the value. universe@549: */ universe@551: void *value; universe@549: }; universe@549: universe@706: extern CxMap *const cxEmptyMap; universe@706: universe@658: /** universe@658: * Advises the map to store copies of the objects (default mode of operation). universe@658: * universe@658: * Retrieving objects from this map will yield pointers to the copies stored universe@658: * within this list. universe@658: * universe@658: * @param map the map universe@658: * @see cxMapStorePointers() universe@658: */ universe@658: __attribute__((__nonnull__)) universe@658: static inline void cxMapStoreObjects(CxMap *map) { universe@685: map->store_pointer = false; universe@658: } universe@658: universe@658: /** universe@658: * Advises the map to only store pointers to the objects. universe@658: * universe@658: * Retrieving objects from this list will yield the original pointers stored. universe@658: * universe@658: * @note This function forcibly sets the element size to the size of a pointer. universe@658: * Invoking this function on a non-empty map that already stores copies of universe@658: * objects is undefined. universe@658: * universe@658: * @param map the map universe@658: * @see cxMapStoreObjects() universe@658: */ universe@658: __attribute__((__nonnull__)) universe@658: static inline void cxMapStorePointers(CxMap *map) { universe@685: map->store_pointer = true; universe@677: map->item_size = sizeof(void *); universe@658: } universe@658: universe@549: universe@549: /** universe@549: * Deallocates the memory of the specified map. universe@549: * universe@549: * @param map the map to be destroyed universe@549: */ universe@549: __attribute__((__nonnull__)) universe@549: static inline void cxMapDestroy(CxMap *map) { universe@549: map->cl->destructor(map); universe@549: } universe@549: universe@549: universe@549: /** universe@549: * Clears a map by removing all elements. universe@549: * universe@549: * @param map the map to be cleared universe@549: */ universe@549: __attribute__((__nonnull__)) universe@549: static inline void cxMapClear(CxMap *map) { universe@549: map->cl->clear(map); universe@549: } universe@549: universe@549: universe@549: // TODO: set-like map operations (union, intersect, difference) universe@549: universe@549: /** universe@549: * Creates a value iterator for a map. universe@549: * universe@549: * \note An iterator iterates over all elements successively. Therefore the order universe@549: * highly depends on the map implementation and may change arbitrarily when the contents change. universe@549: * universe@549: * @param map the map to create the iterator for universe@549: * @return an iterator for the currently stored values universe@549: */ universe@549: __attribute__((__nonnull__, __warn_unused_result__)) universe@710: static inline CxIterator cxMapIteratorValues(CxMap const *map) { universe@709: return map->cl->iterator(map, CX_MAP_ITERATOR_VALUES); universe@549: } universe@549: universe@549: /** universe@549: * Creates a key iterator for a map. universe@549: * universe@564: * The elements of the iterator are keys of type CxHashKey. universe@555: * universe@549: * \note An iterator iterates over all elements successively. Therefore the order universe@549: * highly depends on the map implementation and may change arbitrarily when the contents change. universe@549: * universe@549: * @param map the map to create the iterator for universe@549: * @return an iterator for the currently stored keys universe@549: */ universe@549: __attribute__((__nonnull__, __warn_unused_result__)) universe@710: static inline CxIterator cxMapIteratorKeys(CxMap const *map) { universe@709: return map->cl->iterator(map, CX_MAP_ITERATOR_KEYS); universe@549: } universe@549: universe@549: /** universe@549: * Creates an iterator for a map. universe@549: * universe@555: * The elements of the iterator are key/value pairs of type CxMapEntry. universe@549: * universe@549: * \note An iterator iterates over all elements successively. Therefore the order universe@549: * highly depends on the map implementation and may change arbitrarily when the contents change. universe@549: * universe@549: * @param map the map to create the iterator for universe@555: * @return an iterator for the currently stored entries universe@549: * @see cxMapIteratorKeys() universe@549: * @see cxMapIteratorValues() universe@549: */ universe@549: __attribute__((__nonnull__, __warn_unused_result__)) universe@710: static inline CxIterator cxMapIterator(CxMap const *map) { universe@709: return map->cl->iterator(map, CX_MAP_ITERATOR_PAIRS); universe@549: } universe@549: universe@630: universe@630: /** universe@630: * Creates a mutating iterator over the values of a map. universe@630: * universe@630: * \note An iterator iterates over all elements successively. Therefore the order universe@630: * highly depends on the map implementation and may change arbitrarily when the contents change. universe@630: * universe@630: * @param map the map to create the iterator for universe@630: * @return an iterator for the currently stored values universe@630: */ universe@630: __attribute__((__nonnull__, __warn_unused_result__)) universe@709: CxMutIterator cxMapMutIteratorValues(CxMap *map); universe@630: universe@630: /** universe@630: * Creates a mutating iterator over the keys of a map. universe@630: * universe@630: * The elements of the iterator are keys of type CxHashKey. universe@630: * universe@630: * \note An iterator iterates over all elements successively. Therefore the order universe@630: * highly depends on the map implementation and may change arbitrarily when the contents change. universe@630: * universe@630: * @param map the map to create the iterator for universe@630: * @return an iterator for the currently stored keys universe@630: */ universe@630: __attribute__((__nonnull__, __warn_unused_result__)) universe@709: CxMutIterator cxMapMutIteratorKeys(CxMap *map); universe@630: universe@630: /** universe@630: * Creates a mutating iterator for a map. universe@630: * universe@630: * The elements of the iterator are key/value pairs of type CxMapEntry. universe@630: * universe@630: * \note An iterator iterates over all elements successively. Therefore the order universe@630: * highly depends on the map implementation and may change arbitrarily when the contents change. universe@630: * universe@630: * @param map the map to create the iterator for universe@630: * @return an iterator for the currently stored entries universe@630: * @see cxMapMutIteratorKeys() universe@630: * @see cxMapMutIteratorValues() universe@630: */ universe@630: __attribute__((__nonnull__, __warn_unused_result__)) universe@709: CxMutIterator cxMapMutIterator(CxMap *map); universe@630: universe@691: #ifdef __cplusplus universe@691: } // end the extern "C" block here, because we want to start overloading universe@691: universe@691: /** universe@691: * Puts a key/value-pair into the map. universe@691: * universe@691: * @param map the map universe@691: * @param key the key universe@691: * @param value the value universe@691: * @return 0 on success, non-zero value on failure universe@691: */ universe@691: __attribute__((__nonnull__)) universe@691: static inline int cxMapPut( universe@691: CxMap *map, universe@691: CxHashKey const &key, universe@691: void *value universe@691: ) { universe@691: return map->cl->put(map, key, value); universe@549: } universe@549: universe@691: universe@691: /** universe@691: * Puts a key/value-pair into the map. universe@691: * universe@691: * @param map the map universe@691: * @param key the key universe@691: * @param value the value universe@691: * @return 0 on success, non-zero value on failure universe@691: */ universe@691: __attribute__((__nonnull__)) universe@691: static inline int cxMapPut( universe@691: CxMap *map, universe@691: cxstring const &key, universe@691: void *value universe@691: ) { universe@691: return map->cl->put(map, cx_hash_key_cxstr(key), value); universe@691: } universe@691: universe@691: /** universe@691: * Puts a key/value-pair into the map. universe@691: * universe@691: * @param map the map universe@691: * @param key the key universe@691: * @param value the value universe@691: * @return 0 on success, non-zero value on failure universe@691: */ universe@691: __attribute__((__nonnull__)) universe@691: static inline int cxMapPut( universe@691: CxMap *map, universe@692: cxmutstr const &key, universe@692: void *value universe@692: ) { universe@692: return map->cl->put(map, cx_hash_key_cxstr(key), value); universe@692: } universe@692: universe@692: /** universe@692: * Puts a key/value-pair into the map. universe@692: * universe@692: * @param map the map universe@692: * @param key the key universe@692: * @param value the value universe@692: * @return 0 on success, non-zero value on failure universe@692: */ universe@692: __attribute__((__nonnull__)) universe@692: static inline int cxMapPut( universe@692: CxMap *map, universe@691: char const *key, universe@691: void *value universe@691: ) { universe@691: return map->cl->put(map, cx_hash_key_str(key), value); universe@691: } universe@691: universe@691: /** universe@691: * Retrieves a value by using a key. universe@691: * universe@691: * @param map the map universe@691: * @param key the key universe@691: * @return the value universe@691: */ universe@691: __attribute__((__nonnull__, __warn_unused_result__)) universe@691: static inline void *cxMapGet( universe@691: CxMap const *map, universe@691: CxHashKey const &key universe@691: ) { universe@691: return map->cl->get(map, key); universe@691: } universe@691: universe@691: /** universe@691: * Retrieves a value by using a key. universe@691: * universe@691: * @param map the map universe@691: * @param key the key universe@691: * @return the value universe@691: */ universe@691: __attribute__((__nonnull__, __warn_unused_result__)) universe@691: static inline void *cxMapGet( universe@691: CxMap const *map, universe@691: cxstring const &key universe@691: ) { universe@691: return map->cl->get(map, cx_hash_key_cxstr(key)); universe@691: } universe@691: universe@691: /** universe@691: * Retrieves a value by using a key. universe@691: * universe@691: * @param map the map universe@691: * @param key the key universe@691: * @return the value universe@691: */ universe@691: __attribute__((__nonnull__, __warn_unused_result__)) universe@691: static inline void *cxMapGet( universe@691: CxMap const *map, universe@692: cxmutstr const &key universe@692: ) { universe@692: return map->cl->get(map, cx_hash_key_cxstr(key)); universe@692: } universe@692: universe@692: /** universe@692: * Retrieves a value by using a key. universe@692: * universe@692: * @param map the map universe@692: * @param key the key universe@692: * @return the value universe@692: */ universe@692: __attribute__((__nonnull__, __warn_unused_result__)) universe@692: static inline void *cxMapGet( universe@692: CxMap const *map, universe@691: char const *key universe@691: ) { universe@691: return map->cl->get(map, cx_hash_key_str(key)); universe@691: } universe@691: universe@691: /** universe@691: * Removes a key/value-pair from the map by using the key. universe@691: * universe@691: * Always invokes the destructor function, if any, on the removed element. universe@691: * If this map is storing pointers and you just want to retrieve the pointer universe@691: * without invoking the destructor, use cxMapRemoveAndGet(). universe@691: * If you just want to detach the element from the map without invoking the universe@691: * destructor or returning the element, use cxMapDetach(). universe@691: * universe@691: * @param map the map universe@691: * @param key the key universe@691: * @see cxMapRemoveAndGet() universe@691: * @see cxMapDetach() universe@691: */ universe@691: __attribute__((__nonnull__)) universe@691: static inline void cxMapRemove( universe@691: CxMap *map, universe@691: CxHashKey const &key universe@691: ) { universe@691: (void) map->cl->remove(map, key, true); universe@691: } universe@691: universe@691: /** universe@691: * Removes a key/value-pair from the map by using the key. universe@691: * universe@691: * Always invokes the destructor function, if any, on the removed element. universe@691: * If this map is storing pointers and you just want to retrieve the pointer universe@691: * without invoking the destructor, use cxMapRemoveAndGet(). universe@691: * If you just want to detach the element from the map without invoking the universe@691: * destructor or returning the element, use cxMapDetach(). universe@691: * universe@691: * @param map the map universe@691: * @param key the key universe@691: * @see cxMapRemoveAndGet() universe@691: * @see cxMapDetach() universe@691: */ universe@691: __attribute__((__nonnull__)) universe@691: static inline void cxMapRemove( universe@691: CxMap *map, universe@691: cxstring const &key universe@691: ) { universe@691: (void) map->cl->remove(map, cx_hash_key_cxstr(key), true); universe@691: } universe@691: universe@691: /** universe@691: * Removes a key/value-pair from the map by using the key. universe@691: * universe@691: * Always invokes the destructor function, if any, on the removed element. universe@691: * If this map is storing pointers and you just want to retrieve the pointer universe@691: * without invoking the destructor, use cxMapRemoveAndGet(). universe@691: * If you just want to detach the element from the map without invoking the universe@691: * destructor or returning the element, use cxMapDetach(). universe@691: * universe@691: * @param map the map universe@691: * @param key the key universe@691: * @see cxMapRemoveAndGet() universe@691: * @see cxMapDetach() universe@691: */ universe@691: __attribute__((__nonnull__)) universe@691: static inline void cxMapRemove( universe@691: CxMap *map, universe@692: cxmutstr const &key universe@692: ) { universe@692: (void) map->cl->remove(map, cx_hash_key_cxstr(key), true); universe@692: } universe@692: universe@692: /** universe@692: * Removes a key/value-pair from the map by using the key. universe@692: * universe@692: * Always invokes the destructor function, if any, on the removed element. universe@692: * If this map is storing pointers and you just want to retrieve the pointer universe@692: * without invoking the destructor, use cxMapRemoveAndGet(). universe@692: * If you just want to detach the element from the map without invoking the universe@692: * destructor or returning the element, use cxMapDetach(). universe@692: * universe@692: * @param map the map universe@692: * @param key the key universe@692: * @see cxMapRemoveAndGet() universe@692: * @see cxMapDetach() universe@692: */ universe@692: __attribute__((__nonnull__)) universe@692: static inline void cxMapRemove( universe@692: CxMap *map, universe@691: char const *key universe@691: ) { universe@691: (void) map->cl->remove(map, cx_hash_key_str(key), true); universe@691: } universe@691: universe@691: /** universe@691: * Detaches a key/value-pair from the map by using the key universe@691: * without invoking the destructor. universe@691: * universe@691: * In general, you should only use this function if the map does not own universe@691: * the data and there is a valid reference to the data somewhere else universe@691: * in the program. In all other cases it is preferable to use universe@691: * cxMapRemove() or cxMapRemoveAndGet(). universe@691: * universe@691: * @param map the map universe@691: * @param key the key universe@691: * @see cxMapRemove() universe@691: * @see cxMapRemoveAndGet() universe@691: */ universe@691: __attribute__((__nonnull__)) universe@691: static inline void cxMapDetach( universe@691: CxMap *map, universe@691: CxHashKey const &key universe@691: ) { universe@691: (void) map->cl->remove(map, key, false); universe@691: } universe@691: universe@691: /** universe@691: * Detaches a key/value-pair from the map by using the key universe@691: * without invoking the destructor. universe@691: * universe@691: * In general, you should only use this function if the map does not own universe@691: * the data and there is a valid reference to the data somewhere else universe@691: * in the program. In all other cases it is preferable to use universe@691: * cxMapRemove() or cxMapRemoveAndGet(). universe@691: * universe@691: * @param map the map universe@691: * @param key the key universe@691: * @see cxMapRemove() universe@691: * @see cxMapRemoveAndGet() universe@691: */ universe@691: __attribute__((__nonnull__)) universe@691: static inline void cxMapDetach( universe@691: CxMap *map, universe@691: cxstring const &key universe@691: ) { universe@691: (void) map->cl->remove(map, cx_hash_key_cxstr(key), false); universe@691: } universe@691: universe@691: /** universe@691: * Detaches a key/value-pair from the map by using the key universe@691: * without invoking the destructor. universe@691: * universe@691: * In general, you should only use this function if the map does not own universe@691: * the data and there is a valid reference to the data somewhere else universe@691: * in the program. In all other cases it is preferable to use universe@691: * cxMapRemove() or cxMapRemoveAndGet(). universe@691: * universe@691: * @param map the map universe@691: * @param key the key universe@691: * @see cxMapRemove() universe@691: * @see cxMapRemoveAndGet() universe@691: */ universe@691: __attribute__((__nonnull__)) universe@691: static inline void cxMapDetach( universe@691: CxMap *map, universe@692: cxmutstr const &key universe@692: ) { universe@692: (void) map->cl->remove(map, cx_hash_key_cxstr(key), false); universe@692: } universe@692: universe@692: /** universe@692: * Detaches a key/value-pair from the map by using the key universe@692: * without invoking the destructor. universe@692: * universe@692: * In general, you should only use this function if the map does not own universe@692: * the data and there is a valid reference to the data somewhere else universe@692: * in the program. In all other cases it is preferable to use universe@692: * cxMapRemove() or cxMapRemoveAndGet(). universe@692: * universe@692: * @param map the map universe@692: * @param key the key universe@692: * @see cxMapRemove() universe@692: * @see cxMapRemoveAndGet() universe@692: */ universe@692: __attribute__((__nonnull__)) universe@692: static inline void cxMapDetach( universe@692: CxMap *map, universe@691: char const *key universe@691: ) { universe@691: (void) map->cl->remove(map, cx_hash_key_str(key), false); universe@691: } universe@691: universe@691: /** universe@691: * Removes a key/value-pair from the map by using the key. universe@691: * universe@691: * This function can be used when the map is storing pointers, universe@691: * in order to retrieve the pointer from the map without invoking universe@691: * any destructor function. Sometimes you do not want the pointer universe@691: * to be returned - in that case (instead of suppressing the "unused universe@691: * result" warning) you can use cxMapDetach(). universe@691: * universe@691: * If this map is not storing pointers, this function behaves like universe@691: * cxMapRemove() and returns \c NULL. universe@691: * universe@691: * @param map the map universe@691: * @param key the key universe@691: * @return the stored pointer or \c NULL if either the key is not present universe@691: * in the map or the map is not storing pointers universe@691: * @see cxMapStorePointers() universe@691: * @see cxMapDetach() universe@691: */ universe@691: __attribute__((__nonnull__, __warn_unused_result__)) universe@691: static inline void *cxMapRemoveAndGet( universe@691: CxMap *map, universe@691: CxHashKey key universe@691: ) { universe@691: return map->cl->remove(map, key, !map->store_pointer); universe@691: } universe@691: universe@691: /** universe@691: * Removes a key/value-pair from the map by using the key. universe@691: * universe@691: * This function can be used when the map is storing pointers, universe@691: * in order to retrieve the pointer from the map without invoking universe@691: * any destructor function. Sometimes you do not want the pointer universe@691: * to be returned - in that case (instead of suppressing the "unused universe@691: * result" warning) you can use cxMapDetach(). universe@691: * universe@691: * If this map is not storing pointers, this function behaves like universe@691: * cxMapRemove() and returns \c NULL. universe@691: * universe@691: * @param map the map universe@691: * @param key the key universe@691: * @return the stored pointer or \c NULL if either the key is not present universe@691: * in the map or the map is not storing pointers universe@691: * @see cxMapStorePointers() universe@691: * @see cxMapDetach() universe@691: */ universe@691: __attribute__((__nonnull__, __warn_unused_result__)) universe@691: static inline void *cxMapRemoveAndGet( universe@691: CxMap *map, universe@691: cxstring key universe@691: ) { universe@691: return map->cl->remove(map, cx_hash_key_cxstr(key), !map->store_pointer); universe@691: } universe@691: universe@691: /** universe@691: * Removes a key/value-pair from the map by using the key. universe@691: * universe@691: * This function can be used when the map is storing pointers, universe@691: * in order to retrieve the pointer from the map without invoking universe@691: * any destructor function. Sometimes you do not want the pointer universe@691: * to be returned - in that case (instead of suppressing the "unused universe@691: * result" warning) you can use cxMapDetach(). universe@691: * universe@691: * If this map is not storing pointers, this function behaves like universe@691: * cxMapRemove() and returns \c NULL. universe@691: * universe@691: * @param map the map universe@691: * @param key the key universe@691: * @return the stored pointer or \c NULL if either the key is not present universe@691: * in the map or the map is not storing pointers universe@691: * @see cxMapStorePointers() universe@691: * @see cxMapDetach() universe@691: */ universe@691: __attribute__((__nonnull__, __warn_unused_result__)) universe@691: static inline void *cxMapRemoveAndGet( universe@691: CxMap *map, universe@692: cxmutstr key universe@692: ) { universe@692: return map->cl->remove(map, cx_hash_key_cxstr(key), !map->store_pointer); universe@692: } universe@692: universe@692: /** universe@692: * Removes a key/value-pair from the map by using the key. universe@692: * universe@692: * This function can be used when the map is storing pointers, universe@692: * in order to retrieve the pointer from the map without invoking universe@692: * any destructor function. Sometimes you do not want the pointer universe@692: * to be returned - in that case (instead of suppressing the "unused universe@692: * result" warning) you can use cxMapDetach(). universe@692: * universe@692: * If this map is not storing pointers, this function behaves like universe@692: * cxMapRemove() and returns \c NULL. universe@692: * universe@692: * @param map the map universe@692: * @param key the key universe@692: * @return the stored pointer or \c NULL if either the key is not present universe@692: * in the map or the map is not storing pointers universe@692: * @see cxMapStorePointers() universe@692: * @see cxMapDetach() universe@692: */ universe@692: __attribute__((__nonnull__, __warn_unused_result__)) universe@692: static inline void *cxMapRemoveAndGet( universe@692: CxMap *map, universe@691: char const *key universe@691: ) { universe@691: return map->cl->remove(map, cx_hash_key_str(key), !map->store_pointer); universe@691: } universe@691: universe@691: #else // __cplusplus universe@691: universe@691: /** universe@691: * Puts a key/value-pair into the map. universe@691: * universe@691: * @param map the map universe@691: * @param key the key universe@691: * @param value the value universe@691: * @return 0 on success, non-zero value on failure universe@691: */ universe@691: __attribute__((__nonnull__)) universe@691: static inline int cx_map_put( universe@691: CxMap *map, universe@691: CxHashKey key, universe@691: void *value universe@691: ) { universe@691: return map->cl->put(map, key, value); universe@691: } universe@691: universe@691: /** universe@691: * Puts a key/value-pair into the map. universe@691: * universe@691: * @param map the map universe@691: * @param key the key universe@691: * @param value the value universe@691: * @return 0 on success, non-zero value on failure universe@691: */ universe@691: __attribute__((__nonnull__)) universe@691: static inline int cx_map_put_cxstr( universe@691: CxMap *map, universe@691: cxstring key, universe@691: void *value universe@691: ) { universe@691: return map->cl->put(map, cx_hash_key_cxstr(key), value); universe@691: } universe@691: universe@691: /** universe@691: * Puts a key/value-pair into the map. universe@691: * universe@691: * @param map the map universe@691: * @param key the key universe@691: * @param value the value universe@691: * @return 0 on success, non-zero value on failure universe@691: */ universe@691: __attribute__((__nonnull__)) universe@692: static inline int cx_map_put_mustr( universe@692: CxMap *map, universe@692: cxmutstr key, universe@692: void *value universe@692: ) { universe@692: return map->cl->put(map, cx_hash_key_cxstr(key), value); universe@692: } universe@692: universe@692: /** universe@692: * Puts a key/value-pair into the map. universe@692: * universe@692: * @param map the map universe@692: * @param key the key universe@692: * @param value the value universe@692: * @return 0 on success, non-zero value on failure universe@692: */ universe@692: __attribute__((__nonnull__)) universe@691: static inline int cx_map_put_str( universe@691: CxMap *map, universe@691: char const *key, universe@691: void *value universe@691: ) { universe@691: return map->cl->put(map, cx_hash_key_str(key), value); universe@691: } universe@691: universe@691: /** universe@691: * Puts a key/value-pair into the map. universe@691: * universe@691: * @param map the map universe@691: * @param key the key universe@691: * @param value the value universe@691: * @return 0 on success, non-zero value on failure universe@691: */ universe@691: #define cxMapPut(map, key, value) _Generic((key), \ universe@691: CxHashKey: cx_map_put, \ universe@691: cxstring: cx_map_put_cxstr, \ universe@692: cxmutstr: cx_map_put_mustr, \ universe@694: char*: cx_map_put_str, \ universe@694: char const*: cx_map_put_str) \ universe@691: (map, key, value) universe@691: universe@691: /** universe@691: * Retrieves a value by using a key. universe@691: * universe@691: * @param map the map universe@691: * @param key the key universe@691: * @return the value universe@691: */ universe@691: __attribute__((__nonnull__, __warn_unused_result__)) universe@691: static inline void *cx_map_get( universe@691: CxMap const *map, universe@691: CxHashKey key universe@691: ) { universe@691: return map->cl->get(map, key); universe@691: } universe@691: universe@691: /** universe@691: * Retrieves a value by using a key. universe@691: * universe@691: * @param map the map universe@691: * @param key the key universe@691: * @return the value universe@691: */ universe@691: __attribute__((__nonnull__, __warn_unused_result__)) universe@691: static inline void *cx_map_get_cxstr( universe@691: CxMap const *map, universe@691: cxstring key universe@691: ) { universe@691: return map->cl->get(map, cx_hash_key_cxstr(key)); universe@691: } universe@691: universe@691: /** universe@691: * Retrieves a value by using a key. universe@691: * universe@691: * @param map the map universe@691: * @param key the key universe@691: * @return the value universe@691: */ universe@691: __attribute__((__nonnull__, __warn_unused_result__)) universe@692: static inline void *cx_map_get_mustr( universe@692: CxMap const *map, universe@692: cxmutstr key universe@692: ) { universe@692: return map->cl->get(map, cx_hash_key_cxstr(key)); universe@692: } universe@692: universe@692: /** universe@692: * Retrieves a value by using a key. universe@692: * universe@692: * @param map the map universe@692: * @param key the key universe@692: * @return the value universe@692: */ universe@692: __attribute__((__nonnull__, __warn_unused_result__)) universe@691: static inline void *cx_map_get_str( universe@691: CxMap const *map, universe@691: char const *key universe@691: ) { universe@691: return map->cl->get(map, cx_hash_key_str(key)); universe@691: } universe@691: universe@691: /** universe@691: * Retrieves a value by using a key. universe@691: * universe@691: * @param map the map universe@691: * @param key the key universe@691: * @return the value universe@691: */ universe@691: #define cxMapGet(map, key) _Generic((key), \ universe@691: CxHashKey: cx_map_get, \ universe@691: cxstring: cx_map_get_cxstr, \ universe@692: cxmutstr: cx_map_get_mustr, \ universe@694: char*: cx_map_get_str, \ universe@694: char const*: cx_map_get_str) \ universe@691: (map, key) universe@691: universe@691: /** universe@691: * Removes a key/value-pair from the map by using the key. universe@691: * universe@691: * @param map the map universe@691: * @param key the key universe@691: */ universe@691: __attribute__((__nonnull__)) universe@691: static inline void cx_map_remove( universe@691: CxMap *map, universe@691: CxHashKey key universe@691: ) { universe@691: (void) map->cl->remove(map, key, true); universe@691: } universe@691: universe@691: /** universe@691: * Removes a key/value-pair from the map by using the key. universe@691: * universe@691: * @param map the map universe@691: * @param key the key universe@691: */ universe@691: __attribute__((__nonnull__)) universe@691: static inline void cx_map_remove_cxstr( universe@691: CxMap *map, universe@691: cxstring key universe@691: ) { universe@691: (void) map->cl->remove(map, cx_hash_key_cxstr(key), true); universe@691: } universe@691: universe@691: /** universe@691: * Removes a key/value-pair from the map by using the key. universe@691: * universe@691: * @param map the map universe@691: * @param key the key universe@691: */ universe@691: __attribute__((__nonnull__)) universe@692: static inline void cx_map_remove_mustr( universe@692: CxMap *map, universe@692: cxmutstr key universe@692: ) { universe@692: (void) map->cl->remove(map, cx_hash_key_cxstr(key), true); universe@692: } universe@692: universe@692: /** universe@692: * Removes a key/value-pair from the map by using the key. universe@692: * universe@692: * @param map the map universe@692: * @param key the key universe@692: */ universe@692: __attribute__((__nonnull__)) universe@691: static inline void cx_map_remove_str( universe@691: CxMap *map, universe@691: char const *key universe@691: ) { universe@691: (void) map->cl->remove(map, cx_hash_key_str(key), true); universe@691: } universe@691: universe@691: /** universe@691: * Removes a key/value-pair from the map by using the key. universe@691: * universe@691: * Always invokes the destructor function, if any, on the removed element. universe@691: * If this map is storing pointers and you just want to retrieve the pointer universe@691: * without invoking the destructor, use cxMapRemoveAndGet(). universe@691: * If you just want to detach the element from the map without invoking the universe@691: * destructor or returning the element, use cxMapDetach(). universe@691: * universe@691: * @param map the map universe@691: * @param key the key universe@691: * @see cxMapRemoveAndGet() universe@691: * @see cxMapDetach() universe@691: */ universe@691: #define cxMapRemove(map, key) _Generic((key), \ universe@691: CxHashKey: cx_map_remove, \ universe@691: cxstring: cx_map_remove_cxstr, \ universe@692: cxmutstr: cx_map_remove_mustr, \ universe@694: char*: cx_map_remove_str, \ universe@694: char const*: cx_map_remove_str) \ universe@691: (map, key) universe@691: universe@691: /** universe@691: * Detaches a key/value-pair from the map by using the key universe@691: * without invoking the destructor. universe@691: * universe@691: * @param map the map universe@691: * @param key the key universe@691: */ universe@691: __attribute__((__nonnull__)) universe@691: static inline void cx_map_detach( universe@691: CxMap *map, universe@691: CxHashKey key universe@691: ) { universe@691: (void) map->cl->remove(map, key, false); universe@691: } universe@691: universe@691: /** universe@691: * Detaches a key/value-pair from the map by using the key universe@691: * without invoking the destructor. universe@691: * universe@691: * @param map the map universe@691: * @param key the key universe@691: */ universe@691: __attribute__((__nonnull__)) universe@691: static inline void cx_map_detach_cxstr( universe@691: CxMap *map, universe@691: cxstring key universe@691: ) { universe@691: (void) map->cl->remove(map, cx_hash_key_cxstr(key), false); universe@691: } universe@691: universe@691: /** universe@691: * Detaches a key/value-pair from the map by using the key universe@691: * without invoking the destructor. universe@691: * universe@691: * @param map the map universe@691: * @param key the key universe@691: */ universe@691: __attribute__((__nonnull__)) universe@692: static inline void cx_map_detach_mustr( universe@692: CxMap *map, universe@692: cxmutstr key universe@692: ) { universe@692: (void) map->cl->remove(map, cx_hash_key_cxstr(key), false); universe@692: } universe@692: universe@692: /** universe@692: * Detaches a key/value-pair from the map by using the key universe@692: * without invoking the destructor. universe@692: * universe@692: * @param map the map universe@692: * @param key the key universe@692: */ universe@692: __attribute__((__nonnull__)) universe@691: static inline void cx_map_detach_str( universe@691: CxMap *map, universe@691: char const *key universe@691: ) { universe@691: (void) map->cl->remove(map, cx_hash_key_str(key), false); universe@691: } universe@691: universe@691: /** universe@691: * Detaches a key/value-pair from the map by using the key universe@691: * without invoking the destructor. universe@691: * universe@691: * In general, you should only use this function if the map does not own universe@691: * the data and there is a valid reference to the data somewhere else universe@691: * in the program. In all other cases it is preferable to use universe@691: * cxMapRemove() or cxMapRemoveAndGet(). universe@691: * universe@691: * @param map the map universe@691: * @param key the key universe@691: * @see cxMapRemove() universe@691: * @see cxMapRemoveAndGet() universe@691: */ universe@691: #define cxMapDetach(map, key) _Generic((key), \ universe@691: CxHashKey: cx_map_detach, \ universe@691: cxstring: cx_map_detach_cxstr, \ universe@692: cxmutstr: cx_map_detach_mustr, \ universe@694: char*: cx_map_detach_str, \ universe@694: char const*: cx_map_detach_str) \ universe@691: (map, key) universe@691: universe@691: /** universe@691: * Removes a key/value-pair from the map by using the key. universe@691: * universe@691: * @param map the map universe@691: * @param key the key universe@691: * @return the stored pointer or \c NULL if either the key is not present universe@691: * in the map or the map is not storing pointers universe@691: */ universe@691: __attribute__((__nonnull__, __warn_unused_result__)) universe@691: static inline void *cx_map_remove_and_get( universe@691: CxMap *map, universe@691: CxHashKey key universe@691: ) { universe@691: return map->cl->remove(map, key, !map->store_pointer); universe@691: } universe@691: universe@691: /** universe@691: * Removes a key/value-pair from the map by using the key. universe@691: * universe@691: * @param map the map universe@691: * @param key the key universe@691: * @return the stored pointer or \c NULL if either the key is not present universe@691: * in the map or the map is not storing pointers universe@691: */ universe@691: __attribute__((__nonnull__, __warn_unused_result__)) universe@691: static inline void *cx_map_remove_and_get_cxstr( universe@691: CxMap *map, universe@691: cxstring key universe@691: ) { universe@691: return map->cl->remove(map, cx_hash_key_cxstr(key), !map->store_pointer); universe@691: } universe@691: universe@691: /** universe@691: * Removes a key/value-pair from the map by using the key. universe@691: * universe@691: * @param map the map universe@691: * @param key the key universe@691: * @return the stored pointer or \c NULL if either the key is not present universe@691: * in the map or the map is not storing pointers universe@691: */ universe@691: __attribute__((__nonnull__, __warn_unused_result__)) universe@692: static inline void *cx_map_remove_and_get_mustr( universe@692: CxMap *map, universe@692: cxmutstr key universe@692: ) { universe@692: return map->cl->remove(map, cx_hash_key_cxstr(key), !map->store_pointer); universe@692: } universe@692: universe@692: /** universe@692: * Removes a key/value-pair from the map by using the key. universe@692: * universe@692: * @param map the map universe@692: * @param key the key universe@692: * @return the stored pointer or \c NULL if either the key is not present universe@692: * in the map or the map is not storing pointers universe@692: */ universe@692: __attribute__((__nonnull__, __warn_unused_result__)) universe@691: static inline void *cx_map_remove_and_get_str( universe@691: CxMap *map, universe@691: char const *key universe@691: ) { universe@691: return map->cl->remove(map, cx_hash_key_str(key), !map->store_pointer); universe@691: } universe@691: universe@691: /** universe@691: * Removes a key/value-pair from the map by using the key. universe@691: * universe@691: * This function can be used when the map is storing pointers, universe@691: * in order to retrieve the pointer from the map without invoking universe@691: * any destructor function. Sometimes you do not want the pointer universe@691: * to be returned - in that case (instead of suppressing the "unused universe@691: * result" warning) you can use cxMapDetach(). universe@691: * universe@691: * If this map is not storing pointers, this function behaves like universe@691: * cxMapRemove() and returns \c NULL. universe@691: * universe@691: * @param map the map universe@691: * @param key the key universe@691: * @return the stored pointer or \c NULL if either the key is not present universe@691: * in the map or the map is not storing pointers universe@691: * @see cxMapStorePointers() universe@691: * @see cxMapDetach() universe@691: */ universe@691: #define cxMapRemoveAndGet(map, key) _Generic((key), \ universe@691: CxHashKey: cx_map_remove_and_get, \ universe@691: cxstring: cx_map_remove_and_get_cxstr, \ universe@692: cxmutstr: cx_map_remove_and_get_mustr, \ universe@694: char*: cx_map_remove_and_get_str, \ universe@694: char const*: cx_map_remove_and_get_str) \ universe@691: (map, key) universe@691: universe@691: #endif // __cplusplus universe@691: universe@691: #endif // UCX_MAP_H