Fri, 21 Apr 2023 20:17:09 +0200
add cxmutstr to the map generics
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 cxmutstr const &key,
365 void *value
366 ) {
367 return map->cl->put(map, cx_hash_key_cxstr(key), value);
368 }
370 /**
371 * Puts a key/value-pair into the map.
372 *
373 * @param map the map
374 * @param key the key
375 * @param value the value
376 * @return 0 on success, non-zero value on failure
377 */
378 __attribute__((__nonnull__))
379 static inline int cxMapPut(
380 CxMap *map,
381 char const *key,
382 void *value
383 ) {
384 return map->cl->put(map, cx_hash_key_str(key), value);
385 }
387 /**
388 * Retrieves a value by using a key.
389 *
390 * @param map the map
391 * @param key the key
392 * @return the value
393 */
394 __attribute__((__nonnull__, __warn_unused_result__))
395 static inline void *cxMapGet(
396 CxMap const *map,
397 CxHashKey const &key
398 ) {
399 return map->cl->get(map, key);
400 }
402 /**
403 * Retrieves a value by using a key.
404 *
405 * @param map the map
406 * @param key the key
407 * @return the value
408 */
409 __attribute__((__nonnull__, __warn_unused_result__))
410 static inline void *cxMapGet(
411 CxMap const *map,
412 cxstring const &key
413 ) {
414 return map->cl->get(map, cx_hash_key_cxstr(key));
415 }
417 /**
418 * Retrieves a value by using a key.
419 *
420 * @param map the map
421 * @param key the key
422 * @return the value
423 */
424 __attribute__((__nonnull__, __warn_unused_result__))
425 static inline void *cxMapGet(
426 CxMap const *map,
427 cxmutstr const &key
428 ) {
429 return map->cl->get(map, cx_hash_key_cxstr(key));
430 }
432 /**
433 * Retrieves a value by using a key.
434 *
435 * @param map the map
436 * @param key the key
437 * @return the value
438 */
439 __attribute__((__nonnull__, __warn_unused_result__))
440 static inline void *cxMapGet(
441 CxMap const *map,
442 char const *key
443 ) {
444 return map->cl->get(map, cx_hash_key_str(key));
445 }
447 /**
448 * Removes a key/value-pair from the map by using the key.
449 *
450 * Always invokes the destructor function, if any, on the removed element.
451 * If this map is storing pointers and you just want to retrieve the pointer
452 * without invoking the destructor, use cxMapRemoveAndGet().
453 * If you just want to detach the element from the map without invoking the
454 * destructor or returning the element, use cxMapDetach().
455 *
456 * @param map the map
457 * @param key the key
458 * @see cxMapRemoveAndGet()
459 * @see cxMapDetach()
460 */
461 __attribute__((__nonnull__))
462 static inline void cxMapRemove(
463 CxMap *map,
464 CxHashKey const &key
465 ) {
466 (void) map->cl->remove(map, key, true);
467 }
469 /**
470 * Removes a key/value-pair from the map by using the key.
471 *
472 * Always invokes the destructor function, if any, on the removed element.
473 * If this map is storing pointers and you just want to retrieve the pointer
474 * without invoking the destructor, use cxMapRemoveAndGet().
475 * If you just want to detach the element from the map without invoking the
476 * destructor or returning the element, use cxMapDetach().
477 *
478 * @param map the map
479 * @param key the key
480 * @see cxMapRemoveAndGet()
481 * @see cxMapDetach()
482 */
483 __attribute__((__nonnull__))
484 static inline void cxMapRemove(
485 CxMap *map,
486 cxstring const &key
487 ) {
488 (void) map->cl->remove(map, cx_hash_key_cxstr(key), true);
489 }
491 /**
492 * Removes a key/value-pair from the map by using the key.
493 *
494 * Always invokes the destructor function, if any, on the removed element.
495 * If this map is storing pointers and you just want to retrieve the pointer
496 * without invoking the destructor, use cxMapRemoveAndGet().
497 * If you just want to detach the element from the map without invoking the
498 * destructor or returning the element, use cxMapDetach().
499 *
500 * @param map the map
501 * @param key the key
502 * @see cxMapRemoveAndGet()
503 * @see cxMapDetach()
504 */
505 __attribute__((__nonnull__))
506 static inline void cxMapRemove(
507 CxMap *map,
508 cxmutstr const &key
509 ) {
510 (void) map->cl->remove(map, cx_hash_key_cxstr(key), true);
511 }
513 /**
514 * Removes a key/value-pair from the map by using the key.
515 *
516 * Always invokes the destructor function, if any, on the removed element.
517 * If this map is storing pointers and you just want to retrieve the pointer
518 * without invoking the destructor, use cxMapRemoveAndGet().
519 * If you just want to detach the element from the map without invoking the
520 * destructor or returning the element, use cxMapDetach().
521 *
522 * @param map the map
523 * @param key the key
524 * @see cxMapRemoveAndGet()
525 * @see cxMapDetach()
526 */
527 __attribute__((__nonnull__))
528 static inline void cxMapRemove(
529 CxMap *map,
530 char const *key
531 ) {
532 (void) map->cl->remove(map, cx_hash_key_str(key), true);
533 }
535 /**
536 * Detaches a key/value-pair from the map by using the key
537 * without invoking the destructor.
538 *
539 * In general, you should only use this function if the map does not own
540 * the data and there is a valid reference to the data somewhere else
541 * in the program. In all other cases it is preferable to use
542 * cxMapRemove() or cxMapRemoveAndGet().
543 *
544 * @param map the map
545 * @param key the key
546 * @see cxMapRemove()
547 * @see cxMapRemoveAndGet()
548 */
549 __attribute__((__nonnull__))
550 static inline void cxMapDetach(
551 CxMap *map,
552 CxHashKey const &key
553 ) {
554 (void) map->cl->remove(map, key, false);
555 }
557 /**
558 * Detaches a key/value-pair from the map by using the key
559 * without invoking the destructor.
560 *
561 * In general, you should only use this function if the map does not own
562 * the data and there is a valid reference to the data somewhere else
563 * in the program. In all other cases it is preferable to use
564 * cxMapRemove() or cxMapRemoveAndGet().
565 *
566 * @param map the map
567 * @param key the key
568 * @see cxMapRemove()
569 * @see cxMapRemoveAndGet()
570 */
571 __attribute__((__nonnull__))
572 static inline void cxMapDetach(
573 CxMap *map,
574 cxstring const &key
575 ) {
576 (void) map->cl->remove(map, cx_hash_key_cxstr(key), false);
577 }
579 /**
580 * Detaches a key/value-pair from the map by using the key
581 * without invoking the destructor.
582 *
583 * In general, you should only use this function if the map does not own
584 * the data and there is a valid reference to the data somewhere else
585 * in the program. In all other cases it is preferable to use
586 * cxMapRemove() or cxMapRemoveAndGet().
587 *
588 * @param map the map
589 * @param key the key
590 * @see cxMapRemove()
591 * @see cxMapRemoveAndGet()
592 */
593 __attribute__((__nonnull__))
594 static inline void cxMapDetach(
595 CxMap *map,
596 cxmutstr const &key
597 ) {
598 (void) map->cl->remove(map, cx_hash_key_cxstr(key), false);
599 }
601 /**
602 * Detaches a key/value-pair from the map by using the key
603 * without invoking the destructor.
604 *
605 * In general, you should only use this function if the map does not own
606 * the data and there is a valid reference to the data somewhere else
607 * in the program. In all other cases it is preferable to use
608 * cxMapRemove() or cxMapRemoveAndGet().
609 *
610 * @param map the map
611 * @param key the key
612 * @see cxMapRemove()
613 * @see cxMapRemoveAndGet()
614 */
615 __attribute__((__nonnull__))
616 static inline void cxMapDetach(
617 CxMap *map,
618 char const *key
619 ) {
620 (void) map->cl->remove(map, cx_hash_key_str(key), false);
621 }
623 /**
624 * Removes a key/value-pair from the map by using the key.
625 *
626 * This function can be used when the map is storing pointers,
627 * in order to retrieve the pointer from the map without invoking
628 * any destructor function. Sometimes you do not want the pointer
629 * to be returned - in that case (instead of suppressing the "unused
630 * result" warning) you can use cxMapDetach().
631 *
632 * If this map is not storing pointers, this function behaves like
633 * cxMapRemove() and returns \c NULL.
634 *
635 * @param map the map
636 * @param key the key
637 * @return the stored pointer or \c NULL if either the key is not present
638 * in the map or the map is not storing pointers
639 * @see cxMapStorePointers()
640 * @see cxMapDetach()
641 */
642 __attribute__((__nonnull__, __warn_unused_result__))
643 static inline void *cxMapRemoveAndGet(
644 CxMap *map,
645 CxHashKey key
646 ) {
647 return map->cl->remove(map, key, !map->store_pointer);
648 }
650 /**
651 * Removes a key/value-pair from the map by using the key.
652 *
653 * This function can be used when the map is storing pointers,
654 * in order to retrieve the pointer from the map without invoking
655 * any destructor function. Sometimes you do not want the pointer
656 * to be returned - in that case (instead of suppressing the "unused
657 * result" warning) you can use cxMapDetach().
658 *
659 * If this map is not storing pointers, this function behaves like
660 * cxMapRemove() and returns \c NULL.
661 *
662 * @param map the map
663 * @param key the key
664 * @return the stored pointer or \c NULL if either the key is not present
665 * in the map or the map is not storing pointers
666 * @see cxMapStorePointers()
667 * @see cxMapDetach()
668 */
669 __attribute__((__nonnull__, __warn_unused_result__))
670 static inline void *cxMapRemoveAndGet(
671 CxMap *map,
672 cxstring key
673 ) {
674 return map->cl->remove(map, cx_hash_key_cxstr(key), !map->store_pointer);
675 }
677 /**
678 * Removes a key/value-pair from the map by using the key.
679 *
680 * This function can be used when the map is storing pointers,
681 * in order to retrieve the pointer from the map without invoking
682 * any destructor function. Sometimes you do not want the pointer
683 * to be returned - in that case (instead of suppressing the "unused
684 * result" warning) you can use cxMapDetach().
685 *
686 * If this map is not storing pointers, this function behaves like
687 * cxMapRemove() and returns \c NULL.
688 *
689 * @param map the map
690 * @param key the key
691 * @return the stored pointer or \c NULL if either the key is not present
692 * in the map or the map is not storing pointers
693 * @see cxMapStorePointers()
694 * @see cxMapDetach()
695 */
696 __attribute__((__nonnull__, __warn_unused_result__))
697 static inline void *cxMapRemoveAndGet(
698 CxMap *map,
699 cxmutstr key
700 ) {
701 return map->cl->remove(map, cx_hash_key_cxstr(key), !map->store_pointer);
702 }
704 /**
705 * Removes a key/value-pair from the map by using the key.
706 *
707 * This function can be used when the map is storing pointers,
708 * in order to retrieve the pointer from the map without invoking
709 * any destructor function. Sometimes you do not want the pointer
710 * to be returned - in that case (instead of suppressing the "unused
711 * result" warning) you can use cxMapDetach().
712 *
713 * If this map is not storing pointers, this function behaves like
714 * cxMapRemove() and returns \c NULL.
715 *
716 * @param map the map
717 * @param key the key
718 * @return the stored pointer or \c NULL if either the key is not present
719 * in the map or the map is not storing pointers
720 * @see cxMapStorePointers()
721 * @see cxMapDetach()
722 */
723 __attribute__((__nonnull__, __warn_unused_result__))
724 static inline void *cxMapRemoveAndGet(
725 CxMap *map,
726 char const *key
727 ) {
728 return map->cl->remove(map, cx_hash_key_str(key), !map->store_pointer);
729 }
731 #else // __cplusplus
733 /**
734 * Puts a key/value-pair into the map.
735 *
736 * @param map the map
737 * @param key the key
738 * @param value the value
739 * @return 0 on success, non-zero value on failure
740 */
741 __attribute__((__nonnull__))
742 static inline int cx_map_put(
743 CxMap *map,
744 CxHashKey key,
745 void *value
746 ) {
747 return map->cl->put(map, key, value);
748 }
750 /**
751 * Puts a key/value-pair into the map.
752 *
753 * @param map the map
754 * @param key the key
755 * @param value the value
756 * @return 0 on success, non-zero value on failure
757 */
758 __attribute__((__nonnull__))
759 static inline int cx_map_put_cxstr(
760 CxMap *map,
761 cxstring key,
762 void *value
763 ) {
764 return map->cl->put(map, cx_hash_key_cxstr(key), value);
765 }
767 /**
768 * Puts a key/value-pair into the map.
769 *
770 * @param map the map
771 * @param key the key
772 * @param value the value
773 * @return 0 on success, non-zero value on failure
774 */
775 __attribute__((__nonnull__))
776 static inline int cx_map_put_mustr(
777 CxMap *map,
778 cxmutstr key,
779 void *value
780 ) {
781 return map->cl->put(map, cx_hash_key_cxstr(key), value);
782 }
784 /**
785 * Puts a key/value-pair into the map.
786 *
787 * @param map the map
788 * @param key the key
789 * @param value the value
790 * @return 0 on success, non-zero value on failure
791 */
792 __attribute__((__nonnull__))
793 static inline int cx_map_put_str(
794 CxMap *map,
795 char const *key,
796 void *value
797 ) {
798 return map->cl->put(map, cx_hash_key_str(key), value);
799 }
801 /**
802 * Puts a key/value-pair into the map.
803 *
804 * @param map the map
805 * @param key the key
806 * @param value the value
807 * @return 0 on success, non-zero value on failure
808 */
809 #define cxMapPut(map, key, value) _Generic((key), \
810 CxHashKey: cx_map_put, \
811 cxstring: cx_map_put_cxstr, \
812 cxmutstr: cx_map_put_mustr, \
813 char*: cx_map_put_str) \
814 (map, key, value)
816 /**
817 * Retrieves a value by using a key.
818 *
819 * @param map the map
820 * @param key the key
821 * @return the value
822 */
823 __attribute__((__nonnull__, __warn_unused_result__))
824 static inline void *cx_map_get(
825 CxMap const *map,
826 CxHashKey key
827 ) {
828 return map->cl->get(map, key);
829 }
831 /**
832 * Retrieves a value by using a key.
833 *
834 * @param map the map
835 * @param key the key
836 * @return the value
837 */
838 __attribute__((__nonnull__, __warn_unused_result__))
839 static inline void *cx_map_get_cxstr(
840 CxMap const *map,
841 cxstring key
842 ) {
843 return map->cl->get(map, cx_hash_key_cxstr(key));
844 }
846 /**
847 * Retrieves a value by using a key.
848 *
849 * @param map the map
850 * @param key the key
851 * @return the value
852 */
853 __attribute__((__nonnull__, __warn_unused_result__))
854 static inline void *cx_map_get_mustr(
855 CxMap const *map,
856 cxmutstr key
857 ) {
858 return map->cl->get(map, cx_hash_key_cxstr(key));
859 }
861 /**
862 * Retrieves a value by using a key.
863 *
864 * @param map the map
865 * @param key the key
866 * @return the value
867 */
868 __attribute__((__nonnull__, __warn_unused_result__))
869 static inline void *cx_map_get_str(
870 CxMap const *map,
871 char const *key
872 ) {
873 return map->cl->get(map, cx_hash_key_str(key));
874 }
876 /**
877 * Retrieves a value by using a key.
878 *
879 * @param map the map
880 * @param key the key
881 * @return the value
882 */
883 #define cxMapGet(map, key) _Generic((key), \
884 CxHashKey: cx_map_get, \
885 cxstring: cx_map_get_cxstr, \
886 cxmutstr: cx_map_get_mustr, \
887 char*: cx_map_get_str) \
888 (map, key)
890 /**
891 * Removes a key/value-pair from the map by using the key.
892 *
893 * @param map the map
894 * @param key the key
895 */
896 __attribute__((__nonnull__))
897 static inline void cx_map_remove(
898 CxMap *map,
899 CxHashKey key
900 ) {
901 (void) map->cl->remove(map, key, true);
902 }
904 /**
905 * Removes a key/value-pair from the map by using the key.
906 *
907 * @param map the map
908 * @param key the key
909 */
910 __attribute__((__nonnull__))
911 static inline void cx_map_remove_cxstr(
912 CxMap *map,
913 cxstring key
914 ) {
915 (void) map->cl->remove(map, cx_hash_key_cxstr(key), true);
916 }
918 /**
919 * Removes a key/value-pair from the map by using the key.
920 *
921 * @param map the map
922 * @param key the key
923 */
924 __attribute__((__nonnull__))
925 static inline void cx_map_remove_mustr(
926 CxMap *map,
927 cxmutstr key
928 ) {
929 (void) map->cl->remove(map, cx_hash_key_cxstr(key), true);
930 }
932 /**
933 * Removes a key/value-pair from the map by using the key.
934 *
935 * @param map the map
936 * @param key the key
937 */
938 __attribute__((__nonnull__))
939 static inline void cx_map_remove_str(
940 CxMap *map,
941 char const *key
942 ) {
943 (void) map->cl->remove(map, cx_hash_key_str(key), true);
944 }
946 /**
947 * Removes a key/value-pair from the map by using the key.
948 *
949 * Always invokes the destructor function, if any, on the removed element.
950 * If this map is storing pointers and you just want to retrieve the pointer
951 * without invoking the destructor, use cxMapRemoveAndGet().
952 * If you just want to detach the element from the map without invoking the
953 * destructor or returning the element, use cxMapDetach().
954 *
955 * @param map the map
956 * @param key the key
957 * @see cxMapRemoveAndGet()
958 * @see cxMapDetach()
959 */
960 #define cxMapRemove(map, key) _Generic((key), \
961 CxHashKey: cx_map_remove, \
962 cxstring: cx_map_remove_cxstr, \
963 cxmutstr: cx_map_remove_mustr, \
964 char*: cx_map_remove_str) \
965 (map, key)
967 /**
968 * Detaches a key/value-pair from the map by using the key
969 * without invoking the destructor.
970 *
971 * @param map the map
972 * @param key the key
973 */
974 __attribute__((__nonnull__))
975 static inline void cx_map_detach(
976 CxMap *map,
977 CxHashKey key
978 ) {
979 (void) map->cl->remove(map, key, false);
980 }
982 /**
983 * Detaches a key/value-pair from the map by using the key
984 * without invoking the destructor.
985 *
986 * @param map the map
987 * @param key the key
988 */
989 __attribute__((__nonnull__))
990 static inline void cx_map_detach_cxstr(
991 CxMap *map,
992 cxstring key
993 ) {
994 (void) map->cl->remove(map, cx_hash_key_cxstr(key), false);
995 }
997 /**
998 * Detaches a key/value-pair from the map by using the key
999 * without invoking the destructor.
1000 *
1001 * @param map the map
1002 * @param key the key
1003 */
1004 __attribute__((__nonnull__))
1005 static inline void cx_map_detach_mustr(
1006 CxMap *map,
1007 cxmutstr key
1008 ) {
1009 (void) map->cl->remove(map, cx_hash_key_cxstr(key), false);
1010 }
1012 /**
1013 * Detaches a key/value-pair from the map by using the key
1014 * without invoking the destructor.
1015 *
1016 * @param map the map
1017 * @param key the key
1018 */
1019 __attribute__((__nonnull__))
1020 static inline void cx_map_detach_str(
1021 CxMap *map,
1022 char const *key
1023 ) {
1024 (void) map->cl->remove(map, cx_hash_key_str(key), false);
1025 }
1027 /**
1028 * Detaches a key/value-pair from the map by using the key
1029 * without invoking the destructor.
1030 *
1031 * In general, you should only use this function if the map does not own
1032 * the data and there is a valid reference to the data somewhere else
1033 * in the program. In all other cases it is preferable to use
1034 * cxMapRemove() or cxMapRemoveAndGet().
1035 *
1036 * @param map the map
1037 * @param key the key
1038 * @see cxMapRemove()
1039 * @see cxMapRemoveAndGet()
1040 */
1041 #define cxMapDetach(map, key) _Generic((key), \
1042 CxHashKey: cx_map_detach, \
1043 cxstring: cx_map_detach_cxstr, \
1044 cxmutstr: cx_map_detach_mustr, \
1045 char*: cx_map_detach_str) \
1046 (map, key)
1048 /**
1049 * Removes a key/value-pair from the map by using the key.
1050 *
1051 * @param map the map
1052 * @param key the key
1053 * @return the stored pointer or \c NULL if either the key is not present
1054 * in the map or the map is not storing pointers
1055 */
1056 __attribute__((__nonnull__, __warn_unused_result__))
1057 static inline void *cx_map_remove_and_get(
1058 CxMap *map,
1059 CxHashKey key
1060 ) {
1061 return map->cl->remove(map, key, !map->store_pointer);
1062 }
1064 /**
1065 * Removes a key/value-pair from the map by using the key.
1066 *
1067 * @param map the map
1068 * @param key the key
1069 * @return the stored pointer or \c NULL if either the key is not present
1070 * in the map or the map is not storing pointers
1071 */
1072 __attribute__((__nonnull__, __warn_unused_result__))
1073 static inline void *cx_map_remove_and_get_cxstr(
1074 CxMap *map,
1075 cxstring key
1076 ) {
1077 return map->cl->remove(map, cx_hash_key_cxstr(key), !map->store_pointer);
1078 }
1080 /**
1081 * Removes a key/value-pair from the map by using the key.
1082 *
1083 * @param map the map
1084 * @param key the key
1085 * @return the stored pointer or \c NULL if either the key is not present
1086 * in the map or the map is not storing pointers
1087 */
1088 __attribute__((__nonnull__, __warn_unused_result__))
1089 static inline void *cx_map_remove_and_get_mustr(
1090 CxMap *map,
1091 cxmutstr key
1092 ) {
1093 return map->cl->remove(map, cx_hash_key_cxstr(key), !map->store_pointer);
1094 }
1096 /**
1097 * Removes a key/value-pair from the map by using the key.
1098 *
1099 * @param map the map
1100 * @param key the key
1101 * @return the stored pointer or \c NULL if either the key is not present
1102 * in the map or the map is not storing pointers
1103 */
1104 __attribute__((__nonnull__, __warn_unused_result__))
1105 static inline void *cx_map_remove_and_get_str(
1106 CxMap *map,
1107 char const *key
1108 ) {
1109 return map->cl->remove(map, cx_hash_key_str(key), !map->store_pointer);
1110 }
1112 /**
1113 * Removes a key/value-pair from the map by using the key.
1114 *
1115 * This function can be used when the map is storing pointers,
1116 * in order to retrieve the pointer from the map without invoking
1117 * any destructor function. Sometimes you do not want the pointer
1118 * to be returned - in that case (instead of suppressing the "unused
1119 * result" warning) you can use cxMapDetach().
1120 *
1121 * If this map is not storing pointers, this function behaves like
1122 * cxMapRemove() and returns \c NULL.
1123 *
1124 * @param map the map
1125 * @param key the key
1126 * @return the stored pointer or \c NULL if either the key is not present
1127 * in the map or the map is not storing pointers
1128 * @see cxMapStorePointers()
1129 * @see cxMapDetach()
1130 */
1131 #define cxMapRemoveAndGet(map, key) _Generic((key), \
1132 CxHashKey: cx_map_remove_and_get, \
1133 cxstring: cx_map_remove_and_get_cxstr, \
1134 cxmutstr: cx_map_remove_and_get_mustr, \
1135 char*: cx_map_remove_and_get_str) \
1136 (map, key)
1138 #endif // __cplusplus
1140 #endif // UCX_MAP_H