ucx/cx/map.h

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

mercurial