ucx/cx/map.h

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

mercurial