UNIXworkcode

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 638 #else // __cplusplus 639 640 /** 641 * Puts a key/value-pair into the map. 642 * 643 * @param map the map 644 * @param key the key 645 * @param value the value 646 * @return 0 on success, non-zero value on failure 647 */ 648 __attribute__((__nonnull__)) 649 static inline int cx_map_put( 650 CxMap *map, 651 CxHashKey key, 652 void *value 653 ) { 654 return map->cl->put(map, key, value); 655 } 656 657 /** 658 * Puts a key/value-pair into the map. 659 * 660 * @param map the map 661 * @param key the key 662 * @param value the value 663 * @return 0 on success, non-zero value on failure 664 */ 665 __attribute__((__nonnull__)) 666 static inline int cx_map_put_cxstr( 667 CxMap *map, 668 cxstring key, 669 void *value 670 ) { 671 return map->cl->put(map, cx_hash_key_cxstr(key), value); 672 } 673 674 /** 675 * Puts a key/value-pair into the map. 676 * 677 * @param map the map 678 * @param key the key 679 * @param value the value 680 * @return 0 on success, non-zero value on failure 681 */ 682 __attribute__((__nonnull__)) 683 static inline int cx_map_put_mustr( 684 CxMap *map, 685 cxmutstr key, 686 void *value 687 ) { 688 return map->cl->put(map, cx_hash_key_cxstr(key), value); 689 } 690 691 /** 692 * Puts a key/value-pair into the map. 693 * 694 * @param map the map 695 * @param key the key 696 * @param value the value 697 * @return 0 on success, non-zero value on failure 698 */ 699 __attribute__((__nonnull__)) 700 static inline int cx_map_put_str( 701 CxMap *map, 702 const char *key, 703 void *value 704 ) { 705 return map->cl->put(map, cx_hash_key_str(key), value); 706 } 707 708 /** 709 * Puts a key/value-pair into the map. 710 * 711 * @param map the map 712 * @param key the key 713 * @param value the value 714 * @return 0 on success, non-zero value on failure 715 */ 716 #define cxMapPut(map, key, value) _Generic((key), \ 717 CxHashKey: cx_map_put, \ 718 cxstring: cx_map_put_cxstr, \ 719 cxmutstr: cx_map_put_mustr, \ 720 char*: cx_map_put_str, \ 721 const char*: cx_map_put_str) \ 722 (map, key, value) 723 724 /** 725 * Retrieves a value by using a key. 726 * 727 * @param map the map 728 * @param key the key 729 * @return the value 730 */ 731 __attribute__((__nonnull__, __warn_unused_result__)) 732 static inline void *cx_map_get( 733 const CxMap *map, 734 CxHashKey key 735 ) { 736 return map->cl->get(map, key); 737 } 738 739 /** 740 * Retrieves a value by using a key. 741 * 742 * @param map the map 743 * @param key the key 744 * @return the value 745 */ 746 __attribute__((__nonnull__, __warn_unused_result__)) 747 static inline void *cx_map_get_cxstr( 748 const CxMap *map, 749 cxstring key 750 ) { 751 return map->cl->get(map, cx_hash_key_cxstr(key)); 752 } 753 754 /** 755 * Retrieves a value by using a key. 756 * 757 * @param map the map 758 * @param key the key 759 * @return the value 760 */ 761 __attribute__((__nonnull__, __warn_unused_result__)) 762 static inline void *cx_map_get_mustr( 763 const CxMap *map, 764 cxmutstr key 765 ) { 766 return map->cl->get(map, cx_hash_key_cxstr(key)); 767 } 768 769 /** 770 * Retrieves a value by using a key. 771 * 772 * @param map the map 773 * @param key the key 774 * @return the value 775 */ 776 __attribute__((__nonnull__, __warn_unused_result__)) 777 static inline void *cx_map_get_str( 778 const CxMap *map, 779 const char *key 780 ) { 781 return map->cl->get(map, cx_hash_key_str(key)); 782 } 783 784 /** 785 * Retrieves a value by using a key. 786 * 787 * @param map the map 788 * @param key the key 789 * @return the value 790 */ 791 #define cxMapGet(map, key) _Generic((key), \ 792 CxHashKey: cx_map_get, \ 793 cxstring: cx_map_get_cxstr, \ 794 cxmutstr: cx_map_get_mustr, \ 795 char*: cx_map_get_str, \ 796 const char*: cx_map_get_str) \ 797 (map, key) 798 799 /** 800 * Removes a key/value-pair from the map by using the key. 801 * 802 * @param map the map 803 * @param key the key 804 */ 805 __attribute__((__nonnull__)) 806 static inline void cx_map_remove( 807 CxMap *map, 808 CxHashKey key 809 ) { 810 (void) map->cl->remove(map, key, true); 811 } 812 813 /** 814 * Removes a key/value-pair from the map by using the key. 815 * 816 * @param map the map 817 * @param key the key 818 */ 819 __attribute__((__nonnull__)) 820 static inline void cx_map_remove_cxstr( 821 CxMap *map, 822 cxstring key 823 ) { 824 (void) map->cl->remove(map, cx_hash_key_cxstr(key), true); 825 } 826 827 /** 828 * Removes a key/value-pair from the map by using the key. 829 * 830 * @param map the map 831 * @param key the key 832 */ 833 __attribute__((__nonnull__)) 834 static inline void cx_map_remove_mustr( 835 CxMap *map, 836 cxmutstr key 837 ) { 838 (void) map->cl->remove(map, cx_hash_key_cxstr(key), true); 839 } 840 841 /** 842 * Removes a key/value-pair from the map by using the key. 843 * 844 * @param map the map 845 * @param key the key 846 */ 847 __attribute__((__nonnull__)) 848 static inline void cx_map_remove_str( 849 CxMap *map, 850 const char *key 851 ) { 852 (void) map->cl->remove(map, cx_hash_key_str(key), true); 853 } 854 855 /** 856 * Removes a key/value-pair from the map by using the key. 857 * 858 * Always invokes the destructor function, if any, on the removed element. 859 * If this map is storing pointers and you just want to retrieve the pointer 860 * without invoking the destructor, use cxMapRemoveAndGet(). 861 * If you just want to detach the element from the map without invoking the 862 * destructor or returning the element, use cxMapDetach(). 863 * 864 * @param map the map 865 * @param key the key 866 * @see cxMapRemoveAndGet() 867 * @see cxMapDetach() 868 */ 869 #define cxMapRemove(map, key) _Generic((key), \ 870 CxHashKey: cx_map_remove, \ 871 cxstring: cx_map_remove_cxstr, \ 872 cxmutstr: cx_map_remove_mustr, \ 873 char*: cx_map_remove_str, \ 874 const char*: cx_map_remove_str) \ 875 (map, key) 876 877 /** 878 * Detaches a key/value-pair from the map by using the key 879 * without invoking the destructor. 880 * 881 * @param map the map 882 * @param key the key 883 */ 884 __attribute__((__nonnull__)) 885 static inline void cx_map_detach( 886 CxMap *map, 887 CxHashKey key 888 ) { 889 (void) map->cl->remove(map, key, false); 890 } 891 892 /** 893 * Detaches a key/value-pair from the map by using the key 894 * without invoking the destructor. 895 * 896 * @param map the map 897 * @param key the key 898 */ 899 __attribute__((__nonnull__)) 900 static inline void cx_map_detach_cxstr( 901 CxMap *map, 902 cxstring key 903 ) { 904 (void) map->cl->remove(map, cx_hash_key_cxstr(key), false); 905 } 906 907 /** 908 * Detaches a key/value-pair from the map by using the key 909 * without invoking the destructor. 910 * 911 * @param map the map 912 * @param key the key 913 */ 914 __attribute__((__nonnull__)) 915 static inline void cx_map_detach_mustr( 916 CxMap *map, 917 cxmutstr key 918 ) { 919 (void) map->cl->remove(map, cx_hash_key_cxstr(key), false); 920 } 921 922 /** 923 * Detaches a key/value-pair from the map by using the key 924 * without invoking the destructor. 925 * 926 * @param map the map 927 * @param key the key 928 */ 929 __attribute__((__nonnull__)) 930 static inline void cx_map_detach_str( 931 CxMap *map, 932 const char *key 933 ) { 934 (void) map->cl->remove(map, cx_hash_key_str(key), false); 935 } 936 937 /** 938 * Detaches a key/value-pair from the map by using the key 939 * without invoking the destructor. 940 * 941 * In general, you should only use this function if the map does not own 942 * the data and there is a valid reference to the data somewhere else 943 * in the program. In all other cases it is preferable to use 944 * cxMapRemove() or cxMapRemoveAndGet(). 945 * 946 * @param map the map 947 * @param key the key 948 * @see cxMapRemove() 949 * @see cxMapRemoveAndGet() 950 */ 951 #define cxMapDetach(map, key) _Generic((key), \ 952 CxHashKey: cx_map_detach, \ 953 cxstring: cx_map_detach_cxstr, \ 954 cxmutstr: cx_map_detach_mustr, \ 955 char*: cx_map_detach_str, \ 956 const char*: cx_map_detach_str) \ 957 (map, key) 958 959 /** 960 * Removes a key/value-pair from the map by using the key. 961 * 962 * @param map the map 963 * @param key the key 964 * @return the stored pointer or \c NULL if either the key is not present 965 * in the map or the map is not storing pointers 966 */ 967 __attribute__((__nonnull__, __warn_unused_result__)) 968 static inline void *cx_map_remove_and_get( 969 CxMap *map, 970 CxHashKey key 971 ) { 972 return map->cl->remove(map, key, !map->collection.store_pointer); 973 } 974 975 /** 976 * Removes a key/value-pair from the map by using the key. 977 * 978 * @param map the map 979 * @param key the key 980 * @return the stored pointer or \c NULL if either the key is not present 981 * in the map or the map is not storing pointers 982 */ 983 __attribute__((__nonnull__, __warn_unused_result__)) 984 static inline void *cx_map_remove_and_get_cxstr( 985 CxMap *map, 986 cxstring key 987 ) { 988 return map->cl->remove(map, cx_hash_key_cxstr(key), !map->collection.store_pointer); 989 } 990 991 /** 992 * Removes a key/value-pair from the map by using the key. 993 * 994 * @param map the map 995 * @param key the key 996 * @return the stored pointer or \c NULL if either the key is not present 997 * in the map or the map is not storing pointers 998 */ 999 __attribute__((__nonnull__, __warn_unused_result__)) 1000 static inline void *cx_map_remove_and_get_mustr( 1001 CxMap *map, 1002 cxmutstr key 1003 ) { 1004 return map->cl->remove(map, cx_hash_key_cxstr(key), !map->collection.store_pointer); 1005 } 1006 1007 /** 1008 * Removes a key/value-pair from the map by using the key. 1009 * 1010 * @param map the map 1011 * @param key the key 1012 * @return the stored pointer or \c NULL if either the key is not present 1013 * in the map or the map is not storing pointers 1014 */ 1015 __attribute__((__nonnull__, __warn_unused_result__)) 1016 static inline void *cx_map_remove_and_get_str( 1017 CxMap *map, 1018 const char *key 1019 ) { 1020 return map->cl->remove(map, cx_hash_key_str(key), !map->collection.store_pointer); 1021 } 1022 1023 /** 1024 * Removes a key/value-pair from the map by using the key. 1025 * 1026 * This function can be used when the map is storing pointers, 1027 * in order to retrieve the pointer from the map without invoking 1028 * any destructor function. Sometimes you do not want the pointer 1029 * to be returned - in that case (instead of suppressing the "unused 1030 * result" warning) you can use cxMapDetach(). 1031 * 1032 * If this map is not storing pointers, this function behaves like 1033 * cxMapRemove() and returns \c NULL. 1034 * 1035 * @param map the map 1036 * @param key the key 1037 * @return the stored pointer or \c NULL if either the key is not present 1038 * in the map or the map is not storing pointers 1039 * @see cxMapStorePointers() 1040 * @see cxMapDetach() 1041 */ 1042 #define cxMapRemoveAndGet(map, key) _Generic((key), \ 1043 CxHashKey: cx_map_remove_and_get, \ 1044 cxstring: cx_map_remove_and_get_cxstr, \ 1045 cxmutstr: cx_map_remove_and_get_mustr, \ 1046 char*: cx_map_remove_and_get_str, \ 1047 const char*: cx_map_remove_and_get_str) \ 1048 (map, key) 1049 1050 #endif // __cplusplus 1051 1052 #endif // UCX_MAP_H 1053