Thu, 28 Dec 2023 19:17:45 +0100
fix accidental generation of cxListIterator() symbol
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 * \copyright 2-Clause BSD License
34 */
36 #ifndef UCX_MAP_H
37 #define UCX_MAP_H
39 #include "common.h"
40 #include "collection.h"
41 #include "string.h"
42 #include "hash_key.h"
44 #ifdef __cplusplus
45 extern "C" {
46 #endif
48 /** Type for the UCX map. */
49 typedef struct cx_map_s CxMap;
51 /** Type for a map entry. */
52 typedef struct cx_map_entry_s CxMapEntry;
54 /** Type for map class definitions. */
55 typedef struct cx_map_class_s cx_map_class;
57 /** Structure for the UCX map. */
58 struct cx_map_s {
59 CX_COLLECTION_MEMBERS
60 /** The map class definition. */
61 cx_map_class *cl;
62 };
64 /**
65 * The type of iterator for a map.
66 */
67 enum cx_map_iterator_type {
68 /**
69 * Iterates over key/value pairs.
70 */
71 CX_MAP_ITERATOR_PAIRS,
72 /**
73 * Iterates over keys only.
74 */
75 CX_MAP_ITERATOR_KEYS,
76 /**
77 * Iterates over values only.
78 */
79 CX_MAP_ITERATOR_VALUES
80 };
82 /**
83 * The class definition for arbitrary maps.
84 */
85 struct cx_map_class_s {
86 /**
87 * Deallocates the entire memory.
88 */
89 __attribute__((__nonnull__))
90 void (*destructor)(struct cx_map_s *map);
92 /**
93 * Removes all elements.
94 */
95 __attribute__((__nonnull__))
96 void (*clear)(struct cx_map_s *map);
98 /**
99 * Add or overwrite an element.
100 */
101 __attribute__((__nonnull__))
102 int (*put)(
103 CxMap *map,
104 CxHashKey key,
105 void *value
106 );
108 /**
109 * Returns an element.
110 */
111 __attribute__((__nonnull__, __warn_unused_result__))
112 void *(*get)(
113 CxMap const *map,
114 CxHashKey key
115 );
117 /**
118 * Removes an element.
119 */
120 __attribute__((__nonnull__))
121 void *(*remove)(
122 CxMap *map,
123 CxHashKey key,
124 bool destroy
125 );
127 /**
128 * Creates an iterator for this map.
129 */
130 __attribute__((__nonnull__, __warn_unused_result__))
131 CxIterator (*iterator)(CxMap const *map, enum cx_map_iterator_type type);
132 };
134 /**
135 * A map entry.
136 */
137 struct cx_map_entry_s {
138 /**
139 * A pointer to the key.
140 */
141 CxHashKey const *key;
142 /**
143 * A pointer to the value.
144 */
145 void *value;
146 };
148 /**
149 * A shared instance of an empty map.
150 *
151 * Writing to that map is undefined.
152 */
153 extern CxMap *const cxEmptyMap;
155 /**
156 * Advises the map to store copies of the objects (default mode of operation).
157 *
158 * Retrieving objects from this map will yield pointers to the copies stored
159 * within this list.
160 *
161 * @param map the map
162 * @see cxMapStorePointers()
163 */
164 __attribute__((__nonnull__))
165 static inline void cxMapStoreObjects(CxMap *map) {
166 map->store_pointer = false;
167 }
169 /**
170 * Advises the map to only store pointers to the objects.
171 *
172 * Retrieving objects from this list will yield the original pointers stored.
173 *
174 * @note This function forcibly sets the element size to the size of a pointer.
175 * Invoking this function on a non-empty map that already stores copies of
176 * objects is undefined.
177 *
178 * @param map the map
179 * @see cxMapStoreObjects()
180 */
181 __attribute__((__nonnull__))
182 static inline void cxMapStorePointers(CxMap *map) {
183 map->store_pointer = true;
184 map->item_size = sizeof(void *);
185 }
188 /**
189 * Deallocates the memory of the specified map.
190 *
191 * @param map the map to be destroyed
192 */
193 __attribute__((__nonnull__))
194 static inline void cxMapDestroy(CxMap *map) {
195 map->cl->destructor(map);
196 }
199 /**
200 * Clears a map by removing all elements.
201 *
202 * @param map the map to be cleared
203 */
204 __attribute__((__nonnull__))
205 static inline void cxMapClear(CxMap *map) {
206 map->cl->clear(map);
207 }
210 // TODO: set-like map operations (union, intersect, difference)
212 /**
213 * Creates a value iterator for a map.
214 *
215 * \note An iterator iterates over all elements successively. Therefore the order
216 * highly depends on the map implementation and may change arbitrarily when the contents change.
217 *
218 * @param map the map to create the iterator for
219 * @return an iterator for the currently stored values
220 */
221 __attribute__((__nonnull__, __warn_unused_result__))
222 static inline CxIterator cxMapIteratorValues(CxMap const *map) {
223 return map->cl->iterator(map, CX_MAP_ITERATOR_VALUES);
224 }
226 /**
227 * Creates a key iterator for a map.
228 *
229 * The elements of the iterator are keys of type CxHashKey.
230 *
231 * \note An iterator iterates over all elements successively. Therefore the order
232 * highly depends on the map implementation and may change arbitrarily when the contents change.
233 *
234 * @param map the map to create the iterator for
235 * @return an iterator for the currently stored keys
236 */
237 __attribute__((__nonnull__, __warn_unused_result__))
238 static inline CxIterator cxMapIteratorKeys(CxMap const *map) {
239 return map->cl->iterator(map, CX_MAP_ITERATOR_KEYS);
240 }
242 /**
243 * Creates an iterator for a map.
244 *
245 * The elements of the iterator are key/value pairs of type CxMapEntry.
246 *
247 * \note An iterator iterates over all elements successively. Therefore the order
248 * highly depends on the map implementation and may change arbitrarily when the contents change.
249 *
250 * @param map the map to create the iterator for
251 * @return an iterator for the currently stored entries
252 * @see cxMapIteratorKeys()
253 * @see cxMapIteratorValues()
254 */
255 __attribute__((__nonnull__, __warn_unused_result__))
256 static inline CxIterator cxMapIterator(CxMap const *map) {
257 return map->cl->iterator(map, CX_MAP_ITERATOR_PAIRS);
258 }
261 /**
262 * Creates a mutating iterator over the values of a map.
263 *
264 * \note An iterator iterates over all elements successively. Therefore the order
265 * highly depends on the map implementation and may change arbitrarily when the contents change.
266 *
267 * @param map the map to create the iterator for
268 * @return an iterator for the currently stored values
269 */
270 __attribute__((__nonnull__, __warn_unused_result__))
271 CxMutIterator cxMapMutIteratorValues(CxMap *map);
273 /**
274 * Creates a mutating iterator over the keys of a map.
275 *
276 * The elements of the iterator are keys of type CxHashKey.
277 *
278 * \note An iterator iterates over all elements successively. Therefore the order
279 * highly depends on the map implementation and may change arbitrarily when the contents change.
280 *
281 * @param map the map to create the iterator for
282 * @return an iterator for the currently stored keys
283 */
284 __attribute__((__nonnull__, __warn_unused_result__))
285 CxMutIterator cxMapMutIteratorKeys(CxMap *map);
287 /**
288 * Creates a mutating iterator for a map.
289 *
290 * The elements of the iterator are key/value pairs of type CxMapEntry.
291 *
292 * \note An iterator iterates over all elements successively. Therefore the order
293 * highly depends on the map implementation and may change arbitrarily when the contents change.
294 *
295 * @param map the map to create the iterator for
296 * @return an iterator for the currently stored entries
297 * @see cxMapMutIteratorKeys()
298 * @see cxMapMutIteratorValues()
299 */
300 __attribute__((__nonnull__, __warn_unused_result__))
301 CxMutIterator cxMapMutIterator(CxMap *map);
303 #ifdef __cplusplus
304 } // end the extern "C" block here, because we want to start overloading
306 /**
307 * Puts a key/value-pair into the map.
308 *
309 * @param map the map
310 * @param key the key
311 * @param value the value
312 * @return 0 on success, non-zero value on failure
313 */
314 __attribute__((__nonnull__))
315 static inline int cxMapPut(
316 CxMap *map,
317 CxHashKey const &key,
318 void *value
319 ) {
320 return map->cl->put(map, key, value);
321 }
324 /**
325 * Puts a key/value-pair into the map.
326 *
327 * @param map the map
328 * @param key the key
329 * @param value the value
330 * @return 0 on success, non-zero value on failure
331 */
332 __attribute__((__nonnull__))
333 static inline int cxMapPut(
334 CxMap *map,
335 cxstring const &key,
336 void *value
337 ) {
338 return map->cl->put(map, cx_hash_key_cxstr(key), value);
339 }
341 /**
342 * Puts a key/value-pair into the map.
343 *
344 * @param map the map
345 * @param key the key
346 * @param value the value
347 * @return 0 on success, non-zero value on failure
348 */
349 __attribute__((__nonnull__))
350 static inline int cxMapPut(
351 CxMap *map,
352 cxmutstr const &key,
353 void *value
354 ) {
355 return map->cl->put(map, cx_hash_key_cxstr(key), value);
356 }
358 /**
359 * Puts a key/value-pair into the map.
360 *
361 * @param map the map
362 * @param key the key
363 * @param value the value
364 * @return 0 on success, non-zero value on failure
365 */
366 __attribute__((__nonnull__))
367 static inline int cxMapPut(
368 CxMap *map,
369 char const *key,
370 void *value
371 ) {
372 return map->cl->put(map, cx_hash_key_str(key), value);
373 }
375 /**
376 * Retrieves a value by using a key.
377 *
378 * @param map the map
379 * @param key the key
380 * @return the value
381 */
382 __attribute__((__nonnull__, __warn_unused_result__))
383 static inline void *cxMapGet(
384 CxMap const *map,
385 CxHashKey const &key
386 ) {
387 return map->cl->get(map, key);
388 }
390 /**
391 * Retrieves a value by using a key.
392 *
393 * @param map the map
394 * @param key the key
395 * @return the value
396 */
397 __attribute__((__nonnull__, __warn_unused_result__))
398 static inline void *cxMapGet(
399 CxMap const *map,
400 cxstring const &key
401 ) {
402 return map->cl->get(map, cx_hash_key_cxstr(key));
403 }
405 /**
406 * Retrieves a value by using a key.
407 *
408 * @param map the map
409 * @param key the key
410 * @return the value
411 */
412 __attribute__((__nonnull__, __warn_unused_result__))
413 static inline void *cxMapGet(
414 CxMap const *map,
415 cxmutstr const &key
416 ) {
417 return map->cl->get(map, cx_hash_key_cxstr(key));
418 }
420 /**
421 * Retrieves a value by using a key.
422 *
423 * @param map the map
424 * @param key the key
425 * @return the value
426 */
427 __attribute__((__nonnull__, __warn_unused_result__))
428 static inline void *cxMapGet(
429 CxMap const *map,
430 char const *key
431 ) {
432 return map->cl->get(map, cx_hash_key_str(key));
433 }
435 /**
436 * Removes a key/value-pair from the map by using the key.
437 *
438 * Always invokes the destructor function, if any, on the removed element.
439 * If this map is storing pointers and you just want to retrieve the pointer
440 * without invoking the destructor, use cxMapRemoveAndGet().
441 * If you just want to detach the element from the map without invoking the
442 * destructor or returning the element, use cxMapDetach().
443 *
444 * @param map the map
445 * @param key the key
446 * @see cxMapRemoveAndGet()
447 * @see cxMapDetach()
448 */
449 __attribute__((__nonnull__))
450 static inline void cxMapRemove(
451 CxMap *map,
452 CxHashKey const &key
453 ) {
454 (void) map->cl->remove(map, key, true);
455 }
457 /**
458 * Removes a key/value-pair from the map by using the key.
459 *
460 * Always invokes the destructor function, if any, on the removed element.
461 * If this map is storing pointers and you just want to retrieve the pointer
462 * without invoking the destructor, use cxMapRemoveAndGet().
463 * If you just want to detach the element from the map without invoking the
464 * destructor or returning the element, use cxMapDetach().
465 *
466 * @param map the map
467 * @param key the key
468 * @see cxMapRemoveAndGet()
469 * @see cxMapDetach()
470 */
471 __attribute__((__nonnull__))
472 static inline void cxMapRemove(
473 CxMap *map,
474 cxstring const &key
475 ) {
476 (void) map->cl->remove(map, cx_hash_key_cxstr(key), true);
477 }
479 /**
480 * Removes a key/value-pair from the map by using the key.
481 *
482 * Always invokes the destructor function, if any, on the removed element.
483 * If this map is storing pointers and you just want to retrieve the pointer
484 * without invoking the destructor, use cxMapRemoveAndGet().
485 * If you just want to detach the element from the map without invoking the
486 * destructor or returning the element, use cxMapDetach().
487 *
488 * @param map the map
489 * @param key the key
490 * @see cxMapRemoveAndGet()
491 * @see cxMapDetach()
492 */
493 __attribute__((__nonnull__))
494 static inline void cxMapRemove(
495 CxMap *map,
496 cxmutstr const &key
497 ) {
498 (void) map->cl->remove(map, cx_hash_key_cxstr(key), true);
499 }
501 /**
502 * Removes a key/value-pair from the map by using the key.
503 *
504 * Always invokes the destructor function, if any, on the removed element.
505 * If this map is storing pointers and you just want to retrieve the pointer
506 * without invoking the destructor, use cxMapRemoveAndGet().
507 * If you just want to detach the element from the map without invoking the
508 * destructor or returning the element, use cxMapDetach().
509 *
510 * @param map the map
511 * @param key the key
512 * @see cxMapRemoveAndGet()
513 * @see cxMapDetach()
514 */
515 __attribute__((__nonnull__))
516 static inline void cxMapRemove(
517 CxMap *map,
518 char const *key
519 ) {
520 (void) map->cl->remove(map, cx_hash_key_str(key), true);
521 }
523 /**
524 * Detaches a key/value-pair from the map by using the key
525 * without invoking the destructor.
526 *
527 * In general, you should only use this function if the map does not own
528 * the data and there is a valid reference to the data somewhere else
529 * in the program. In all other cases it is preferable to use
530 * cxMapRemove() or cxMapRemoveAndGet().
531 *
532 * @param map the map
533 * @param key the key
534 * @see cxMapRemove()
535 * @see cxMapRemoveAndGet()
536 */
537 __attribute__((__nonnull__))
538 static inline void cxMapDetach(
539 CxMap *map,
540 CxHashKey const &key
541 ) {
542 (void) map->cl->remove(map, key, false);
543 }
545 /**
546 * Detaches a key/value-pair from the map by using the key
547 * without invoking the destructor.
548 *
549 * In general, you should only use this function if the map does not own
550 * the data and there is a valid reference to the data somewhere else
551 * in the program. In all other cases it is preferable to use
552 * cxMapRemove() or cxMapRemoveAndGet().
553 *
554 * @param map the map
555 * @param key the key
556 * @see cxMapRemove()
557 * @see cxMapRemoveAndGet()
558 */
559 __attribute__((__nonnull__))
560 static inline void cxMapDetach(
561 CxMap *map,
562 cxstring const &key
563 ) {
564 (void) map->cl->remove(map, cx_hash_key_cxstr(key), false);
565 }
567 /**
568 * Detaches a key/value-pair from the map by using the key
569 * without invoking the destructor.
570 *
571 * In general, you should only use this function if the map does not own
572 * the data and there is a valid reference to the data somewhere else
573 * in the program. In all other cases it is preferable to use
574 * cxMapRemove() or cxMapRemoveAndGet().
575 *
576 * @param map the map
577 * @param key the key
578 * @see cxMapRemove()
579 * @see cxMapRemoveAndGet()
580 */
581 __attribute__((__nonnull__))
582 static inline void cxMapDetach(
583 CxMap *map,
584 cxmutstr const &key
585 ) {
586 (void) map->cl->remove(map, cx_hash_key_cxstr(key), false);
587 }
589 /**
590 * Detaches a key/value-pair from the map by using the key
591 * without invoking the destructor.
592 *
593 * In general, you should only use this function if the map does not own
594 * the data and there is a valid reference to the data somewhere else
595 * in the program. In all other cases it is preferable to use
596 * cxMapRemove() or cxMapRemoveAndGet().
597 *
598 * @param map the map
599 * @param key the key
600 * @see cxMapRemove()
601 * @see cxMapRemoveAndGet()
602 */
603 __attribute__((__nonnull__))
604 static inline void cxMapDetach(
605 CxMap *map,
606 char const *key
607 ) {
608 (void) map->cl->remove(map, cx_hash_key_str(key), false);
609 }
611 /**
612 * Removes a key/value-pair from the map by using the key.
613 *
614 * This function can be used when the map is storing pointers,
615 * in order to retrieve the pointer from the map without invoking
616 * any destructor function. Sometimes you do not want the pointer
617 * to be returned - in that case (instead of suppressing the "unused
618 * result" warning) you can use cxMapDetach().
619 *
620 * If this map is not storing pointers, this function behaves like
621 * cxMapRemove() and returns \c NULL.
622 *
623 * @param map the map
624 * @param key the key
625 * @return the stored pointer or \c NULL if either the key is not present
626 * in the map or the map is not storing pointers
627 * @see cxMapStorePointers()
628 * @see cxMapDetach()
629 */
630 __attribute__((__nonnull__, __warn_unused_result__))
631 static inline void *cxMapRemoveAndGet(
632 CxMap *map,
633 CxHashKey key
634 ) {
635 return map->cl->remove(map, key, !map->store_pointer);
636 }
638 /**
639 * Removes a key/value-pair from the map by using the key.
640 *
641 * This function can be used when the map is storing pointers,
642 * in order to retrieve the pointer from the map without invoking
643 * any destructor function. Sometimes you do not want the pointer
644 * to be returned - in that case (instead of suppressing the "unused
645 * result" warning) you can use cxMapDetach().
646 *
647 * If this map is not storing pointers, this function behaves like
648 * cxMapRemove() and returns \c NULL.
649 *
650 * @param map the map
651 * @param key the key
652 * @return the stored pointer or \c NULL if either the key is not present
653 * in the map or the map is not storing pointers
654 * @see cxMapStorePointers()
655 * @see cxMapDetach()
656 */
657 __attribute__((__nonnull__, __warn_unused_result__))
658 static inline void *cxMapRemoveAndGet(
659 CxMap *map,
660 cxstring key
661 ) {
662 return map->cl->remove(map, cx_hash_key_cxstr(key), !map->store_pointer);
663 }
665 /**
666 * Removes a key/value-pair from the map by using the key.
667 *
668 * This function can be used when the map is storing pointers,
669 * in order to retrieve the pointer from the map without invoking
670 * any destructor function. Sometimes you do not want the pointer
671 * to be returned - in that case (instead of suppressing the "unused
672 * result" warning) you can use cxMapDetach().
673 *
674 * If this map is not storing pointers, this function behaves like
675 * cxMapRemove() and returns \c NULL.
676 *
677 * @param map the map
678 * @param key the key
679 * @return the stored pointer or \c NULL if either the key is not present
680 * in the map or the map is not storing pointers
681 * @see cxMapStorePointers()
682 * @see cxMapDetach()
683 */
684 __attribute__((__nonnull__, __warn_unused_result__))
685 static inline void *cxMapRemoveAndGet(
686 CxMap *map,
687 cxmutstr key
688 ) {
689 return map->cl->remove(map, cx_hash_key_cxstr(key), !map->store_pointer);
690 }
692 /**
693 * Removes a key/value-pair from the map by using the key.
694 *
695 * This function can be used when the map is storing pointers,
696 * in order to retrieve the pointer from the map without invoking
697 * any destructor function. Sometimes you do not want the pointer
698 * to be returned - in that case (instead of suppressing the "unused
699 * result" warning) you can use cxMapDetach().
700 *
701 * If this map is not storing pointers, this function behaves like
702 * cxMapRemove() and returns \c NULL.
703 *
704 * @param map the map
705 * @param key the key
706 * @return the stored pointer or \c NULL if either the key is not present
707 * in the map or the map is not storing pointers
708 * @see cxMapStorePointers()
709 * @see cxMapDetach()
710 */
711 __attribute__((__nonnull__, __warn_unused_result__))
712 static inline void *cxMapRemoveAndGet(
713 CxMap *map,
714 char const *key
715 ) {
716 return map->cl->remove(map, cx_hash_key_str(key), !map->store_pointer);
717 }
719 #else // __cplusplus
721 /**
722 * Puts a key/value-pair into the map.
723 *
724 * @param map the map
725 * @param key the key
726 * @param value the value
727 * @return 0 on success, non-zero value on failure
728 */
729 __attribute__((__nonnull__))
730 static inline int cx_map_put(
731 CxMap *map,
732 CxHashKey key,
733 void *value
734 ) {
735 return map->cl->put(map, key, value);
736 }
738 /**
739 * Puts a key/value-pair into the map.
740 *
741 * @param map the map
742 * @param key the key
743 * @param value the value
744 * @return 0 on success, non-zero value on failure
745 */
746 __attribute__((__nonnull__))
747 static inline int cx_map_put_cxstr(
748 CxMap *map,
749 cxstring key,
750 void *value
751 ) {
752 return map->cl->put(map, cx_hash_key_cxstr(key), value);
753 }
755 /**
756 * Puts a key/value-pair into the map.
757 *
758 * @param map the map
759 * @param key the key
760 * @param value the value
761 * @return 0 on success, non-zero value on failure
762 */
763 __attribute__((__nonnull__))
764 static inline int cx_map_put_mustr(
765 CxMap *map,
766 cxmutstr key,
767 void *value
768 ) {
769 return map->cl->put(map, cx_hash_key_cxstr(key), value);
770 }
772 /**
773 * Puts a key/value-pair into the map.
774 *
775 * @param map the map
776 * @param key the key
777 * @param value the value
778 * @return 0 on success, non-zero value on failure
779 */
780 __attribute__((__nonnull__))
781 static inline int cx_map_put_str(
782 CxMap *map,
783 char const *key,
784 void *value
785 ) {
786 return map->cl->put(map, cx_hash_key_str(key), value);
787 }
789 /**
790 * Puts a key/value-pair into the map.
791 *
792 * @param map the map
793 * @param key the key
794 * @param value the value
795 * @return 0 on success, non-zero value on failure
796 */
797 #define cxMapPut(map, key, value) _Generic((key), \
798 CxHashKey: cx_map_put, \
799 cxstring: cx_map_put_cxstr, \
800 cxmutstr: cx_map_put_mustr, \
801 char*: cx_map_put_str, \
802 char const*: cx_map_put_str) \
803 (map, key, value)
805 /**
806 * Retrieves a value by using a key.
807 *
808 * @param map the map
809 * @param key the key
810 * @return the value
811 */
812 __attribute__((__nonnull__, __warn_unused_result__))
813 static inline void *cx_map_get(
814 CxMap const *map,
815 CxHashKey key
816 ) {
817 return map->cl->get(map, key);
818 }
820 /**
821 * Retrieves a value by using a key.
822 *
823 * @param map the map
824 * @param key the key
825 * @return the value
826 */
827 __attribute__((__nonnull__, __warn_unused_result__))
828 static inline void *cx_map_get_cxstr(
829 CxMap const *map,
830 cxstring key
831 ) {
832 return map->cl->get(map, cx_hash_key_cxstr(key));
833 }
835 /**
836 * Retrieves a value by using a key.
837 *
838 * @param map the map
839 * @param key the key
840 * @return the value
841 */
842 __attribute__((__nonnull__, __warn_unused_result__))
843 static inline void *cx_map_get_mustr(
844 CxMap const *map,
845 cxmutstr key
846 ) {
847 return map->cl->get(map, cx_hash_key_cxstr(key));
848 }
850 /**
851 * Retrieves a value by using a key.
852 *
853 * @param map the map
854 * @param key the key
855 * @return the value
856 */
857 __attribute__((__nonnull__, __warn_unused_result__))
858 static inline void *cx_map_get_str(
859 CxMap const *map,
860 char const *key
861 ) {
862 return map->cl->get(map, cx_hash_key_str(key));
863 }
865 /**
866 * Retrieves a value by using a key.
867 *
868 * @param map the map
869 * @param key the key
870 * @return the value
871 */
872 #define cxMapGet(map, key) _Generic((key), \
873 CxHashKey: cx_map_get, \
874 cxstring: cx_map_get_cxstr, \
875 cxmutstr: cx_map_get_mustr, \
876 char*: cx_map_get_str, \
877 char const*: cx_map_get_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 */
886 __attribute__((__nonnull__))
887 static inline void cx_map_remove(
888 CxMap *map,
889 CxHashKey key
890 ) {
891 (void) map->cl->remove(map, key, true);
892 }
894 /**
895 * Removes a key/value-pair from the map by using the key.
896 *
897 * @param map the map
898 * @param key the key
899 */
900 __attribute__((__nonnull__))
901 static inline void cx_map_remove_cxstr(
902 CxMap *map,
903 cxstring key
904 ) {
905 (void) map->cl->remove(map, cx_hash_key_cxstr(key), true);
906 }
908 /**
909 * Removes a key/value-pair from the map by using the key.
910 *
911 * @param map the map
912 * @param key the key
913 */
914 __attribute__((__nonnull__))
915 static inline void cx_map_remove_mustr(
916 CxMap *map,
917 cxmutstr key
918 ) {
919 (void) map->cl->remove(map, cx_hash_key_cxstr(key), true);
920 }
922 /**
923 * Removes a key/value-pair from the map by using the key.
924 *
925 * @param map the map
926 * @param key the key
927 */
928 __attribute__((__nonnull__))
929 static inline void cx_map_remove_str(
930 CxMap *map,
931 char const *key
932 ) {
933 (void) map->cl->remove(map, cx_hash_key_str(key), true);
934 }
936 /**
937 * Removes a key/value-pair from the map by using the key.
938 *
939 * Always invokes the destructor function, if any, on the removed element.
940 * If this map is storing pointers and you just want to retrieve the pointer
941 * without invoking the destructor, use cxMapRemoveAndGet().
942 * If you just want to detach the element from the map without invoking the
943 * destructor or returning the element, use cxMapDetach().
944 *
945 * @param map the map
946 * @param key the key
947 * @see cxMapRemoveAndGet()
948 * @see cxMapDetach()
949 */
950 #define cxMapRemove(map, key) _Generic((key), \
951 CxHashKey: cx_map_remove, \
952 cxstring: cx_map_remove_cxstr, \
953 cxmutstr: cx_map_remove_mustr, \
954 char*: cx_map_remove_str, \
955 char const*: cx_map_remove_str) \
956 (map, key)
958 /**
959 * Detaches a key/value-pair from the map by using the key
960 * without invoking the destructor.
961 *
962 * @param map the map
963 * @param key the key
964 */
965 __attribute__((__nonnull__))
966 static inline void cx_map_detach(
967 CxMap *map,
968 CxHashKey key
969 ) {
970 (void) map->cl->remove(map, key, false);
971 }
973 /**
974 * Detaches a key/value-pair from the map by using the key
975 * without invoking the destructor.
976 *
977 * @param map the map
978 * @param key the key
979 */
980 __attribute__((__nonnull__))
981 static inline void cx_map_detach_cxstr(
982 CxMap *map,
983 cxstring key
984 ) {
985 (void) map->cl->remove(map, cx_hash_key_cxstr(key), false);
986 }
988 /**
989 * Detaches a key/value-pair from the map by using the key
990 * without invoking the destructor.
991 *
992 * @param map the map
993 * @param key the key
994 */
995 __attribute__((__nonnull__))
996 static inline void cx_map_detach_mustr(
997 CxMap *map,
998 cxmutstr key
999 ) {
1000 (void) map->cl->remove(map, cx_hash_key_cxstr(key), false);
1001 }
1003 /**
1004 * Detaches a key/value-pair from the map by using the key
1005 * without invoking the destructor.
1006 *
1007 * @param map the map
1008 * @param key the key
1009 */
1010 __attribute__((__nonnull__))
1011 static inline void cx_map_detach_str(
1012 CxMap *map,
1013 char const *key
1014 ) {
1015 (void) map->cl->remove(map, cx_hash_key_str(key), false);
1016 }
1018 /**
1019 * Detaches a key/value-pair from the map by using the key
1020 * without invoking the destructor.
1021 *
1022 * In general, you should only use this function if the map does not own
1023 * the data and there is a valid reference to the data somewhere else
1024 * in the program. In all other cases it is preferable to use
1025 * cxMapRemove() or cxMapRemoveAndGet().
1026 *
1027 * @param map the map
1028 * @param key the key
1029 * @see cxMapRemove()
1030 * @see cxMapRemoveAndGet()
1031 */
1032 #define cxMapDetach(map, key) _Generic((key), \
1033 CxHashKey: cx_map_detach, \
1034 cxstring: cx_map_detach_cxstr, \
1035 cxmutstr: cx_map_detach_mustr, \
1036 char*: cx_map_detach_str, \
1037 char const*: cx_map_detach_str) \
1038 (map, key)
1040 /**
1041 * Removes a key/value-pair from the map by using the key.
1042 *
1043 * @param map the map
1044 * @param key the key
1045 * @return the stored pointer or \c NULL if either the key is not present
1046 * in the map or the map is not storing pointers
1047 */
1048 __attribute__((__nonnull__, __warn_unused_result__))
1049 static inline void *cx_map_remove_and_get(
1050 CxMap *map,
1051 CxHashKey key
1052 ) {
1053 return map->cl->remove(map, key, !map->store_pointer);
1054 }
1056 /**
1057 * Removes a key/value-pair from the map by using the key.
1058 *
1059 * @param map the map
1060 * @param key the key
1061 * @return the stored pointer or \c NULL if either the key is not present
1062 * in the map or the map is not storing pointers
1063 */
1064 __attribute__((__nonnull__, __warn_unused_result__))
1065 static inline void *cx_map_remove_and_get_cxstr(
1066 CxMap *map,
1067 cxstring key
1068 ) {
1069 return map->cl->remove(map, cx_hash_key_cxstr(key), !map->store_pointer);
1070 }
1072 /**
1073 * Removes a key/value-pair from the map by using the key.
1074 *
1075 * @param map the map
1076 * @param key the key
1077 * @return the stored pointer or \c NULL if either the key is not present
1078 * in the map or the map is not storing pointers
1079 */
1080 __attribute__((__nonnull__, __warn_unused_result__))
1081 static inline void *cx_map_remove_and_get_mustr(
1082 CxMap *map,
1083 cxmutstr key
1084 ) {
1085 return map->cl->remove(map, cx_hash_key_cxstr(key), !map->store_pointer);
1086 }
1088 /**
1089 * Removes a key/value-pair from the map by using the key.
1090 *
1091 * @param map the map
1092 * @param key the key
1093 * @return the stored pointer or \c NULL if either the key is not present
1094 * in the map or the map is not storing pointers
1095 */
1096 __attribute__((__nonnull__, __warn_unused_result__))
1097 static inline void *cx_map_remove_and_get_str(
1098 CxMap *map,
1099 char const *key
1100 ) {
1101 return map->cl->remove(map, cx_hash_key_str(key), !map->store_pointer);
1102 }
1104 /**
1105 * Removes a key/value-pair from the map by using the key.
1106 *
1107 * This function can be used when the map is storing pointers,
1108 * in order to retrieve the pointer from the map without invoking
1109 * any destructor function. Sometimes you do not want the pointer
1110 * to be returned - in that case (instead of suppressing the "unused
1111 * result" warning) you can use cxMapDetach().
1112 *
1113 * If this map is not storing pointers, this function behaves like
1114 * cxMapRemove() and returns \c NULL.
1115 *
1116 * @param map the map
1117 * @param key the key
1118 * @return the stored pointer or \c NULL if either the key is not present
1119 * in the map or the map is not storing pointers
1120 * @see cxMapStorePointers()
1121 * @see cxMapDetach()
1122 */
1123 #define cxMapRemoveAndGet(map, key) _Generic((key), \
1124 CxHashKey: cx_map_remove_and_get, \
1125 cxstring: cx_map_remove_and_get_cxstr, \
1126 cxmutstr: cx_map_remove_and_get_mustr, \
1127 char*: cx_map_remove_and_get_str, \
1128 char const*: cx_map_remove_and_get_str) \
1129 (map, key)
1131 #endif // __cplusplus
1133 #endif // UCX_MAP_H