2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
4 * Copyright 2021 Mike Becker, Olaf Wintermann All rights reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
30 * \brief Interface for map implementations.
32 * \author Olaf Wintermann
34 * \copyright 2-Clause BSD License
41 #include "collection.h"
49 /** Type for the UCX map. */
50 typedef struct cx_map_s CxMap;
52 /** Type for a map entry. */
53 typedef struct cx_map_entry_s CxMapEntry;
55 /** Type for map class definitions. */
56 typedef struct cx_map_class_s cx_map_class;
58 /** Structure for the UCX map. */
61 /** The map class definition. */
66 * The type of iterator for a map.
68 enum cx_map_iterator_type {
70 * Iterates over key/value pairs.
72 CX_MAP_ITERATOR_PAIRS,
74 * Iterates over keys only.
78 * Iterates over values only.
80 CX_MAP_ITERATOR_VALUES
84 * The class definition for arbitrary maps.
86 struct cx_map_class_s {
88 * Deallocates the entire memory.
90 __attribute__((__nonnull__))
91 void (*destructor)(struct cx_map_s *map);
94 * Removes all elements.
96 __attribute__((__nonnull__))
97 void (*clear)(struct cx_map_s *map);
100 * Add or overwrite an element.
102 __attribute__((__nonnull__))
110 * Returns an element.
112 __attribute__((__nonnull__, __warn_unused_result__))
119 * Removes an element.
121 __attribute__((__nonnull__))
129 * Creates an iterator for this map.
131 __attribute__((__nonnull__, __warn_unused_result__))
132 CxIterator (*iterator)(CxMap const *map, enum cx_map_iterator_type type);
138 struct cx_map_entry_s {
140 * A pointer to the key.
142 CxHashKey const *key;
144 * A pointer to the value.
150 * A shared instance of an empty map.
152 * Writing to that map is undefined.
154 extern CxMap *const cxEmptyMap;
157 * Advises the map to store copies of the objects (default mode of operation).
159 * Retrieving objects from this map will yield pointers to the copies stored
163 * @see cxMapStorePointers()
165 __attribute__((__nonnull__))
166 static inline void cxMapStoreObjects(CxMap *map) {
167 map->store_pointer = false;
171 * Advises the map to only store pointers to the objects.
173 * Retrieving objects from this list will yield the original pointers stored.
175 * @note This function forcibly sets the element size to the size of a pointer.
176 * Invoking this function on a non-empty map that already stores copies of
177 * objects is undefined.
180 * @see cxMapStoreObjects()
182 __attribute__((__nonnull__))
183 static inline void cxMapStorePointers(CxMap *map) {
184 map->store_pointer = true;
185 map->item_size = sizeof(void *);
190 * Deallocates the memory of the specified map.
192 * @param map the map to be destroyed
194 __attribute__((__nonnull__))
195 static inline void cxMapDestroy(CxMap *map) {
196 map->cl->destructor(map);
201 * Clears a map by removing all elements.
203 * @param map the map to be cleared
205 __attribute__((__nonnull__))
206 static inline void cxMapClear(CxMap *map) {
211 // TODO: set-like map operations (union, intersect, difference)
214 * Creates a value iterator for a map.
216 * \note An iterator iterates over all elements successively. Therefore the order
217 * highly depends on the map implementation and may change arbitrarily when the contents change.
219 * @param map the map to create the iterator for
220 * @return an iterator for the currently stored values
222 __attribute__((__nonnull__, __warn_unused_result__))
223 static inline CxIterator cxMapIteratorValues(CxMap const *map) {
224 return map->cl->iterator(map, CX_MAP_ITERATOR_VALUES);
228 * Creates a key iterator for a map.
230 * The elements of the iterator are keys of type CxHashKey.
232 * \note An iterator iterates over all elements successively. Therefore the order
233 * highly depends on the map implementation and may change arbitrarily when the contents change.
235 * @param map the map to create the iterator for
236 * @return an iterator for the currently stored keys
238 __attribute__((__nonnull__, __warn_unused_result__))
239 static inline CxIterator cxMapIteratorKeys(CxMap const *map) {
240 return map->cl->iterator(map, CX_MAP_ITERATOR_KEYS);
244 * Creates an iterator for a map.
246 * The elements of the iterator are key/value pairs of type CxMapEntry.
248 * \note An iterator iterates over all elements successively. Therefore the order
249 * highly depends on the map implementation and may change arbitrarily when the contents change.
251 * @param map the map to create the iterator for
252 * @return an iterator for the currently stored entries
253 * @see cxMapIteratorKeys()
254 * @see cxMapIteratorValues()
256 __attribute__((__nonnull__, __warn_unused_result__))
257 static inline CxIterator cxMapIterator(CxMap const *map) {
258 return map->cl->iterator(map, CX_MAP_ITERATOR_PAIRS);
263 * Creates a mutating iterator over the values of a map.
265 * \note An iterator iterates over all elements successively. Therefore the order
266 * highly depends on the map implementation and may change arbitrarily when the contents change.
268 * @param map the map to create the iterator for
269 * @return an iterator for the currently stored values
271 __attribute__((__nonnull__, __warn_unused_result__))
272 CxMutIterator cxMapMutIteratorValues(CxMap *map);
275 * Creates a mutating iterator over the keys of a map.
277 * The elements of the iterator are keys of type CxHashKey.
279 * \note An iterator iterates over all elements successively. Therefore the order
280 * highly depends on the map implementation and may change arbitrarily when the contents change.
282 * @param map the map to create the iterator for
283 * @return an iterator for the currently stored keys
285 __attribute__((__nonnull__, __warn_unused_result__))
286 CxMutIterator cxMapMutIteratorKeys(CxMap *map);
289 * Creates a mutating iterator for a map.
291 * The elements of the iterator are key/value pairs of type CxMapEntry.
293 * \note An iterator iterates over all elements successively. Therefore the order
294 * highly depends on the map implementation and may change arbitrarily when the contents change.
296 * @param map the map to create the iterator for
297 * @return an iterator for the currently stored entries
298 * @see cxMapMutIteratorKeys()
299 * @see cxMapMutIteratorValues()
301 __attribute__((__nonnull__, __warn_unused_result__))
302 CxMutIterator cxMapMutIterator(CxMap *map);
305 } // end the extern "C" block here, because we want to start overloading
308 * Puts a key/value-pair into the map.
312 * @param value the value
313 * @return 0 on success, non-zero value on failure
315 __attribute__((__nonnull__))
316 static inline int cxMapPut(
318 CxHashKey const &key,
321 return map->cl->put(map, key, value);
326 * Puts a key/value-pair into the map.
330 * @param value the value
331 * @return 0 on success, non-zero value on failure
333 __attribute__((__nonnull__))
334 static inline int cxMapPut(
339 return map->cl->put(map, cx_hash_key_cxstr(key), value);
343 * Puts a key/value-pair into the map.
347 * @param value the value
348 * @return 0 on success, non-zero value on failure
350 __attribute__((__nonnull__))
351 static inline int cxMapPut(
356 return map->cl->put(map, cx_hash_key_cxstr(key), value);
360 * Puts a key/value-pair into the map.
364 * @param value the value
365 * @return 0 on success, non-zero value on failure
367 __attribute__((__nonnull__))
368 static inline int cxMapPut(
373 return map->cl->put(map, cx_hash_key_str(key), value);
377 * Retrieves a value by using a key.
383 __attribute__((__nonnull__, __warn_unused_result__))
384 static inline void *cxMapGet(
388 return map->cl->get(map, key);
392 * Retrieves a value by using a key.
398 __attribute__((__nonnull__, __warn_unused_result__))
399 static inline void *cxMapGet(
403 return map->cl->get(map, cx_hash_key_cxstr(key));
407 * Retrieves a value by using a key.
413 __attribute__((__nonnull__, __warn_unused_result__))
414 static inline void *cxMapGet(
418 return map->cl->get(map, cx_hash_key_cxstr(key));
422 * Retrieves a value by using a key.
428 __attribute__((__nonnull__, __warn_unused_result__))
429 static inline void *cxMapGet(
433 return map->cl->get(map, cx_hash_key_str(key));
437 * Removes a key/value-pair from the map by using the key.
439 * Always invokes the destructor function, if any, on the removed element.
440 * If this map is storing pointers and you just want to retrieve the pointer
441 * without invoking the destructor, use cxMapRemoveAndGet().
442 * If you just want to detach the element from the map without invoking the
443 * destructor or returning the element, use cxMapDetach().
447 * @see cxMapRemoveAndGet()
450 __attribute__((__nonnull__))
451 static inline void cxMapRemove(
455 (void) map->cl->remove(map, key, true);
459 * Removes a key/value-pair from the map by using the key.
461 * Always invokes the destructor function, if any, on the removed element.
462 * If this map is storing pointers and you just want to retrieve the pointer
463 * without invoking the destructor, use cxMapRemoveAndGet().
464 * If you just want to detach the element from the map without invoking the
465 * destructor or returning the element, use cxMapDetach().
469 * @see cxMapRemoveAndGet()
472 __attribute__((__nonnull__))
473 static inline void cxMapRemove(
477 (void) map->cl->remove(map, cx_hash_key_cxstr(key), true);
481 * Removes a key/value-pair from the map by using the key.
483 * Always invokes the destructor function, if any, on the removed element.
484 * If this map is storing pointers and you just want to retrieve the pointer
485 * without invoking the destructor, use cxMapRemoveAndGet().
486 * If you just want to detach the element from the map without invoking the
487 * destructor or returning the element, use cxMapDetach().
491 * @see cxMapRemoveAndGet()
494 __attribute__((__nonnull__))
495 static inline void cxMapRemove(
499 (void) map->cl->remove(map, cx_hash_key_cxstr(key), true);
503 * Removes a key/value-pair from the map by using the key.
505 * Always invokes the destructor function, if any, on the removed element.
506 * If this map is storing pointers and you just want to retrieve the pointer
507 * without invoking the destructor, use cxMapRemoveAndGet().
508 * If you just want to detach the element from the map without invoking the
509 * destructor or returning the element, use cxMapDetach().
513 * @see cxMapRemoveAndGet()
516 __attribute__((__nonnull__))
517 static inline void cxMapRemove(
521 (void) map->cl->remove(map, cx_hash_key_str(key), true);
525 * Detaches a key/value-pair from the map by using the key
526 * without invoking the destructor.
528 * In general, you should only use this function if the map does not own
529 * the data and there is a valid reference to the data somewhere else
530 * in the program. In all other cases it is preferable to use
531 * cxMapRemove() or cxMapRemoveAndGet().
536 * @see cxMapRemoveAndGet()
538 __attribute__((__nonnull__))
539 static inline void cxMapDetach(
543 (void) map->cl->remove(map, key, false);
547 * Detaches a key/value-pair from the map by using the key
548 * without invoking the destructor.
550 * In general, you should only use this function if the map does not own
551 * the data and there is a valid reference to the data somewhere else
552 * in the program. In all other cases it is preferable to use
553 * cxMapRemove() or cxMapRemoveAndGet().
558 * @see cxMapRemoveAndGet()
560 __attribute__((__nonnull__))
561 static inline void cxMapDetach(
565 (void) map->cl->remove(map, cx_hash_key_cxstr(key), false);
569 * Detaches a key/value-pair from the map by using the key
570 * without invoking the destructor.
572 * In general, you should only use this function if the map does not own
573 * the data and there is a valid reference to the data somewhere else
574 * in the program. In all other cases it is preferable to use
575 * cxMapRemove() or cxMapRemoveAndGet().
580 * @see cxMapRemoveAndGet()
582 __attribute__((__nonnull__))
583 static inline void cxMapDetach(
587 (void) map->cl->remove(map, cx_hash_key_cxstr(key), false);
591 * Detaches a key/value-pair from the map by using the key
592 * without invoking the destructor.
594 * In general, you should only use this function if the map does not own
595 * the data and there is a valid reference to the data somewhere else
596 * in the program. In all other cases it is preferable to use
597 * cxMapRemove() or cxMapRemoveAndGet().
602 * @see cxMapRemoveAndGet()
604 __attribute__((__nonnull__))
605 static inline void cxMapDetach(
609 (void) map->cl->remove(map, cx_hash_key_str(key), false);
613 * Removes a key/value-pair from the map by using the key.
615 * This function can be used when the map is storing pointers,
616 * in order to retrieve the pointer from the map without invoking
617 * any destructor function. Sometimes you do not want the pointer
618 * to be returned - in that case (instead of suppressing the "unused
619 * result" warning) you can use cxMapDetach().
621 * If this map is not storing pointers, this function behaves like
622 * cxMapRemove() and returns \c NULL.
626 * @return the stored pointer or \c NULL if either the key is not present
627 * in the map or the map is not storing pointers
628 * @see cxMapStorePointers()
631 __attribute__((__nonnull__, __warn_unused_result__))
632 static inline void *cxMapRemoveAndGet(
636 return map->cl->remove(map, key, !map->store_pointer);
640 * Removes a key/value-pair from the map by using the key.
642 * This function can be used when the map is storing pointers,
643 * in order to retrieve the pointer from the map without invoking
644 * any destructor function. Sometimes you do not want the pointer
645 * to be returned - in that case (instead of suppressing the "unused
646 * result" warning) you can use cxMapDetach().
648 * If this map is not storing pointers, this function behaves like
649 * cxMapRemove() and returns \c NULL.
653 * @return the stored pointer or \c NULL if either the key is not present
654 * in the map or the map is not storing pointers
655 * @see cxMapStorePointers()
658 __attribute__((__nonnull__, __warn_unused_result__))
659 static inline void *cxMapRemoveAndGet(
663 return map->cl->remove(map, cx_hash_key_cxstr(key), !map->store_pointer);
667 * Removes a key/value-pair from the map by using the key.
669 * This function can be used when the map is storing pointers,
670 * in order to retrieve the pointer from the map without invoking
671 * any destructor function. Sometimes you do not want the pointer
672 * to be returned - in that case (instead of suppressing the "unused
673 * result" warning) you can use cxMapDetach().
675 * If this map is not storing pointers, this function behaves like
676 * cxMapRemove() and returns \c NULL.
680 * @return the stored pointer or \c NULL if either the key is not present
681 * in the map or the map is not storing pointers
682 * @see cxMapStorePointers()
685 __attribute__((__nonnull__, __warn_unused_result__))
686 static inline void *cxMapRemoveAndGet(
690 return map->cl->remove(map, cx_hash_key_cxstr(key), !map->store_pointer);
694 * Removes a key/value-pair from the map by using the key.
696 * This function can be used when the map is storing pointers,
697 * in order to retrieve the pointer from the map without invoking
698 * any destructor function. Sometimes you do not want the pointer
699 * to be returned - in that case (instead of suppressing the "unused
700 * result" warning) you can use cxMapDetach().
702 * If this map is not storing pointers, this function behaves like
703 * cxMapRemove() and returns \c NULL.
707 * @return the stored pointer or \c NULL if either the key is not present
708 * in the map or the map is not storing pointers
709 * @see cxMapStorePointers()
712 __attribute__((__nonnull__, __warn_unused_result__))
713 static inline void *cxMapRemoveAndGet(
717 return map->cl->remove(map, cx_hash_key_str(key), !map->store_pointer);
723 * Puts a key/value-pair into the map.
727 * @param value the value
728 * @return 0 on success, non-zero value on failure
730 __attribute__((__nonnull__))
731 static inline int cx_map_put(
736 return map->cl->put(map, key, value);
740 * Puts a key/value-pair into the map.
744 * @param value the value
745 * @return 0 on success, non-zero value on failure
747 __attribute__((__nonnull__))
748 static inline int cx_map_put_cxstr(
753 return map->cl->put(map, cx_hash_key_cxstr(key), value);
757 * Puts a key/value-pair into the map.
761 * @param value the value
762 * @return 0 on success, non-zero value on failure
764 __attribute__((__nonnull__))
765 static inline int cx_map_put_mustr(
770 return map->cl->put(map, cx_hash_key_cxstr(key), value);
774 * Puts a key/value-pair into the map.
778 * @param value the value
779 * @return 0 on success, non-zero value on failure
781 __attribute__((__nonnull__))
782 static inline int cx_map_put_str(
787 return map->cl->put(map, cx_hash_key_str(key), value);
791 * Puts a key/value-pair into the map.
795 * @param value the value
796 * @return 0 on success, non-zero value on failure
798 #define cxMapPut(map, key, value) _Generic((key), \
799 CxHashKey: cx_map_put, \
800 cxstring: cx_map_put_cxstr, \
801 cxmutstr: cx_map_put_mustr, \
802 char*: cx_map_put_str, \
803 char const*: cx_map_put_str) \
807 * Retrieves a value by using a key.
813 __attribute__((__nonnull__, __warn_unused_result__))
814 static inline void *cx_map_get(
818 return map->cl->get(map, key);
822 * Retrieves a value by using a key.
828 __attribute__((__nonnull__, __warn_unused_result__))
829 static inline void *cx_map_get_cxstr(
833 return map->cl->get(map, cx_hash_key_cxstr(key));
837 * Retrieves a value by using a key.
843 __attribute__((__nonnull__, __warn_unused_result__))
844 static inline void *cx_map_get_mustr(
848 return map->cl->get(map, cx_hash_key_cxstr(key));
852 * Retrieves a value by using a key.
858 __attribute__((__nonnull__, __warn_unused_result__))
859 static inline void *cx_map_get_str(
863 return map->cl->get(map, cx_hash_key_str(key));
867 * Retrieves a value by using a key.
873 #define cxMapGet(map, key) _Generic((key), \
874 CxHashKey: cx_map_get, \
875 cxstring: cx_map_get_cxstr, \
876 cxmutstr: cx_map_get_mustr, \
877 char*: cx_map_get_str, \
878 char const*: cx_map_get_str) \
882 * Removes a key/value-pair from the map by using the key.
887 __attribute__((__nonnull__))
888 static inline void cx_map_remove(
892 (void) map->cl->remove(map, key, true);
896 * Removes a key/value-pair from the map by using the key.
901 __attribute__((__nonnull__))
902 static inline void cx_map_remove_cxstr(
906 (void) map->cl->remove(map, cx_hash_key_cxstr(key), true);
910 * Removes a key/value-pair from the map by using the key.
915 __attribute__((__nonnull__))
916 static inline void cx_map_remove_mustr(
920 (void) map->cl->remove(map, cx_hash_key_cxstr(key), true);
924 * Removes a key/value-pair from the map by using the key.
929 __attribute__((__nonnull__))
930 static inline void cx_map_remove_str(
934 (void) map->cl->remove(map, cx_hash_key_str(key), true);
938 * Removes a key/value-pair from the map by using the key.
940 * Always invokes the destructor function, if any, on the removed element.
941 * If this map is storing pointers and you just want to retrieve the pointer
942 * without invoking the destructor, use cxMapRemoveAndGet().
943 * If you just want to detach the element from the map without invoking the
944 * destructor or returning the element, use cxMapDetach().
948 * @see cxMapRemoveAndGet()
951 #define cxMapRemove(map, key) _Generic((key), \
952 CxHashKey: cx_map_remove, \
953 cxstring: cx_map_remove_cxstr, \
954 cxmutstr: cx_map_remove_mustr, \
955 char*: cx_map_remove_str, \
956 char const*: cx_map_remove_str) \
960 * Detaches a key/value-pair from the map by using the key
961 * without invoking the destructor.
966 __attribute__((__nonnull__))
967 static inline void cx_map_detach(
971 (void) map->cl->remove(map, key, false);
975 * Detaches a key/value-pair from the map by using the key
976 * without invoking the destructor.
981 __attribute__((__nonnull__))
982 static inline void cx_map_detach_cxstr(
986 (void) map->cl->remove(map, cx_hash_key_cxstr(key), false);
990 * Detaches a key/value-pair from the map by using the key
991 * without invoking the destructor.
996 __attribute__((__nonnull__))
997 static inline void cx_map_detach_mustr(
1001 (void) map->cl->remove(map, cx_hash_key_cxstr(key), false);
1005 * Detaches a key/value-pair from the map by using the key
1006 * without invoking the destructor.
1008 * @param map the map
1009 * @param key the key
1011 __attribute__((__nonnull__))
1012 static inline void cx_map_detach_str(
1016 (void) map->cl->remove(map, cx_hash_key_str(key), false);
1020 * Detaches a key/value-pair from the map by using the key
1021 * without invoking the destructor.
1023 * In general, you should only use this function if the map does not own
1024 * the data and there is a valid reference to the data somewhere else
1025 * in the program. In all other cases it is preferable to use
1026 * cxMapRemove() or cxMapRemoveAndGet().
1028 * @param map the map
1029 * @param key the key
1030 * @see cxMapRemove()
1031 * @see cxMapRemoveAndGet()
1033 #define cxMapDetach(map, key) _Generic((key), \
1034 CxHashKey: cx_map_detach, \
1035 cxstring: cx_map_detach_cxstr, \
1036 cxmutstr: cx_map_detach_mustr, \
1037 char*: cx_map_detach_str, \
1038 char const*: cx_map_detach_str) \
1042 * Removes a key/value-pair from the map by using the key.
1044 * @param map the map
1045 * @param key the key
1046 * @return the stored pointer or \c NULL if either the key is not present
1047 * in the map or the map is not storing pointers
1049 __attribute__((__nonnull__, __warn_unused_result__))
1050 static inline void *cx_map_remove_and_get(
1054 return map->cl->remove(map, key, !map->store_pointer);
1058 * Removes a key/value-pair from the map by using the key.
1060 * @param map the map
1061 * @param key the key
1062 * @return the stored pointer or \c NULL if either the key is not present
1063 * in the map or the map is not storing pointers
1065 __attribute__((__nonnull__, __warn_unused_result__))
1066 static inline void *cx_map_remove_and_get_cxstr(
1070 return map->cl->remove(map, cx_hash_key_cxstr(key), !map->store_pointer);
1074 * Removes a key/value-pair from the map by using the key.
1076 * @param map the map
1077 * @param key the key
1078 * @return the stored pointer or \c NULL if either the key is not present
1079 * in the map or the map is not storing pointers
1081 __attribute__((__nonnull__, __warn_unused_result__))
1082 static inline void *cx_map_remove_and_get_mustr(
1086 return map->cl->remove(map, cx_hash_key_cxstr(key), !map->store_pointer);
1090 * Removes a key/value-pair from the map by using the key.
1092 * @param map the map
1093 * @param key the key
1094 * @return the stored pointer or \c NULL if either the key is not present
1095 * in the map or the map is not storing pointers
1097 __attribute__((__nonnull__, __warn_unused_result__))
1098 static inline void *cx_map_remove_and_get_str(
1102 return map->cl->remove(map, cx_hash_key_str(key), !map->store_pointer);
1106 * Removes a key/value-pair from the map by using the key.
1108 * This function can be used when the map is storing pointers,
1109 * in order to retrieve the pointer from the map without invoking
1110 * any destructor function. Sometimes you do not want the pointer
1111 * to be returned - in that case (instead of suppressing the "unused
1112 * result" warning) you can use cxMapDetach().
1114 * If this map is not storing pointers, this function behaves like
1115 * cxMapRemove() and returns \c NULL.
1117 * @param map the map
1118 * @param key the key
1119 * @return the stored pointer or \c NULL if either the key is not present
1120 * in the map or the map is not storing pointers
1121 * @see cxMapStorePointers()
1122 * @see cxMapDetach()
1124 #define cxMapRemoveAndGet(map, key) _Generic((key), \
1125 CxHashKey: cx_map_remove_and_get, \
1126 cxstring: cx_map_remove_and_get_cxstr, \
1127 cxmutstr: cx_map_remove_and_get_mustr, \
1128 char*: cx_map_remove_and_get_str, \
1129 char const*: cx_map_remove_and_get_str) \
1132 #endif // __cplusplus