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