#define UCX_MAP_H
#include "common.h"
-#include "allocator.h"
-#include "iterator.h"
+#include "collection.h"
+#include "string.h"
#include "hash_key.h"
#ifdef __cplusplus
extern "C" {
#endif
-#ifndef CX_STORE_POINTERS
-/**
- * Special constant used for creating collections that are storing pointers.
- */
-#define CX_STORE_POINTERS 0
-#endif
-
/** Type for the UCX map. */
typedef struct cx_map_s CxMap;
/** Structure for the UCX map. */
struct cx_map_s {
+ CX_COLLECTION_MEMBERS
/** The map class definition. */
cx_map_class *cl;
- /** An allocator that is used for the map elements. */
- CxAllocator *allocator;
- /** The number of elements currently stored. */
- size_t size;
+};
+
+/**
+ * The type of iterator for a map.
+ */
+enum cx_map_iterator_type {
/**
- * The size of an element.
+ * Iterates over key/value pairs.
*/
- size_t itemsize;
+ CX_MAP_ITERATOR_PAIRS,
/**
- * True, if this map shall store pointers instead
- * of copies of objects.
+ * Iterates over keys only.
*/
- bool store_pointers;
+ CX_MAP_ITERATOR_KEYS,
+ /**
+ * Iterates over values only.
+ */
+ CX_MAP_ITERATOR_VALUES
};
/**
__attribute__((__nonnull__))
void *(*remove)(
CxMap *map,
- CxHashKey key
+ CxHashKey key,
+ bool destroy
);
/**
- * Iterator over the key/value pairs.
- */
- __attribute__((__nonnull__, __warn_unused_result__))
- CxIterator (*iterator)(CxMap const *map);
-
- /**
- * Iterator over the keys.
- */
- __attribute__((__nonnull__, __warn_unused_result__))
- CxIterator (*iterator_keys)(CxMap const *map);
-
- /**
- * Iterator over the values.
- */
- __attribute__((__nonnull__, __warn_unused_result__))
- CxIterator (*iterator_values)(CxMap const *map);
-
- /**
- * Mutating iterator over the key/value pairs.
- */
- __attribute__((__nonnull__, __warn_unused_result__))
- CxMutIterator (*mut_iterator)(CxMap *map);
-
- /**
- * Mutating iterator over the keys.
- */
- __attribute__((__nonnull__, __warn_unused_result__))
- CxMutIterator (*mut_iterator_keys)(CxMap *map);
-
- /**
- * Mutating iterator over the values.
+ * Creates an iterator for this map.
*/
__attribute__((__nonnull__, __warn_unused_result__))
- CxMutIterator (*mut_iterator_values)(CxMap *map);
+ CxIterator (*iterator)(CxMap const *map, enum cx_map_iterator_type type);
};
/**
};
/**
+ * A shared instance of an empty map.
+ *
+ * Writing to that map is undefined.
+ */
+extern CxMap *const cxEmptyMap;
+
+/**
* Advises the map to store copies of the objects (default mode of operation).
*
* Retrieving objects from this map will yield pointers to the copies stored
*/
__attribute__((__nonnull__))
static inline void cxMapStoreObjects(CxMap *map) {
- map->store_pointers = false;
+ map->store_pointer = false;
}
/**
*/
__attribute__((__nonnull__))
static inline void cxMapStorePointers(CxMap *map) {
- map->store_pointers = true;
- map->itemsize = sizeof(void *);
+ map->store_pointer = true;
+ map->item_size = sizeof(void *);
}
*/
__attribute__((__nonnull__))
static inline void cxMapDestroy(CxMap *map) {
- // TODO: likely to add auto-free feature for contents in the future
map->cl->destructor(map);
}
map->cl->clear(map);
}
-/**
- * Puts a key/value-pair into the map.
- *
- * @param map the map
- * @param key the key
- * @param value the value
- * @return 0 on success, non-zero value on failure
- */
-__attribute__((__nonnull__))
-static inline int cxMapPut(
- CxMap *map,
- CxHashKey key,
- void *value
-) {
- return map->cl->put(map, key, value);
-}
-
-/**
- * Retrieves a value by using a key.
- *
- * @param map the map
- * @param key the key
- * @return the value
- */
-__attribute__((__nonnull__, __warn_unused_result__))
-static inline void *cxMapGet(
- CxMap const *map,
- CxHashKey key
-) {
- return map->cl->get(map, key);
-}
-
-/**
- * Removes a key/value-pair from the map by using the key.
- *
- * If this map is storing pointers, you should make sure that the map
- * is not the last location where this pointer is stored.
- * Otherwise, use cxMapRemoveAndGet() to retrieve the pointer while
- * removing it from the map.
- *
- * @param map the map
- * @param key the key
- * @see cxMapRemoveAndGet()
- */
-__attribute__((__nonnull__))
-static inline void cxMapRemove(
- CxMap *map,
- CxHashKey key
-) {
- (void) map->cl->remove(map, key);
-}
-
-/**
- * Removes a key/value-pair from the map by using the key.
- *
- * This function should only be used when the map is storing pointers,
- * in order to retrieve the pointer you are about to remove.
- * In any other case, cxMapRemove() is sufficient.
- *
- * @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()
- */
-__attribute__((__nonnull__, __warn_unused_result__))
-static inline void *cxMapRemoveAndGet(
- CxMap *map,
- CxHashKey key
-) {
- return map->cl->remove(map, key);
-}
// TODO: set-like map operations (union, intersect, difference)
* @return an iterator for the currently stored values
*/
__attribute__((__nonnull__, __warn_unused_result__))
-static inline CxIterator cxMapIteratorValues(CxMap *map) {
- return map->cl->iterator_values(map);
+static inline CxIterator cxMapIteratorValues(CxMap const *map) {
+ return map->cl->iterator(map, CX_MAP_ITERATOR_VALUES);
}
/**
* @return an iterator for the currently stored keys
*/
__attribute__((__nonnull__, __warn_unused_result__))
-static inline CxIterator cxMapIteratorKeys(CxMap *map) {
- return map->cl->iterator_keys(map);
+static inline CxIterator cxMapIteratorKeys(CxMap const *map) {
+ return map->cl->iterator(map, CX_MAP_ITERATOR_KEYS);
}
/**
* @see cxMapIteratorValues()
*/
__attribute__((__nonnull__, __warn_unused_result__))
-static inline CxIterator cxMapIterator(CxMap *map) {
- return map->cl->iterator(map);
+static inline CxIterator cxMapIterator(CxMap const *map) {
+ return map->cl->iterator(map, CX_MAP_ITERATOR_PAIRS);
}
* @return an iterator for the currently stored values
*/
__attribute__((__nonnull__, __warn_unused_result__))
-static inline CxMutIterator cxMapMutIteratorValues(CxMap *map) {
- return map->cl->mut_iterator_values(map);
-}
+CxMutIterator cxMapMutIteratorValues(CxMap *map);
/**
* Creates a mutating iterator over the keys of a map.
* @return an iterator for the currently stored keys
*/
__attribute__((__nonnull__, __warn_unused_result__))
-static inline CxMutIterator cxMapMutIteratorKeys(CxMap *map) {
- return map->cl->mut_iterator_keys(map);
-}
+CxMutIterator cxMapMutIteratorKeys(CxMap *map);
/**
* Creates a mutating iterator for a map.
* @see cxMapMutIteratorValues()
*/
__attribute__((__nonnull__, __warn_unused_result__))
-static inline CxMutIterator cxMapMutIterator(CxMap *map) {
- return map->cl->mut_iterator(map);
+CxMutIterator cxMapMutIterator(CxMap *map);
+
+#ifdef __cplusplus
+} // end the extern "C" block here, because we want to start overloading
+
+/**
+ * Puts a key/value-pair into the map.
+ *
+ * @param map the map
+ * @param key the key
+ * @param value the value
+ * @return 0 on success, non-zero value on failure
+ */
+__attribute__((__nonnull__))
+static inline int cxMapPut(
+ CxMap *map,
+ CxHashKey const &key,
+ void *value
+) {
+ return map->cl->put(map, key, value);
}
-#ifdef __cplusplus
+
+/**
+ * Puts a key/value-pair into the map.
+ *
+ * @param map the map
+ * @param key the key
+ * @param value the value
+ * @return 0 on success, non-zero value on failure
+ */
+__attribute__((__nonnull__))
+static inline int cxMapPut(
+ CxMap *map,
+ cxstring const &key,
+ void *value
+) {
+ return map->cl->put(map, cx_hash_key_cxstr(key), value);
}
-#endif
-#endif // UCX_MAP_H
\ No newline at end of file
+/**
+ * Puts a key/value-pair into the map.
+ *
+ * @param map the map
+ * @param key the key
+ * @param value the value
+ * @return 0 on success, non-zero value on failure
+ */
+__attribute__((__nonnull__))
+static inline int cxMapPut(
+ CxMap *map,
+ cxmutstr const &key,
+ void *value
+) {
+ return map->cl->put(map, cx_hash_key_cxstr(key), value);
+}
+
+/**
+ * Puts a key/value-pair into the map.
+ *
+ * @param map the map
+ * @param key the key
+ * @param value the value
+ * @return 0 on success, non-zero value on failure
+ */
+__attribute__((__nonnull__))
+static inline int cxMapPut(
+ CxMap *map,
+ char const *key,
+ void *value
+) {
+ return map->cl->put(map, cx_hash_key_str(key), value);
+}
+
+/**
+ * Retrieves a value by using a key.
+ *
+ * @param map the map
+ * @param key the key
+ * @return the value
+ */
+__attribute__((__nonnull__, __warn_unused_result__))
+static inline void *cxMapGet(
+ CxMap const *map,
+ CxHashKey const &key
+) {
+ return map->cl->get(map, key);
+}
+
+/**
+ * Retrieves a value by using a key.
+ *
+ * @param map the map
+ * @param key the key
+ * @return the value
+ */
+__attribute__((__nonnull__, __warn_unused_result__))
+static inline void *cxMapGet(
+ CxMap const *map,
+ cxstring const &key
+) {
+ return map->cl->get(map, cx_hash_key_cxstr(key));
+}
+
+/**
+ * Retrieves a value by using a key.
+ *
+ * @param map the map
+ * @param key the key
+ * @return the value
+ */
+__attribute__((__nonnull__, __warn_unused_result__))
+static inline void *cxMapGet(
+ CxMap const *map,
+ cxmutstr const &key
+) {
+ return map->cl->get(map, cx_hash_key_cxstr(key));
+}
+
+/**
+ * Retrieves a value by using a key.
+ *
+ * @param map the map
+ * @param key the key
+ * @return the value
+ */
+__attribute__((__nonnull__, __warn_unused_result__))
+static inline void *cxMapGet(
+ CxMap const *map,
+ char const *key
+) {
+ return map->cl->get(map, cx_hash_key_str(key));
+}
+
+/**
+ * Removes a key/value-pair from the map by using the key.
+ *
+ * Always invokes the 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,
+ CxHashKey const &key
+) {
+ (void) map->cl->remove(map, key, true);
+}
+
+/**
+ * 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,
+ cxstring const &key
+) {
+ (void) map->cl->remove(map, cx_hash_key_cxstr(key), true);
+}
+
+/**
+ * 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,
+ cxmutstr const &key
+) {
+ (void) map->cl->remove(map, cx_hash_key_cxstr(key), true);
+}
+
+/**
+ * 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.
+ *
+ * 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().
+ *
+ * @param map the map
+ * @param key the key
+ * @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(
+ CxMap *map,
+ cxmutstr 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(
+ CxMap *map,
+ char const *key
+) {
+ (void) map->cl->remove(map, cx_hash_key_str(key), false);
+}
+
+/**
+ * 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,
+ CxHashKey key
+) {
+ return map->cl->remove(map, 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,
+ cxstring key
+) {
+ 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,
+ cxmutstr key
+) {
+ 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);
+}
+
+#else // __cplusplus
+
+/**
+ * Puts a key/value-pair into the map.
+ *
+ * @param map the map
+ * @param key the key
+ * @param value the value
+ * @return 0 on success, non-zero value on failure
+ */
+__attribute__((__nonnull__))
+static inline int cx_map_put(
+ CxMap *map,
+ CxHashKey key,
+ void *value
+) {
+ return map->cl->put(map, key, value);
+}
+
+/**
+ * Puts a key/value-pair into the map.
+ *
+ * @param map the map
+ * @param key the key
+ * @param value the value
+ * @return 0 on success, non-zero value on failure
+ */
+__attribute__((__nonnull__))
+static inline int cx_map_put_cxstr(
+ CxMap *map,
+ cxstring key,
+ void *value
+) {
+ return map->cl->put(map, cx_hash_key_cxstr(key), value);
+}
+
+/**
+ * Puts a key/value-pair into the map.
+ *
+ * @param map the map
+ * @param key the key
+ * @param value the value
+ * @return 0 on success, non-zero value on failure
+ */
+__attribute__((__nonnull__))
+static inline int cx_map_put_mustr(
+ CxMap *map,
+ cxmutstr key,
+ void *value
+) {
+ return map->cl->put(map, cx_hash_key_cxstr(key), value);
+}
+
+/**
+ * Puts a key/value-pair into the map.
+ *
+ * @param map the map
+ * @param key the key
+ * @param value the value
+ * @return 0 on success, non-zero value on failure
+ */
+__attribute__((__nonnull__))
+static inline int cx_map_put_str(
+ CxMap *map,
+ char const *key,
+ void *value
+) {
+ return map->cl->put(map, cx_hash_key_str(key), value);
+}
+
+/**
+ * Puts a key/value-pair into the map.
+ *
+ * @param map the map
+ * @param key the key
+ * @param value the value
+ * @return 0 on success, non-zero value on failure
+ */
+#define cxMapPut(map, key, value) _Generic((key), \
+ CxHashKey: cx_map_put, \
+ cxstring: cx_map_put_cxstr, \
+ cxmutstr: cx_map_put_mustr, \
+ char*: cx_map_put_str, \
+ char const*: cx_map_put_str) \
+ (map, key, value)
+
+/**
+ * Retrieves a value by using a key.
+ *
+ * @param map the map
+ * @param key the key
+ * @return the value
+ */
+__attribute__((__nonnull__, __warn_unused_result__))
+static inline void *cx_map_get(
+ CxMap const *map,
+ CxHashKey key
+) {
+ return map->cl->get(map, key);
+}
+
+/**
+ * Retrieves a value by using a key.
+ *
+ * @param map the map
+ * @param key the key
+ * @return the value
+ */
+__attribute__((__nonnull__, __warn_unused_result__))
+static inline void *cx_map_get_cxstr(
+ CxMap const *map,
+ cxstring key
+) {
+ return map->cl->get(map, cx_hash_key_cxstr(key));
+}
+
+/**
+ * Retrieves a value by using a key.
+ *
+ * @param map the map
+ * @param key the key
+ * @return the value
+ */
+__attribute__((__nonnull__, __warn_unused_result__))
+static inline void *cx_map_get_mustr(
+ CxMap const *map,
+ cxmutstr key
+) {
+ return map->cl->get(map, cx_hash_key_cxstr(key));
+}
+
+/**
+ * Retrieves a value by using a key.
+ *
+ * @param map the map
+ * @param key the key
+ * @return the value
+ */
+__attribute__((__nonnull__, __warn_unused_result__))
+static inline void *cx_map_get_str(
+ CxMap const *map,
+ char const *key
+) {
+ return map->cl->get(map, cx_hash_key_str(key));
+}
+
+/**
+ * Retrieves a value by using a key.
+ *
+ * @param map the map
+ * @param key the key
+ * @return the value
+ */
+#define cxMapGet(map, key) _Generic((key), \
+ CxHashKey: cx_map_get, \
+ cxstring: cx_map_get_cxstr, \
+ cxmutstr: cx_map_get_mustr, \
+ char*: cx_map_get_str, \
+ char const*: cx_map_get_str) \
+ (map, key)
+
+/**
+ * Removes a key/value-pair from the map by using the key.
+ *
+ * @param map the map
+ * @param key the key
+ */
+__attribute__((__nonnull__))
+static inline void cx_map_remove(
+ CxMap *map,
+ CxHashKey key
+) {
+ (void) map->cl->remove(map, key, true);
+}
+
+/**
+ * Removes a key/value-pair from the map by using the key.
+ *
+ * @param map the map
+ * @param key the key
+ */
+__attribute__((__nonnull__))
+static inline void cx_map_remove_cxstr(
+ CxMap *map,
+ cxstring key
+) {
+ (void) map->cl->remove(map, cx_hash_key_cxstr(key), true);
+}
+
+/**
+ * Removes a key/value-pair from the map by using the key.
+ *
+ * @param map the map
+ * @param key the key
+ */
+__attribute__((__nonnull__))
+static inline void cx_map_remove_mustr(
+ CxMap *map,
+ cxmutstr key
+) {
+ (void) map->cl->remove(map, cx_hash_key_cxstr(key), true);
+}
+
+/**
+ * Removes a key/value-pair from the map by using the key.
+ *
+ * @param map the map
+ * @param key the key
+ */
+__attribute__((__nonnull__))
+static inline void cx_map_remove_str(
+ CxMap *map,
+ char const *key
+) {
+ (void) map->cl->remove(map, cx_hash_key_str(key), true);
+}
+
+/**
+ * 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()
+ */
+#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) \
+ (map, key)
+
+/**
+ * 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
+ */
+__attribute__((__nonnull__, __warn_unused_result__))
+static inline void *cx_map_remove_and_get(
+ CxMap *map,
+ CxHashKey key
+) {
+ return map->cl->remove(map, key, !map->store_pointer);
+}
+
+/**
+ * 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
+ */
+__attribute__((__nonnull__, __warn_unused_result__))
+static inline void *cx_map_remove_and_get_cxstr(
+ CxMap *map,
+ cxstring key
+) {
+ 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.
+ *
+ * @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
+ */
+__attribute__((__nonnull__, __warn_unused_result__))
+static inline void *cx_map_remove_and_get_mustr(
+ CxMap *map,
+ cxmutstr key
+) {
+ 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.
+ *
+ * @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
+ */
+__attribute__((__nonnull__, __warn_unused_result__))
+static inline void *cx_map_remove_and_get_str(
+ CxMap *map,
+ char const *key
+) {
+ return map->cl->remove(map, cx_hash_key_str(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()
+ */
+#define cxMapRemoveAndGet(map, key) _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)
+
+#endif // __cplusplus
+
+#endif // UCX_MAP_H