Fri, 21 Apr 2023 19:50:43 +0200
bring a generic interface to CxMap
1 /*
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3 *
4 * Copyright 2021 Mike Becker, Olaf Wintermann All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
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.
15 *
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.
27 */
28 /**
29 * \file map.h
30 * \brief Interface for map implementations.
31 * \author Mike Becker
32 * \author Olaf Wintermann
33 * \version 3.0
34 * \copyright 2-Clause BSD License
35 */
37 #ifndef UCX_MAP_H
38 #define UCX_MAP_H
40 #include "common.h"
41 #include "collection.h"
42 #include "string.h"
43 #include "hash_key.h"
45 #ifdef __cplusplus
46 extern "C" {
47 #endif
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. */
59 struct cx_map_s {
60 CX_COLLECTION_MEMBERS
61 /** The map class definition. */
62 cx_map_class *cl;
63 };
65 /**
66 * The class definition for arbitrary maps.
67 */
68 struct cx_map_class_s {
69 /**
70 * Deallocates the entire memory.
71 */
72 __attribute__((__nonnull__))
73 void (*destructor)(struct cx_map_s *map);
75 /**
76 * Removes all elements.
77 */
78 __attribute__((__nonnull__))
79 void (*clear)(struct cx_map_s *map);
81 /**
82 * Add or overwrite an element.
83 */
84 __attribute__((__nonnull__))
85 int (*put)(
86 CxMap *map,
87 CxHashKey key,
88 void *value
89 );
91 /**
92 * Returns an element.
93 */
94 __attribute__((__nonnull__, __warn_unused_result__))
95 void *(*get)(
96 CxMap const *map,
97 CxHashKey key
98 );
100 /**
101 * Removes an element.
102 */
103 __attribute__((__nonnull__))
104 void *(*remove)(
105 CxMap *map,
106 CxHashKey key,
107 bool destroy
108 );
110 /**
111 * Iterator over the key/value pairs.
112 */
113 __attribute__((__nonnull__, __warn_unused_result__))
114 CxIterator (*iterator)(CxMap const *map);
116 /**
117 * Iterator over the keys.
118 */
119 __attribute__((__nonnull__, __warn_unused_result__))
120 CxIterator (*iterator_keys)(CxMap const *map);
122 /**
123 * Iterator over the values.
124 */
125 __attribute__((__nonnull__, __warn_unused_result__))
126 CxIterator (*iterator_values)(CxMap const *map);
128 /**
129 * Mutating iterator over the key/value pairs.
130 */
131 __attribute__((__nonnull__, __warn_unused_result__))
132 CxMutIterator (*mut_iterator)(CxMap *map);
134 /**
135 * Mutating iterator over the keys.
136 */
137 __attribute__((__nonnull__, __warn_unused_result__))
138 CxMutIterator (*mut_iterator_keys)(CxMap *map);
140 /**
141 * Mutating iterator over the values.
142 */
143 __attribute__((__nonnull__, __warn_unused_result__))
144 CxMutIterator (*mut_iterator_values)(CxMap *map);
145 };
147 /**
148 * A map entry.
149 */
150 struct cx_map_entry_s {
151 /**
152 * A pointer to the key.
153 */
154 CxHashKey const *key;
155 /**
156 * A pointer to the value.
157 */
158 void *value;
159 };
161 /**
162 * Advises the map to store copies of the objects (default mode of operation).
163 *
164 * Retrieving objects from this map will yield pointers to the copies stored
165 * within this list.
166 *
167 * @param map the map
168 * @see cxMapStorePointers()
169 */
170 __attribute__((__nonnull__))
171 static inline void cxMapStoreObjects(CxMap *map) {
172 map->store_pointer = false;
173 }
175 /**
176 * Advises the map to only store pointers to the objects.
177 *
178 * Retrieving objects from this list will yield the original pointers stored.
179 *
180 * @note This function forcibly sets the element size to the size of a pointer.
181 * Invoking this function on a non-empty map that already stores copies of
182 * objects is undefined.
183 *
184 * @param map the map
185 * @see cxMapStoreObjects()
186 */
187 __attribute__((__nonnull__))
188 static inline void cxMapStorePointers(CxMap *map) {
189 map->store_pointer = true;
190 map->item_size = sizeof(void *);
191 }
194 /**
195 * Deallocates the memory of the specified map.
196 *
197 * @param map the map to be destroyed
198 */
199 __attribute__((__nonnull__))
200 static inline void cxMapDestroy(CxMap *map) {
201 map->cl->destructor(map);
202 }
205 /**
206 * Clears a map by removing all elements.
207 *
208 * @param map the map to be cleared
209 */
210 __attribute__((__nonnull__))
211 static inline void cxMapClear(CxMap *map) {
212 map->cl->clear(map);
213 }
216 // TODO: set-like map operations (union, intersect, difference)
218 /**
219 * Creates a value iterator for a map.
220 *
221 * \note An iterator iterates over all elements successively. Therefore the order
222 * highly depends on the map implementation and may change arbitrarily when the contents change.
223 *
224 * @param map the map to create the iterator for
225 * @return an iterator for the currently stored values
226 */
227 __attribute__((__nonnull__, __warn_unused_result__))
228 static inline CxIterator cxMapIteratorValues(CxMap *map) {
229 return map->cl->iterator_values(map);
230 }
232 /**
233 * Creates a key iterator for a map.
234 *
235 * The elements of the iterator are keys of type CxHashKey.
236 *
237 * \note An iterator iterates over all elements successively. Therefore the order
238 * highly depends on the map implementation and may change arbitrarily when the contents change.
239 *
240 * @param map the map to create the iterator for
241 * @return an iterator for the currently stored keys
242 */
243 __attribute__((__nonnull__, __warn_unused_result__))
244 static inline CxIterator cxMapIteratorKeys(CxMap *map) {
245 return map->cl->iterator_keys(map);
246 }
248 /**
249 * Creates an iterator for a map.
250 *
251 * The elements of the iterator are key/value pairs of type CxMapEntry.
252 *
253 * \note An iterator iterates over all elements successively. Therefore the order
254 * highly depends on the map implementation and may change arbitrarily when the contents change.
255 *
256 * @param map the map to create the iterator for
257 * @return an iterator for the currently stored entries
258 * @see cxMapIteratorKeys()
259 * @see cxMapIteratorValues()
260 */
261 __attribute__((__nonnull__, __warn_unused_result__))
262 static inline CxIterator cxMapIterator(CxMap *map) {
263 return map->cl->iterator(map);
264 }
267 /**
268 * Creates a mutating iterator over the values of a map.
269 *
270 * \note An iterator iterates over all elements successively. Therefore the order
271 * highly depends on the map implementation and may change arbitrarily when the contents change.
272 *
273 * @param map the map to create the iterator for
274 * @return an iterator for the currently stored values
275 */
276 __attribute__((__nonnull__, __warn_unused_result__))
277 static inline CxMutIterator cxMapMutIteratorValues(CxMap *map) {
278 return map->cl->mut_iterator_values(map);
279 }
281 /**
282 * Creates a mutating iterator over the keys of a map.
283 *
284 * The elements of the iterator are keys of type CxHashKey.
285 *
286 * \note An iterator iterates over all elements successively. Therefore the order
287 * highly depends on the map implementation and may change arbitrarily when the contents change.
288 *
289 * @param map the map to create the iterator for
290 * @return an iterator for the currently stored keys
291 */
292 __attribute__((__nonnull__, __warn_unused_result__))
293 static inline CxMutIterator cxMapMutIteratorKeys(CxMap *map) {
294 return map->cl->mut_iterator_keys(map);
295 }
297 /**
298 * Creates a mutating iterator for a map.
299 *
300 * The elements of the iterator are key/value pairs of type CxMapEntry.
301 *
302 * \note An iterator iterates over all elements successively. Therefore the order
303 * highly depends on the map implementation and may change arbitrarily when the contents change.
304 *
305 * @param map the map to create the iterator for
306 * @return an iterator for the currently stored entries
307 * @see cxMapMutIteratorKeys()
308 * @see cxMapMutIteratorValues()
309 */
310 __attribute__((__nonnull__, __warn_unused_result__))
311 static inline CxMutIterator cxMapMutIterator(CxMap *map) {
312 return map->cl->mut_iterator(map);
313 }
315 #ifdef __cplusplus
316 } // end the extern "C" block here, because we want to start overloading
318 /**
319 * Puts a key/value-pair into the map.
320 *
321 * @param map the map
322 * @param key the key
323 * @param value the value
324 * @return 0 on success, non-zero value on failure
325 */
326 __attribute__((__nonnull__))
327 static inline int cxMapPut(
328 CxMap *map,
329 CxHashKey const &key,
330 void *value
331 ) {
332 return map->cl->put(map, key, value);
333 }
336 /**
337 * Puts a key/value-pair into the map.
338 *
339 * @param map the map
340 * @param key the key
341 * @param value the value
342 * @return 0 on success, non-zero value on failure
343 */
344 __attribute__((__nonnull__))
345 static inline int cxMapPut(
346 CxMap *map,
347 cxstring const &key,
348 void *value
349 ) {
350 return map->cl->put(map, cx_hash_key_cxstr(key), value);
351 }
353 /**
354 * Puts a key/value-pair into the map.
355 *
356 * @param map the map
357 * @param key the key
358 * @param value the value
359 * @return 0 on success, non-zero value on failure
360 */
361 __attribute__((__nonnull__))
362 static inline int cxMapPut(
363 CxMap *map,
364 char const *key,
365 void *value
366 ) {
367 return map->cl->put(map, cx_hash_key_str(key), value);
368 }
370 /**
371 * Retrieves a value by using a key.
372 *
373 * @param map the map
374 * @param key the key
375 * @return the value
376 */
377 __attribute__((__nonnull__, __warn_unused_result__))
378 static inline void *cxMapGet(
379 CxMap const *map,
380 CxHashKey const &key
381 ) {
382 return map->cl->get(map, key);
383 }
385 /**
386 * Retrieves a value by using a key.
387 *
388 * @param map the map
389 * @param key the key
390 * @return the value
391 */
392 __attribute__((__nonnull__, __warn_unused_result__))
393 static inline void *cxMapGet(
394 CxMap const *map,
395 cxstring const &key
396 ) {
397 return map->cl->get(map, cx_hash_key_cxstr(key));
398 }
400 /**
401 * Retrieves a value by using a key.
402 *
403 * @param map the map
404 * @param key the key
405 * @return the value
406 */
407 __attribute__((__nonnull__, __warn_unused_result__))
408 static inline void *cxMapGet(
409 CxMap const *map,
410 char const *key
411 ) {
412 return map->cl->get(map, cx_hash_key_str(key));
413 }
415 /**
416 * Removes a key/value-pair from the map by using the key.
417 *
418 * Always invokes the destructor function, if any, on the removed element.
419 * If this map is storing pointers and you just want to retrieve the pointer
420 * without invoking the destructor, use cxMapRemoveAndGet().
421 * If you just want to detach the element from the map without invoking the
422 * destructor or returning the element, use cxMapDetach().
423 *
424 * @param map the map
425 * @param key the key
426 * @see cxMapRemoveAndGet()
427 * @see cxMapDetach()
428 */
429 __attribute__((__nonnull__))
430 static inline void cxMapRemove(
431 CxMap *map,
432 CxHashKey const &key
433 ) {
434 (void) map->cl->remove(map, key, true);
435 }
437 /**
438 * Removes a key/value-pair from the map by using the key.
439 *
440 * Always invokes the destructor function, if any, on the removed element.
441 * If this map is storing pointers and you just want to retrieve the pointer
442 * without invoking the destructor, use cxMapRemoveAndGet().
443 * If you just want to detach the element from the map without invoking the
444 * destructor or returning the element, use cxMapDetach().
445 *
446 * @param map the map
447 * @param key the key
448 * @see cxMapRemoveAndGet()
449 * @see cxMapDetach()
450 */
451 __attribute__((__nonnull__))
452 static inline void cxMapRemove(
453 CxMap *map,
454 cxstring const &key
455 ) {
456 (void) map->cl->remove(map, cx_hash_key_cxstr(key), true);
457 }
459 /**
460 * Removes a key/value-pair from the map by using the key.
461 *
462 * Always invokes the destructor function, if any, on the removed element.
463 * If this map is storing pointers and you just want to retrieve the pointer
464 * without invoking the destructor, use cxMapRemoveAndGet().
465 * If you just want to detach the element from the map without invoking the
466 * destructor or returning the element, use cxMapDetach().
467 *
468 * @param map the map
469 * @param key the key
470 * @see cxMapRemoveAndGet()
471 * @see cxMapDetach()
472 */
473 __attribute__((__nonnull__))
474 static inline void cxMapRemove(
475 CxMap *map,
476 char const *key
477 ) {
478 (void) map->cl->remove(map, cx_hash_key_str(key), true);
479 }
481 /**
482 * Detaches a key/value-pair from the map by using the key
483 * without invoking the destructor.
484 *
485 * In general, you should only use this function if the map does not own
486 * the data and there is a valid reference to the data somewhere else
487 * in the program. In all other cases it is preferable to use
488 * cxMapRemove() or cxMapRemoveAndGet().
489 *
490 * @param map the map
491 * @param key the key
492 * @see cxMapRemove()
493 * @see cxMapRemoveAndGet()
494 */
495 __attribute__((__nonnull__))
496 static inline void cxMapDetach(
497 CxMap *map,
498 CxHashKey const &key
499 ) {
500 (void) map->cl->remove(map, key, false);
501 }
503 /**
504 * Detaches a key/value-pair from the map by using the key
505 * without invoking the destructor.
506 *
507 * In general, you should only use this function if the map does not own
508 * the data and there is a valid reference to the data somewhere else
509 * in the program. In all other cases it is preferable to use
510 * cxMapRemove() or cxMapRemoveAndGet().
511 *
512 * @param map the map
513 * @param key the key
514 * @see cxMapRemove()
515 * @see cxMapRemoveAndGet()
516 */
517 __attribute__((__nonnull__))
518 static inline void cxMapDetach(
519 CxMap *map,
520 cxstring const &key
521 ) {
522 (void) map->cl->remove(map, cx_hash_key_cxstr(key), false);
523 }
525 /**
526 * Detaches a key/value-pair from the map by using the key
527 * without invoking the destructor.
528 *
529 * In general, you should only use this function if the map does not own
530 * the data and there is a valid reference to the data somewhere else
531 * in the program. In all other cases it is preferable to use
532 * cxMapRemove() or cxMapRemoveAndGet().
533 *
534 * @param map the map
535 * @param key the key
536 * @see cxMapRemove()
537 * @see cxMapRemoveAndGet()
538 */
539 __attribute__((__nonnull__))
540 static inline void cxMapDetach(
541 CxMap *map,
542 char const *key
543 ) {
544 (void) map->cl->remove(map, cx_hash_key_str(key), false);
545 }
547 /**
548 * Removes a key/value-pair from the map by using the key.
549 *
550 * This function can be used when the map is storing pointers,
551 * in order to retrieve the pointer from the map without invoking
552 * any destructor function. Sometimes you do not want the pointer
553 * to be returned - in that case (instead of suppressing the "unused
554 * result" warning) you can use cxMapDetach().
555 *
556 * If this map is not storing pointers, this function behaves like
557 * cxMapRemove() and returns \c NULL.
558 *
559 * @param map the map
560 * @param key the key
561 * @return the stored pointer or \c NULL if either the key is not present
562 * in the map or the map is not storing pointers
563 * @see cxMapStorePointers()
564 * @see cxMapDetach()
565 */
566 __attribute__((__nonnull__, __warn_unused_result__))
567 static inline void *cxMapRemoveAndGet(
568 CxMap *map,
569 CxHashKey key
570 ) {
571 return map->cl->remove(map, key, !map->store_pointer);
572 }
574 /**
575 * Removes a key/value-pair from the map by using the key.
576 *
577 * This function can be used when the map is storing pointers,
578 * in order to retrieve the pointer from the map without invoking
579 * any destructor function. Sometimes you do not want the pointer
580 * to be returned - in that case (instead of suppressing the "unused
581 * result" warning) you can use cxMapDetach().
582 *
583 * If this map is not storing pointers, this function behaves like
584 * cxMapRemove() and returns \c NULL.
585 *
586 * @param map the map
587 * @param key the key
588 * @return the stored pointer or \c NULL if either the key is not present
589 * in the map or the map is not storing pointers
590 * @see cxMapStorePointers()
591 * @see cxMapDetach()
592 */
593 __attribute__((__nonnull__, __warn_unused_result__))
594 static inline void *cxMapRemoveAndGet(
595 CxMap *map,
596 cxstring key
597 ) {
598 return map->cl->remove(map, cx_hash_key_cxstr(key), !map->store_pointer);
599 }
601 /**
602 * Removes a key/value-pair from the map by using the key.
603 *
604 * This function can be used when the map is storing pointers,
605 * in order to retrieve the pointer from the map without invoking
606 * any destructor function. Sometimes you do not want the pointer
607 * to be returned - in that case (instead of suppressing the "unused
608 * result" warning) you can use cxMapDetach().
609 *
610 * If this map is not storing pointers, this function behaves like
611 * cxMapRemove() and returns \c NULL.
612 *
613 * @param map the map
614 * @param key the key
615 * @return the stored pointer or \c NULL if either the key is not present
616 * in the map or the map is not storing pointers
617 * @see cxMapStorePointers()
618 * @see cxMapDetach()
619 */
620 __attribute__((__nonnull__, __warn_unused_result__))
621 static inline void *cxMapRemoveAndGet(
622 CxMap *map,
623 char const *key
624 ) {
625 return map->cl->remove(map, cx_hash_key_str(key), !map->store_pointer);
626 }
628 #else // __cplusplus
630 /**
631 * Puts a key/value-pair into the map.
632 *
633 * @param map the map
634 * @param key the key
635 * @param value the value
636 * @return 0 on success, non-zero value on failure
637 */
638 __attribute__((__nonnull__))
639 static inline int cx_map_put(
640 CxMap *map,
641 CxHashKey key,
642 void *value
643 ) {
644 return map->cl->put(map, key, value);
645 }
647 /**
648 * Puts a key/value-pair into the map.
649 *
650 * @param map the map
651 * @param key the key
652 * @param value the value
653 * @return 0 on success, non-zero value on failure
654 */
655 __attribute__((__nonnull__))
656 static inline int cx_map_put_cxstr(
657 CxMap *map,
658 cxstring key,
659 void *value
660 ) {
661 return map->cl->put(map, cx_hash_key_cxstr(key), value);
662 }
664 /**
665 * Puts a key/value-pair into the map.
666 *
667 * @param map the map
668 * @param key the key
669 * @param value the value
670 * @return 0 on success, non-zero value on failure
671 */
672 __attribute__((__nonnull__))
673 static inline int cx_map_put_str(
674 CxMap *map,
675 char const *key,
676 void *value
677 ) {
678 return map->cl->put(map, cx_hash_key_str(key), value);
679 }
681 /**
682 * Puts a key/value-pair into the map.
683 *
684 * @param map the map
685 * @param key the key
686 * @param value the value
687 * @return 0 on success, non-zero value on failure
688 */
689 #define cxMapPut(map, key, value) _Generic((key), \
690 CxHashKey: cx_map_put, \
691 cxstring: cx_map_put_cxstr, \
692 char*: cx_map_put_str) \
693 (map, key, value)
695 /**
696 * Retrieves a value by using a key.
697 *
698 * @param map the map
699 * @param key the key
700 * @return the value
701 */
702 __attribute__((__nonnull__, __warn_unused_result__))
703 static inline void *cx_map_get(
704 CxMap const *map,
705 CxHashKey key
706 ) {
707 return map->cl->get(map, key);
708 }
710 /**
711 * Retrieves a value by using a key.
712 *
713 * @param map the map
714 * @param key the key
715 * @return the value
716 */
717 __attribute__((__nonnull__, __warn_unused_result__))
718 static inline void *cx_map_get_cxstr(
719 CxMap const *map,
720 cxstring key
721 ) {
722 return map->cl->get(map, cx_hash_key_cxstr(key));
723 }
725 /**
726 * Retrieves a value by using a key.
727 *
728 * @param map the map
729 * @param key the key
730 * @return the value
731 */
732 __attribute__((__nonnull__, __warn_unused_result__))
733 static inline void *cx_map_get_str(
734 CxMap const *map,
735 char const *key
736 ) {
737 return map->cl->get(map, cx_hash_key_str(key));
738 }
740 /**
741 * Retrieves a value by using a key.
742 *
743 * @param map the map
744 * @param key the key
745 * @return the value
746 */
747 #define cxMapGet(map, key) _Generic((key), \
748 CxHashKey: cx_map_get, \
749 cxstring: cx_map_get_cxstr, \
750 char*: cx_map_get_str) \
751 (map, key)
753 /**
754 * Removes a key/value-pair from the map by using the key.
755 *
756 * @param map the map
757 * @param key the key
758 */
759 __attribute__((__nonnull__))
760 static inline void cx_map_remove(
761 CxMap *map,
762 CxHashKey key
763 ) {
764 (void) map->cl->remove(map, key, true);
765 }
767 /**
768 * Removes a key/value-pair from the map by using the key.
769 *
770 * @param map the map
771 * @param key the key
772 */
773 __attribute__((__nonnull__))
774 static inline void cx_map_remove_cxstr(
775 CxMap *map,
776 cxstring key
777 ) {
778 (void) map->cl->remove(map, cx_hash_key_cxstr(key), true);
779 }
781 /**
782 * Removes a key/value-pair from the map by using the key.
783 *
784 * @param map the map
785 * @param key the key
786 */
787 __attribute__((__nonnull__))
788 static inline void cx_map_remove_str(
789 CxMap *map,
790 char const *key
791 ) {
792 (void) map->cl->remove(map, cx_hash_key_str(key), true);
793 }
795 /**
796 * Removes a key/value-pair from the map by using the key.
797 *
798 * Always invokes the destructor function, if any, on the removed element.
799 * If this map is storing pointers and you just want to retrieve the pointer
800 * without invoking the destructor, use cxMapRemoveAndGet().
801 * If you just want to detach the element from the map without invoking the
802 * destructor or returning the element, use cxMapDetach().
803 *
804 * @param map the map
805 * @param key the key
806 * @see cxMapRemoveAndGet()
807 * @see cxMapDetach()
808 */
809 #define cxMapRemove(map, key) _Generic((key), \
810 CxHashKey: cx_map_remove, \
811 cxstring: cx_map_remove_cxstr, \
812 char*: cx_map_remove_str) \
813 (map, key)
815 /**
816 * Detaches a key/value-pair from the map by using the key
817 * without invoking the destructor.
818 *
819 * @param map the map
820 * @param key the key
821 */
822 __attribute__((__nonnull__))
823 static inline void cx_map_detach(
824 CxMap *map,
825 CxHashKey key
826 ) {
827 (void) map->cl->remove(map, key, false);
828 }
830 /**
831 * Detaches a key/value-pair from the map by using the key
832 * without invoking the destructor.
833 *
834 * @param map the map
835 * @param key the key
836 */
837 __attribute__((__nonnull__))
838 static inline void cx_map_detach_cxstr(
839 CxMap *map,
840 cxstring key
841 ) {
842 (void) map->cl->remove(map, cx_hash_key_cxstr(key), false);
843 }
845 /**
846 * Detaches a key/value-pair from the map by using the key
847 * without invoking the destructor.
848 *
849 * @param map the map
850 * @param key the key
851 */
852 __attribute__((__nonnull__))
853 static inline void cx_map_detach_str(
854 CxMap *map,
855 char const *key
856 ) {
857 (void) map->cl->remove(map, cx_hash_key_str(key), false);
858 }
860 /**
861 * Detaches a key/value-pair from the map by using the key
862 * without invoking the destructor.
863 *
864 * In general, you should only use this function if the map does not own
865 * the data and there is a valid reference to the data somewhere else
866 * in the program. In all other cases it is preferable to use
867 * cxMapRemove() or cxMapRemoveAndGet().
868 *
869 * @param map the map
870 * @param key the key
871 * @see cxMapRemove()
872 * @see cxMapRemoveAndGet()
873 */
874 #define cxMapDetach(map, key) _Generic((key), \
875 CxHashKey: cx_map_detach, \
876 cxstring: cx_map_detach_cxstr, \
877 char*: cx_map_detach_str) \
878 (map, key)
880 /**
881 * Removes a key/value-pair from the map by using the key.
882 *
883 * @param map the map
884 * @param key the key
885 * @return the stored pointer or \c NULL if either the key is not present
886 * in the map or the map is not storing pointers
887 */
888 __attribute__((__nonnull__, __warn_unused_result__))
889 static inline void *cx_map_remove_and_get(
890 CxMap *map,
891 CxHashKey key
892 ) {
893 return map->cl->remove(map, key, !map->store_pointer);
894 }
896 /**
897 * Removes a key/value-pair from the map by using the key.
898 *
899 * @param map the map
900 * @param key the key
901 * @return the stored pointer or \c NULL if either the key is not present
902 * in the map or the map is not storing pointers
903 */
904 __attribute__((__nonnull__, __warn_unused_result__))
905 static inline void *cx_map_remove_and_get_cxstr(
906 CxMap *map,
907 cxstring key
908 ) {
909 return map->cl->remove(map, cx_hash_key_cxstr(key), !map->store_pointer);
910 }
912 /**
913 * Removes a key/value-pair from the map by using the key.
914 *
915 * @param map the map
916 * @param key the key
917 * @return the stored pointer or \c NULL if either the key is not present
918 * in the map or the map is not storing pointers
919 */
920 __attribute__((__nonnull__, __warn_unused_result__))
921 static inline void *cx_map_remove_and_get_str(
922 CxMap *map,
923 char const *key
924 ) {
925 return map->cl->remove(map, cx_hash_key_str(key), !map->store_pointer);
926 }
928 /**
929 * Removes a key/value-pair from the map by using the key.
930 *
931 * This function can be used when the map is storing pointers,
932 * in order to retrieve the pointer from the map without invoking
933 * any destructor function. Sometimes you do not want the pointer
934 * to be returned - in that case (instead of suppressing the "unused
935 * result" warning) you can use cxMapDetach().
936 *
937 * If this map is not storing pointers, this function behaves like
938 * cxMapRemove() and returns \c NULL.
939 *
940 * @param map the map
941 * @param key the key
942 * @return the stored pointer or \c NULL if either the key is not present
943 * in the map or the map is not storing pointers
944 * @see cxMapStorePointers()
945 * @see cxMapDetach()
946 */
947 #define cxMapRemoveAndGet(map, key) _Generic((key), \
948 CxHashKey: cx_map_remove_and_get, \
949 cxstring: cx_map_remove_and_get_cxstr, \
950 char*: cx_map_remove_and_get_str) \
951 (map, key)
953 #endif // __cplusplus
955 #endif // UCX_MAP_H