Sun, 21 May 2023 14:37:56 +0200
add empty map implementation - fixes #259
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 extern CxMap *const cxEmptyMap;
163 /**
164 * Advises the map to store copies of the objects (default mode of operation).
165 *
166 * Retrieving objects from this map will yield pointers to the copies stored
167 * within this list.
168 *
169 * @param map the map
170 * @see cxMapStorePointers()
171 */
172 __attribute__((__nonnull__))
173 static inline void cxMapStoreObjects(CxMap *map) {
174 map->store_pointer = false;
175 }
177 /**
178 * Advises the map to only store pointers to the objects.
179 *
180 * Retrieving objects from this list will yield the original pointers stored.
181 *
182 * @note This function forcibly sets the element size to the size of a pointer.
183 * Invoking this function on a non-empty map that already stores copies of
184 * objects is undefined.
185 *
186 * @param map the map
187 * @see cxMapStoreObjects()
188 */
189 __attribute__((__nonnull__))
190 static inline void cxMapStorePointers(CxMap *map) {
191 map->store_pointer = true;
192 map->item_size = sizeof(void *);
193 }
196 /**
197 * Deallocates the memory of the specified map.
198 *
199 * @param map the map to be destroyed
200 */
201 __attribute__((__nonnull__))
202 static inline void cxMapDestroy(CxMap *map) {
203 map->cl->destructor(map);
204 }
207 /**
208 * Clears a map by removing all elements.
209 *
210 * @param map the map to be cleared
211 */
212 __attribute__((__nonnull__))
213 static inline void cxMapClear(CxMap *map) {
214 map->cl->clear(map);
215 }
218 // TODO: set-like map operations (union, intersect, difference)
220 /**
221 * Creates a value iterator for a map.
222 *
223 * \note An iterator iterates over all elements successively. Therefore the order
224 * highly depends on the map implementation and may change arbitrarily when the contents change.
225 *
226 * @param map the map to create the iterator for
227 * @return an iterator for the currently stored values
228 */
229 __attribute__((__nonnull__, __warn_unused_result__))
230 static inline CxIterator cxMapIteratorValues(CxMap *map) {
231 return map->cl->iterator_values(map);
232 }
234 /**
235 * Creates a key iterator for a map.
236 *
237 * The elements of the iterator are keys of type CxHashKey.
238 *
239 * \note An iterator iterates over all elements successively. Therefore the order
240 * highly depends on the map implementation and may change arbitrarily when the contents change.
241 *
242 * @param map the map to create the iterator for
243 * @return an iterator for the currently stored keys
244 */
245 __attribute__((__nonnull__, __warn_unused_result__))
246 static inline CxIterator cxMapIteratorKeys(CxMap *map) {
247 return map->cl->iterator_keys(map);
248 }
250 /**
251 * Creates an iterator for a map.
252 *
253 * The elements of the iterator are key/value pairs of type CxMapEntry.
254 *
255 * \note An iterator iterates over all elements successively. Therefore the order
256 * highly depends on the map implementation and may change arbitrarily when the contents change.
257 *
258 * @param map the map to create the iterator for
259 * @return an iterator for the currently stored entries
260 * @see cxMapIteratorKeys()
261 * @see cxMapIteratorValues()
262 */
263 __attribute__((__nonnull__, __warn_unused_result__))
264 static inline CxIterator cxMapIterator(CxMap *map) {
265 return map->cl->iterator(map);
266 }
269 /**
270 * Creates a mutating iterator over the values of a map.
271 *
272 * \note An iterator iterates over all elements successively. Therefore the order
273 * highly depends on the map implementation and may change arbitrarily when the contents change.
274 *
275 * @param map the map to create the iterator for
276 * @return an iterator for the currently stored values
277 */
278 __attribute__((__nonnull__, __warn_unused_result__))
279 static inline CxMutIterator cxMapMutIteratorValues(CxMap *map) {
280 return map->cl->mut_iterator_values(map);
281 }
283 /**
284 * Creates a mutating iterator over the keys of a map.
285 *
286 * The elements of the iterator are keys of type CxHashKey.
287 *
288 * \note An iterator iterates over all elements successively. Therefore the order
289 * highly depends on the map implementation and may change arbitrarily when the contents change.
290 *
291 * @param map the map to create the iterator for
292 * @return an iterator for the currently stored keys
293 */
294 __attribute__((__nonnull__, __warn_unused_result__))
295 static inline CxMutIterator cxMapMutIteratorKeys(CxMap *map) {
296 return map->cl->mut_iterator_keys(map);
297 }
299 /**
300 * Creates a mutating iterator for a map.
301 *
302 * The elements of the iterator are key/value pairs of type CxMapEntry.
303 *
304 * \note An iterator iterates over all elements successively. Therefore the order
305 * highly depends on the map implementation and may change arbitrarily when the contents change.
306 *
307 * @param map the map to create the iterator for
308 * @return an iterator for the currently stored entries
309 * @see cxMapMutIteratorKeys()
310 * @see cxMapMutIteratorValues()
311 */
312 __attribute__((__nonnull__, __warn_unused_result__))
313 static inline CxMutIterator cxMapMutIterator(CxMap *map) {
314 return map->cl->mut_iterator(map);
315 }
317 #ifdef __cplusplus
318 } // end the extern "C" block here, because we want to start overloading
320 /**
321 * Puts a key/value-pair into the map.
322 *
323 * @param map the map
324 * @param key the key
325 * @param value the value
326 * @return 0 on success, non-zero value on failure
327 */
328 __attribute__((__nonnull__))
329 static inline int cxMapPut(
330 CxMap *map,
331 CxHashKey const &key,
332 void *value
333 ) {
334 return map->cl->put(map, key, value);
335 }
338 /**
339 * Puts a key/value-pair into the map.
340 *
341 * @param map the map
342 * @param key the key
343 * @param value the value
344 * @return 0 on success, non-zero value on failure
345 */
346 __attribute__((__nonnull__))
347 static inline int cxMapPut(
348 CxMap *map,
349 cxstring const &key,
350 void *value
351 ) {
352 return map->cl->put(map, cx_hash_key_cxstr(key), value);
353 }
355 /**
356 * Puts a key/value-pair into the map.
357 *
358 * @param map the map
359 * @param key the key
360 * @param value the value
361 * @return 0 on success, non-zero value on failure
362 */
363 __attribute__((__nonnull__))
364 static inline int cxMapPut(
365 CxMap *map,
366 cxmutstr const &key,
367 void *value
368 ) {
369 return map->cl->put(map, cx_hash_key_cxstr(key), value);
370 }
372 /**
373 * Puts a key/value-pair into the map.
374 *
375 * @param map the map
376 * @param key the key
377 * @param value the value
378 * @return 0 on success, non-zero value on failure
379 */
380 __attribute__((__nonnull__))
381 static inline int cxMapPut(
382 CxMap *map,
383 char const *key,
384 void *value
385 ) {
386 return map->cl->put(map, cx_hash_key_str(key), value);
387 }
389 /**
390 * Retrieves a value by using a key.
391 *
392 * @param map the map
393 * @param key the key
394 * @return the value
395 */
396 __attribute__((__nonnull__, __warn_unused_result__))
397 static inline void *cxMapGet(
398 CxMap const *map,
399 CxHashKey const &key
400 ) {
401 return map->cl->get(map, key);
402 }
404 /**
405 * Retrieves a value by using a key.
406 *
407 * @param map the map
408 * @param key the key
409 * @return the value
410 */
411 __attribute__((__nonnull__, __warn_unused_result__))
412 static inline void *cxMapGet(
413 CxMap const *map,
414 cxstring const &key
415 ) {
416 return map->cl->get(map, cx_hash_key_cxstr(key));
417 }
419 /**
420 * Retrieves a value by using a key.
421 *
422 * @param map the map
423 * @param key the key
424 * @return the value
425 */
426 __attribute__((__nonnull__, __warn_unused_result__))
427 static inline void *cxMapGet(
428 CxMap const *map,
429 cxmutstr const &key
430 ) {
431 return map->cl->get(map, cx_hash_key_cxstr(key));
432 }
434 /**
435 * Retrieves a value by using a key.
436 *
437 * @param map the map
438 * @param key the key
439 * @return the value
440 */
441 __attribute__((__nonnull__, __warn_unused_result__))
442 static inline void *cxMapGet(
443 CxMap const *map,
444 char const *key
445 ) {
446 return map->cl->get(map, cx_hash_key_str(key));
447 }
449 /**
450 * Removes a key/value-pair from the map by using the key.
451 *
452 * Always invokes the destructor function, if any, on the removed element.
453 * If this map is storing pointers and you just want to retrieve the pointer
454 * without invoking the destructor, use cxMapRemoveAndGet().
455 * If you just want to detach the element from the map without invoking the
456 * destructor or returning the element, use cxMapDetach().
457 *
458 * @param map the map
459 * @param key the key
460 * @see cxMapRemoveAndGet()
461 * @see cxMapDetach()
462 */
463 __attribute__((__nonnull__))
464 static inline void cxMapRemove(
465 CxMap *map,
466 CxHashKey const &key
467 ) {
468 (void) map->cl->remove(map, key, true);
469 }
471 /**
472 * Removes a key/value-pair from the map by using the key.
473 *
474 * Always invokes the destructor function, if any, on the removed element.
475 * If this map is storing pointers and you just want to retrieve the pointer
476 * without invoking the destructor, use cxMapRemoveAndGet().
477 * If you just want to detach the element from the map without invoking the
478 * destructor or returning the element, use cxMapDetach().
479 *
480 * @param map the map
481 * @param key the key
482 * @see cxMapRemoveAndGet()
483 * @see cxMapDetach()
484 */
485 __attribute__((__nonnull__))
486 static inline void cxMapRemove(
487 CxMap *map,
488 cxstring const &key
489 ) {
490 (void) map->cl->remove(map, cx_hash_key_cxstr(key), true);
491 }
493 /**
494 * Removes a key/value-pair from the map by using the key.
495 *
496 * Always invokes the destructor function, if any, on the removed element.
497 * If this map is storing pointers and you just want to retrieve the pointer
498 * without invoking the destructor, use cxMapRemoveAndGet().
499 * If you just want to detach the element from the map without invoking the
500 * destructor or returning the element, use cxMapDetach().
501 *
502 * @param map the map
503 * @param key the key
504 * @see cxMapRemoveAndGet()
505 * @see cxMapDetach()
506 */
507 __attribute__((__nonnull__))
508 static inline void cxMapRemove(
509 CxMap *map,
510 cxmutstr const &key
511 ) {
512 (void) map->cl->remove(map, cx_hash_key_cxstr(key), true);
513 }
515 /**
516 * Removes a key/value-pair from the map by using the key.
517 *
518 * Always invokes the destructor function, if any, on the removed element.
519 * If this map is storing pointers and you just want to retrieve the pointer
520 * without invoking the destructor, use cxMapRemoveAndGet().
521 * If you just want to detach the element from the map without invoking the
522 * destructor or returning the element, use cxMapDetach().
523 *
524 * @param map the map
525 * @param key the key
526 * @see cxMapRemoveAndGet()
527 * @see cxMapDetach()
528 */
529 __attribute__((__nonnull__))
530 static inline void cxMapRemove(
531 CxMap *map,
532 char const *key
533 ) {
534 (void) map->cl->remove(map, cx_hash_key_str(key), true);
535 }
537 /**
538 * Detaches a key/value-pair from the map by using the key
539 * without invoking the destructor.
540 *
541 * In general, you should only use this function if the map does not own
542 * the data and there is a valid reference to the data somewhere else
543 * in the program. In all other cases it is preferable to use
544 * cxMapRemove() or cxMapRemoveAndGet().
545 *
546 * @param map the map
547 * @param key the key
548 * @see cxMapRemove()
549 * @see cxMapRemoveAndGet()
550 */
551 __attribute__((__nonnull__))
552 static inline void cxMapDetach(
553 CxMap *map,
554 CxHashKey const &key
555 ) {
556 (void) map->cl->remove(map, key, false);
557 }
559 /**
560 * Detaches a key/value-pair from the map by using the key
561 * without invoking the destructor.
562 *
563 * In general, you should only use this function if the map does not own
564 * the data and there is a valid reference to the data somewhere else
565 * in the program. In all other cases it is preferable to use
566 * cxMapRemove() or cxMapRemoveAndGet().
567 *
568 * @param map the map
569 * @param key the key
570 * @see cxMapRemove()
571 * @see cxMapRemoveAndGet()
572 */
573 __attribute__((__nonnull__))
574 static inline void cxMapDetach(
575 CxMap *map,
576 cxstring const &key
577 ) {
578 (void) map->cl->remove(map, cx_hash_key_cxstr(key), false);
579 }
581 /**
582 * Detaches a key/value-pair from the map by using the key
583 * without invoking the destructor.
584 *
585 * In general, you should only use this function if the map does not own
586 * the data and there is a valid reference to the data somewhere else
587 * in the program. In all other cases it is preferable to use
588 * cxMapRemove() or cxMapRemoveAndGet().
589 *
590 * @param map the map
591 * @param key the key
592 * @see cxMapRemove()
593 * @see cxMapRemoveAndGet()
594 */
595 __attribute__((__nonnull__))
596 static inline void cxMapDetach(
597 CxMap *map,
598 cxmutstr const &key
599 ) {
600 (void) map->cl->remove(map, cx_hash_key_cxstr(key), false);
601 }
603 /**
604 * Detaches a key/value-pair from the map by using the key
605 * without invoking the destructor.
606 *
607 * In general, you should only use this function if the map does not own
608 * the data and there is a valid reference to the data somewhere else
609 * in the program. In all other cases it is preferable to use
610 * cxMapRemove() or cxMapRemoveAndGet().
611 *
612 * @param map the map
613 * @param key the key
614 * @see cxMapRemove()
615 * @see cxMapRemoveAndGet()
616 */
617 __attribute__((__nonnull__))
618 static inline void cxMapDetach(
619 CxMap *map,
620 char const *key
621 ) {
622 (void) map->cl->remove(map, cx_hash_key_str(key), false);
623 }
625 /**
626 * Removes a key/value-pair from the map by using the key.
627 *
628 * This function can be used when the map is storing pointers,
629 * in order to retrieve the pointer from the map without invoking
630 * any destructor function. Sometimes you do not want the pointer
631 * to be returned - in that case (instead of suppressing the "unused
632 * result" warning) you can use cxMapDetach().
633 *
634 * If this map is not storing pointers, this function behaves like
635 * cxMapRemove() and returns \c NULL.
636 *
637 * @param map the map
638 * @param key the key
639 * @return the stored pointer or \c NULL if either the key is not present
640 * in the map or the map is not storing pointers
641 * @see cxMapStorePointers()
642 * @see cxMapDetach()
643 */
644 __attribute__((__nonnull__, __warn_unused_result__))
645 static inline void *cxMapRemoveAndGet(
646 CxMap *map,
647 CxHashKey key
648 ) {
649 return map->cl->remove(map, key, !map->store_pointer);
650 }
652 /**
653 * Removes a key/value-pair from the map by using the key.
654 *
655 * This function can be used when the map is storing pointers,
656 * in order to retrieve the pointer from the map without invoking
657 * any destructor function. Sometimes you do not want the pointer
658 * to be returned - in that case (instead of suppressing the "unused
659 * result" warning) you can use cxMapDetach().
660 *
661 * If this map is not storing pointers, this function behaves like
662 * cxMapRemove() and returns \c NULL.
663 *
664 * @param map the map
665 * @param key the key
666 * @return the stored pointer or \c NULL if either the key is not present
667 * in the map or the map is not storing pointers
668 * @see cxMapStorePointers()
669 * @see cxMapDetach()
670 */
671 __attribute__((__nonnull__, __warn_unused_result__))
672 static inline void *cxMapRemoveAndGet(
673 CxMap *map,
674 cxstring key
675 ) {
676 return map->cl->remove(map, cx_hash_key_cxstr(key), !map->store_pointer);
677 }
679 /**
680 * Removes a key/value-pair from the map by using the key.
681 *
682 * This function can be used when the map is storing pointers,
683 * in order to retrieve the pointer from the map without invoking
684 * any destructor function. Sometimes you do not want the pointer
685 * to be returned - in that case (instead of suppressing the "unused
686 * result" warning) you can use cxMapDetach().
687 *
688 * If this map is not storing pointers, this function behaves like
689 * cxMapRemove() and returns \c NULL.
690 *
691 * @param map the map
692 * @param key the key
693 * @return the stored pointer or \c NULL if either the key is not present
694 * in the map or the map is not storing pointers
695 * @see cxMapStorePointers()
696 * @see cxMapDetach()
697 */
698 __attribute__((__nonnull__, __warn_unused_result__))
699 static inline void *cxMapRemoveAndGet(
700 CxMap *map,
701 cxmutstr key
702 ) {
703 return map->cl->remove(map, cx_hash_key_cxstr(key), !map->store_pointer);
704 }
706 /**
707 * Removes a key/value-pair from the map by using the key.
708 *
709 * This function can be used when the map is storing pointers,
710 * in order to retrieve the pointer from the map without invoking
711 * any destructor function. Sometimes you do not want the pointer
712 * to be returned - in that case (instead of suppressing the "unused
713 * result" warning) you can use cxMapDetach().
714 *
715 * If this map is not storing pointers, this function behaves like
716 * cxMapRemove() and returns \c NULL.
717 *
718 * @param map the map
719 * @param key the key
720 * @return the stored pointer or \c NULL if either the key is not present
721 * in the map or the map is not storing pointers
722 * @see cxMapStorePointers()
723 * @see cxMapDetach()
724 */
725 __attribute__((__nonnull__, __warn_unused_result__))
726 static inline void *cxMapRemoveAndGet(
727 CxMap *map,
728 char const *key
729 ) {
730 return map->cl->remove(map, cx_hash_key_str(key), !map->store_pointer);
731 }
733 #else // __cplusplus
735 /**
736 * Puts a key/value-pair into the map.
737 *
738 * @param map the map
739 * @param key the key
740 * @param value the value
741 * @return 0 on success, non-zero value on failure
742 */
743 __attribute__((__nonnull__))
744 static inline int cx_map_put(
745 CxMap *map,
746 CxHashKey key,
747 void *value
748 ) {
749 return map->cl->put(map, key, value);
750 }
752 /**
753 * Puts a key/value-pair into the map.
754 *
755 * @param map the map
756 * @param key the key
757 * @param value the value
758 * @return 0 on success, non-zero value on failure
759 */
760 __attribute__((__nonnull__))
761 static inline int cx_map_put_cxstr(
762 CxMap *map,
763 cxstring key,
764 void *value
765 ) {
766 return map->cl->put(map, cx_hash_key_cxstr(key), value);
767 }
769 /**
770 * Puts a key/value-pair into the map.
771 *
772 * @param map the map
773 * @param key the key
774 * @param value the value
775 * @return 0 on success, non-zero value on failure
776 */
777 __attribute__((__nonnull__))
778 static inline int cx_map_put_mustr(
779 CxMap *map,
780 cxmutstr key,
781 void *value
782 ) {
783 return map->cl->put(map, cx_hash_key_cxstr(key), value);
784 }
786 /**
787 * Puts a key/value-pair into the map.
788 *
789 * @param map the map
790 * @param key the key
791 * @param value the value
792 * @return 0 on success, non-zero value on failure
793 */
794 __attribute__((__nonnull__))
795 static inline int cx_map_put_str(
796 CxMap *map,
797 char const *key,
798 void *value
799 ) {
800 return map->cl->put(map, cx_hash_key_str(key), value);
801 }
803 /**
804 * Puts a key/value-pair into the map.
805 *
806 * @param map the map
807 * @param key the key
808 * @param value the value
809 * @return 0 on success, non-zero value on failure
810 */
811 #define cxMapPut(map, key, value) _Generic((key), \
812 CxHashKey: cx_map_put, \
813 cxstring: cx_map_put_cxstr, \
814 cxmutstr: cx_map_put_mustr, \
815 char*: cx_map_put_str, \
816 char const*: cx_map_put_str) \
817 (map, key, value)
819 /**
820 * Retrieves a value by using a key.
821 *
822 * @param map the map
823 * @param key the key
824 * @return the value
825 */
826 __attribute__((__nonnull__, __warn_unused_result__))
827 static inline void *cx_map_get(
828 CxMap const *map,
829 CxHashKey key
830 ) {
831 return map->cl->get(map, key);
832 }
834 /**
835 * Retrieves a value by using a key.
836 *
837 * @param map the map
838 * @param key the key
839 * @return the value
840 */
841 __attribute__((__nonnull__, __warn_unused_result__))
842 static inline void *cx_map_get_cxstr(
843 CxMap const *map,
844 cxstring key
845 ) {
846 return map->cl->get(map, cx_hash_key_cxstr(key));
847 }
849 /**
850 * Retrieves a value by using a key.
851 *
852 * @param map the map
853 * @param key the key
854 * @return the value
855 */
856 __attribute__((__nonnull__, __warn_unused_result__))
857 static inline void *cx_map_get_mustr(
858 CxMap const *map,
859 cxmutstr key
860 ) {
861 return map->cl->get(map, cx_hash_key_cxstr(key));
862 }
864 /**
865 * Retrieves a value by using a key.
866 *
867 * @param map the map
868 * @param key the key
869 * @return the value
870 */
871 __attribute__((__nonnull__, __warn_unused_result__))
872 static inline void *cx_map_get_str(
873 CxMap const *map,
874 char const *key
875 ) {
876 return map->cl->get(map, cx_hash_key_str(key));
877 }
879 /**
880 * Retrieves a value by using a key.
881 *
882 * @param map the map
883 * @param key the key
884 * @return the value
885 */
886 #define cxMapGet(map, key) _Generic((key), \
887 CxHashKey: cx_map_get, \
888 cxstring: cx_map_get_cxstr, \
889 cxmutstr: cx_map_get_mustr, \
890 char*: cx_map_get_str, \
891 char const*: cx_map_get_str) \
892 (map, key)
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(
902 CxMap *map,
903 CxHashKey key
904 ) {
905 (void) map->cl->remove(map, 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_cxstr(
916 CxMap *map,
917 cxstring 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_mustr(
930 CxMap *map,
931 cxmutstr key
932 ) {
933 (void) map->cl->remove(map, cx_hash_key_cxstr(key), true);
934 }
936 /**
937 * Removes a key/value-pair from the map by using the key.
938 *
939 * @param map the map
940 * @param key the key
941 */
942 __attribute__((__nonnull__))
943 static inline void cx_map_remove_str(
944 CxMap *map,
945 char const *key
946 ) {
947 (void) map->cl->remove(map, cx_hash_key_str(key), true);
948 }
950 /**
951 * Removes a key/value-pair from the map by using the key.
952 *
953 * Always invokes the destructor function, if any, on the removed element.
954 * If this map is storing pointers and you just want to retrieve the pointer
955 * without invoking the destructor, use cxMapRemoveAndGet().
956 * If you just want to detach the element from the map without invoking the
957 * destructor or returning the element, use cxMapDetach().
958 *
959 * @param map the map
960 * @param key the key
961 * @see cxMapRemoveAndGet()
962 * @see cxMapDetach()
963 */
964 #define cxMapRemove(map, key) _Generic((key), \
965 CxHashKey: cx_map_remove, \
966 cxstring: cx_map_remove_cxstr, \
967 cxmutstr: cx_map_remove_mustr, \
968 char*: cx_map_remove_str, \
969 char const*: cx_map_remove_str) \
970 (map, key)
972 /**
973 * Detaches a key/value-pair from the map by using the key
974 * without invoking the destructor.
975 *
976 * @param map the map
977 * @param key the key
978 */
979 __attribute__((__nonnull__))
980 static inline void cx_map_detach(
981 CxMap *map,
982 CxHashKey key
983 ) {
984 (void) map->cl->remove(map, key, false);
985 }
987 /**
988 * Detaches a key/value-pair from the map by using the key
989 * without invoking the destructor.
990 *
991 * @param map the map
992 * @param key the key
993 */
994 __attribute__((__nonnull__))
995 static inline void cx_map_detach_cxstr(
996 CxMap *map,
997 cxstring key
998 ) {
999 (void) map->cl->remove(map, cx_hash_key_cxstr(key), false);
1000 }
1002 /**
1003 * Detaches a key/value-pair from the map by using the key
1004 * without invoking the destructor.
1005 *
1006 * @param map the map
1007 * @param key the key
1008 */
1009 __attribute__((__nonnull__))
1010 static inline void cx_map_detach_mustr(
1011 CxMap *map,
1012 cxmutstr key
1013 ) {
1014 (void) map->cl->remove(map, cx_hash_key_cxstr(key), false);
1015 }
1017 /**
1018 * Detaches a key/value-pair from the map by using the key
1019 * without invoking the destructor.
1020 *
1021 * @param map the map
1022 * @param key the key
1023 */
1024 __attribute__((__nonnull__))
1025 static inline void cx_map_detach_str(
1026 CxMap *map,
1027 char const *key
1028 ) {
1029 (void) map->cl->remove(map, cx_hash_key_str(key), false);
1030 }
1032 /**
1033 * Detaches a key/value-pair from the map by using the key
1034 * without invoking the destructor.
1035 *
1036 * In general, you should only use this function if the map does not own
1037 * the data and there is a valid reference to the data somewhere else
1038 * in the program. In all other cases it is preferable to use
1039 * cxMapRemove() or cxMapRemoveAndGet().
1040 *
1041 * @param map the map
1042 * @param key the key
1043 * @see cxMapRemove()
1044 * @see cxMapRemoveAndGet()
1045 */
1046 #define cxMapDetach(map, key) _Generic((key), \
1047 CxHashKey: cx_map_detach, \
1048 cxstring: cx_map_detach_cxstr, \
1049 cxmutstr: cx_map_detach_mustr, \
1050 char*: cx_map_detach_str, \
1051 char const*: cx_map_detach_str) \
1052 (map, key)
1054 /**
1055 * Removes a key/value-pair from the map by using the key.
1056 *
1057 * @param map the map
1058 * @param key the key
1059 * @return the stored pointer or \c NULL if either the key is not present
1060 * in the map or the map is not storing pointers
1061 */
1062 __attribute__((__nonnull__, __warn_unused_result__))
1063 static inline void *cx_map_remove_and_get(
1064 CxMap *map,
1065 CxHashKey key
1066 ) {
1067 return map->cl->remove(map, key, !map->store_pointer);
1068 }
1070 /**
1071 * Removes a key/value-pair from the map by using the key.
1072 *
1073 * @param map the map
1074 * @param key the key
1075 * @return the stored pointer or \c NULL if either the key is not present
1076 * in the map or the map is not storing pointers
1077 */
1078 __attribute__((__nonnull__, __warn_unused_result__))
1079 static inline void *cx_map_remove_and_get_cxstr(
1080 CxMap *map,
1081 cxstring key
1082 ) {
1083 return map->cl->remove(map, cx_hash_key_cxstr(key), !map->store_pointer);
1084 }
1086 /**
1087 * Removes a key/value-pair from the map by using the key.
1088 *
1089 * @param map the map
1090 * @param key the key
1091 * @return the stored pointer or \c NULL if either the key is not present
1092 * in the map or the map is not storing pointers
1093 */
1094 __attribute__((__nonnull__, __warn_unused_result__))
1095 static inline void *cx_map_remove_and_get_mustr(
1096 CxMap *map,
1097 cxmutstr key
1098 ) {
1099 return map->cl->remove(map, cx_hash_key_cxstr(key), !map->store_pointer);
1100 }
1102 /**
1103 * Removes a key/value-pair from the map by using the key.
1104 *
1105 * @param map the map
1106 * @param key the key
1107 * @return the stored pointer or \c NULL if either the key is not present
1108 * in the map or the map is not storing pointers
1109 */
1110 __attribute__((__nonnull__, __warn_unused_result__))
1111 static inline void *cx_map_remove_and_get_str(
1112 CxMap *map,
1113 char const *key
1114 ) {
1115 return map->cl->remove(map, cx_hash_key_str(key), !map->store_pointer);
1116 }
1118 /**
1119 * Removes a key/value-pair from the map by using the key.
1120 *
1121 * This function can be used when the map is storing pointers,
1122 * in order to retrieve the pointer from the map without invoking
1123 * any destructor function. Sometimes you do not want the pointer
1124 * to be returned - in that case (instead of suppressing the "unused
1125 * result" warning) you can use cxMapDetach().
1126 *
1127 * If this map is not storing pointers, this function behaves like
1128 * cxMapRemove() and returns \c NULL.
1129 *
1130 * @param map the map
1131 * @param key the key
1132 * @return the stored pointer or \c NULL if either the key is not present
1133 * in the map or the map is not storing pointers
1134 * @see cxMapStorePointers()
1135 * @see cxMapDetach()
1136 */
1137 #define cxMapRemoveAndGet(map, key) _Generic((key), \
1138 CxHashKey: cx_map_remove_and_get, \
1139 cxstring: cx_map_remove_and_get_cxstr, \
1140 cxmutstr: cx_map_remove_and_get_mustr, \
1141 char*: cx_map_remove_and_get_str, \
1142 char const*: cx_map_remove_and_get_str) \
1143 (map, key)
1145 #endif // __cplusplus
1147 #endif // UCX_MAP_H