ucx/cx/map.h

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

mercurial