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 CxMap const *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)(CxMap const *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 CxHashKey const *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(CxMap const *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(CxMap const *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(CxMap const *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(CxMap const *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(CxMap const *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 char const *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 CxMap const *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 CxMap const *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 CxMap const *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 CxMap const *map, 455 char const *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 char const *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 char const *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->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->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->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 char const *key 740 ) { 741 return map->cl->remove(map, cx_hash_key_str(key), !map->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 char const *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 char const*: 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 CxMap const *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 CxMap const *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 CxMap const *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 CxMap const *map, 885 char const *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 char const*: 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 char const *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 char const*: 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 char const *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 char const*: 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 char const *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 char const*: cx_map_remove_and_get_str) \ 1154 (map, key) 1155 1156 #endif // __cplusplus 1157 1158 #endif // UCX_MAP_H 1159