| 1101:2872f287fadc | 1102:db5e355e5349 |
|---|---|
| 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 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 | 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
| 26 * POSSIBILITY OF SUCH DAMAGE. | 26 * POSSIBILITY OF SUCH DAMAGE. |
| 27 */ | 27 */ |
| 28 /** | 28 /** |
| 29 * \file map.h | 29 * @file map.h |
| 30 * \brief Interface for map implementations. | 30 * @brief Interface for map implementations. |
| 31 * \author Mike Becker | 31 * @author Mike Becker |
| 32 * \author Olaf Wintermann | 32 * @author Olaf Wintermann |
| 33 * \copyright 2-Clause BSD License | 33 * @copyright 2-Clause BSD License |
| 34 */ | 34 */ |
| 35 | 35 |
| 36 #ifndef UCX_MAP_H | 36 #ifndef UCX_MAP_H |
| 37 #define UCX_MAP_H | 37 #define UCX_MAP_H |
| 38 | 38 |
| 87 */ | 87 */ |
| 88 struct cx_map_class_s { | 88 struct cx_map_class_s { |
| 89 /** | 89 /** |
| 90 * Deallocates the entire memory. | 90 * Deallocates the entire memory. |
| 91 */ | 91 */ |
| 92 cx_attr_nonnull | |
| 93 void (*deallocate)(struct cx_map_s *map); | 92 void (*deallocate)(struct cx_map_s *map); |
| 94 | 93 |
| 95 /** | 94 /** |
| 96 * Removes all elements. | 95 * Removes all elements. |
| 97 */ | 96 */ |
| 98 cx_attr_nonnull | |
| 99 void (*clear)(struct cx_map_s *map); | 97 void (*clear)(struct cx_map_s *map); |
| 100 | 98 |
| 101 /** | 99 /** |
| 102 * Add or overwrite an element. | 100 * Add or overwrite an element. |
| 103 */ | 101 */ |
| 104 cx_attr_nonnull | |
| 105 int (*put)( | 102 int (*put)( |
| 106 CxMap *map, | 103 CxMap *map, |
| 107 CxHashKey key, | 104 CxHashKey key, |
| 108 void *value | 105 void *value |
| 109 ); | 106 ); |
| 110 | 107 |
| 111 /** | 108 /** |
| 112 * Returns an element. | 109 * Returns an element. |
| 113 */ | 110 */ |
| 114 cx_attr_nonnull | |
| 115 cx_attr_nodiscard | |
| 116 void *(*get)( | 111 void *(*get)( |
| 117 const CxMap *map, | 112 const CxMap *map, |
| 118 CxHashKey key | 113 CxHashKey key |
| 119 ); | 114 ); |
| 120 | 115 |
| 121 /** | 116 /** |
| 122 * Removes an element. | 117 * Removes an element. |
| 123 * | 118 * |
| 124 * Implementations SHALL check if \p targetbuf is set and copy the elements | 119 * Implementations SHALL check if @p targetbuf is set and copy the elements |
| 125 * to the buffer without invoking any destructor. | 120 * to the buffer without invoking any destructor. |
| 126 * When \p targetbuf is not set, the destructors SHALL be invoked. | 121 * When @p targetbuf is not set, the destructors SHALL be invoked. |
| 127 * | 122 * |
| 128 * The function SHALL return zero when the \p key was found and | 123 * The function SHALL return zero when the @p key was found and |
| 129 * non-zero, otherwise. | 124 * non-zero, otherwise. |
| 130 */ | 125 */ |
| 131 cx_attr_nonnull_arg(1) | |
| 132 cx_attr_access_w(3) | |
| 133 int (*remove)( | 126 int (*remove)( |
| 134 CxMap *map, | 127 CxMap *map, |
| 135 CxHashKey key, | 128 CxHashKey key, |
| 136 void *targetbuf | 129 void *targetbuf |
| 137 ); | 130 ); |
| 138 | 131 |
| 139 /** | 132 /** |
| 140 * Creates an iterator for this map. | 133 * Creates an iterator for this map. |
| 141 */ | 134 */ |
| 142 cx_attr_nonnull | |
| 143 cx_attr_nodiscard | |
| 144 CxIterator (*iterator)(const CxMap *map, enum cx_map_iterator_type type); | 135 CxIterator (*iterator)(const CxMap *map, enum cx_map_iterator_type type); |
| 145 }; | 136 }; |
| 146 | 137 |
| 147 /** | 138 /** |
| 148 * A map entry. | 139 * A map entry. |
| 160 | 151 |
| 161 /** | 152 /** |
| 162 * A shared instance of an empty map. | 153 * A shared instance of an empty map. |
| 163 * | 154 * |
| 164 * Writing to that map is not allowed. | 155 * Writing to that map is not allowed. |
| 156 * | |
| 157 * You can use this is a placeholder for initializing CxMap pointers | |
| 158 * for which you do not want to reserve memory right from the beginning. | |
| 165 */ | 159 */ |
| 166 extern CxMap *const cxEmptyMap; | 160 extern CxMap *const cxEmptyMap; |
| 167 | 161 |
| 168 /** | 162 /** |
| 169 * Advises the map to store copies of the objects (default mode of operation). | 163 * Advises the map to store copies of the objects (default mode of operation). |
| 210 } | 204 } |
| 211 | 205 |
| 212 /** | 206 /** |
| 213 * Deallocates the memory of the specified map. | 207 * Deallocates the memory of the specified map. |
| 214 * | 208 * |
| 209 * Also calls the content destructor functions for each element, if specified. | |
| 210 * | |
| 215 * @param map the map to be freed | 211 * @param map the map to be freed |
| 216 */ | 212 */ |
| 217 static inline void cxMapFree(CxMap *map) { | 213 static inline void cxMapFree(CxMap *map) { |
| 218 if (map == NULL) return; | 214 if (map == NULL) return; |
| 219 map->cl->deallocate(map); | 215 map->cl->deallocate(map); |
| 221 | 217 |
| 222 | 218 |
| 223 /** | 219 /** |
| 224 * Clears a map by removing all elements. | 220 * Clears a map by removing all elements. |
| 225 * | 221 * |
| 222 * Also calls the content destructor functions for each element, if specified. | |
| 223 * | |
| 226 * @param map the map to be cleared | 224 * @param map the map to be cleared |
| 227 */ | 225 */ |
| 228 cx_attr_nonnull | 226 cx_attr_nonnull |
| 229 static inline void cxMapClear(CxMap *map) { | 227 static inline void cxMapClear(CxMap *map) { |
| 230 map->cl->clear(map); | 228 map->cl->clear(map); |
| 239 cx_attr_nonnull | 237 cx_attr_nonnull |
| 240 static inline size_t cxMapSize(const CxMap *map) { | 238 static inline size_t cxMapSize(const CxMap *map) { |
| 241 return map->collection.size; | 239 return map->collection.size; |
| 242 } | 240 } |
| 243 | 241 |
| 244 | |
| 245 // TODO: set-like map operations (union, intersect, difference) | |
| 246 | |
| 247 /** | 242 /** |
| 248 * Creates a value iterator for a map. | 243 * Creates a value iterator for a map. |
| 249 * | 244 * |
| 250 * \note An iterator iterates over all elements successively. Therefore, the order | 245 * @note An iterator iterates over all elements successively. Therefore, the order |
| 251 * highly depends on the map implementation and may change arbitrarily when the contents change. | 246 * highly depends on the map implementation and may change arbitrarily when the contents change. |
| 252 * | 247 * |
| 253 * @param map the map to create the iterator for | 248 * @param map the map to create the iterator for |
| 254 * @return an iterator for the currently stored values | 249 * @return an iterator for the currently stored values |
| 255 */ | 250 */ |
| 262 /** | 257 /** |
| 263 * Creates a key iterator for a map. | 258 * Creates a key iterator for a map. |
| 264 * | 259 * |
| 265 * The elements of the iterator are keys of type CxHashKey. | 260 * The elements of the iterator are keys of type CxHashKey. |
| 266 * | 261 * |
| 267 * \note An iterator iterates over all elements successively. Therefore, the order | 262 * @note An iterator iterates over all elements successively. Therefore, the order |
| 268 * highly depends on the map implementation and may change arbitrarily when the contents change. | 263 * highly depends on the map implementation and may change arbitrarily when the contents change. |
| 269 * | 264 * |
| 270 * @param map the map to create the iterator for | 265 * @param map the map to create the iterator for |
| 271 * @return an iterator for the currently stored keys | 266 * @return an iterator for the currently stored keys |
| 272 */ | 267 */ |
| 279 /** | 274 /** |
| 280 * Creates an iterator for a map. | 275 * Creates an iterator for a map. |
| 281 * | 276 * |
| 282 * The elements of the iterator are key/value pairs of type CxMapEntry. | 277 * The elements of the iterator are key/value pairs of type CxMapEntry. |
| 283 * | 278 * |
| 284 * \note An iterator iterates over all elements successively. Therefore, the order | 279 * @note An iterator iterates over all elements successively. Therefore, the order |
| 285 * highly depends on the map implementation and may change arbitrarily when the contents change. | 280 * highly depends on the map implementation and may change arbitrarily when the contents change. |
| 286 * | 281 * |
| 287 * @param map the map to create the iterator for | 282 * @param map the map to create the iterator for |
| 288 * @return an iterator for the currently stored entries | 283 * @return an iterator for the currently stored entries |
| 289 * @see cxMapIteratorKeys() | 284 * @see cxMapIteratorKeys() |
| 297 | 292 |
| 298 | 293 |
| 299 /** | 294 /** |
| 300 * Creates a mutating iterator over the values of a map. | 295 * Creates a mutating iterator over the values of a map. |
| 301 * | 296 * |
| 302 * \note An iterator iterates over all elements successively. Therefore, the order | 297 * @note An iterator iterates over all elements successively. Therefore, the order |
| 303 * highly depends on the map implementation and may change arbitrarily when the contents change. | 298 * highly depends on the map implementation and may change arbitrarily when the contents change. |
| 304 * | 299 * |
| 305 * @param map the map to create the iterator for | 300 * @param map the map to create the iterator for |
| 306 * @return an iterator for the currently stored values | 301 * @return an iterator for the currently stored values |
| 307 */ | 302 */ |
| 312 /** | 307 /** |
| 313 * Creates a mutating iterator over the keys of a map. | 308 * Creates a mutating iterator over the keys of a map. |
| 314 * | 309 * |
| 315 * The elements of the iterator are keys of type CxHashKey. | 310 * The elements of the iterator are keys of type CxHashKey. |
| 316 * | 311 * |
| 317 * \note An iterator iterates over all elements successively. Therefore, the order | 312 * @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. | 313 * highly depends on the map implementation and may change arbitrarily when the contents change. |
| 319 * | 314 * |
| 320 * @param map the map to create the iterator for | 315 * @param map the map to create the iterator for |
| 321 * @return an iterator for the currently stored keys | 316 * @return an iterator for the currently stored keys |
| 322 */ | 317 */ |
| 327 /** | 322 /** |
| 328 * Creates a mutating iterator for a map. | 323 * Creates a mutating iterator for a map. |
| 329 * | 324 * |
| 330 * The elements of the iterator are key/value pairs of type CxMapEntry. | 325 * The elements of the iterator are key/value pairs of type CxMapEntry. |
| 331 * | 326 * |
| 332 * \note An iterator iterates over all elements successively. Therefore, the order | 327 * @note An iterator iterates over all elements successively. Therefore, the order |
| 333 * highly depends on the map implementation and may change arbitrarily when the contents change. | 328 * highly depends on the map implementation and may change arbitrarily when the contents change. |
| 334 * | 329 * |
| 335 * @param map the map to create the iterator for | 330 * @param map the map to create the iterator for |
| 336 * @return an iterator for the currently stored entries | 331 * @return an iterator for the currently stored entries |
| 337 * @see cxMapMutIteratorKeys() | 332 * @see cxMapMutIteratorKeys() |
| 341 cx_attr_nodiscard | 336 cx_attr_nodiscard |
| 342 CxIterator cxMapMutIterator(CxMap *map); | 337 CxIterator cxMapMutIterator(CxMap *map); |
| 343 | 338 |
| 344 #ifdef __cplusplus | 339 #ifdef __cplusplus |
| 345 } // end the extern "C" block here, because we want to start overloading | 340 } // end the extern "C" block here, because we want to start overloading |
| 346 | |
| 347 /** | |
| 348 * Puts a key/value-pair into the map. | |
| 349 * | |
| 350 * @param map the map | |
| 351 * @param key the key | |
| 352 * @param value the value | |
| 353 * @return 0 on success, non-zero value on failure | |
| 354 */ | |
| 355 cx_attr_nonnull | 341 cx_attr_nonnull |
| 356 static inline int cxMapPut( | 342 static inline int cxMapPut( |
| 357 CxMap *map, | 343 CxMap *map, |
| 358 CxHashKey const &key, | 344 CxHashKey const &key, |
| 359 void *value | 345 void *value |
| 360 ) { | 346 ) { |
| 361 return map->cl->put(map, key, value); | 347 return map->cl->put(map, key, value); |
| 362 } | 348 } |
| 363 | 349 |
| 364 | |
| 365 /** | |
| 366 * Puts a key/value-pair into the map. | |
| 367 * | |
| 368 * @param map the map | |
| 369 * @param key the key | |
| 370 * @param value the value | |
| 371 * @return 0 on success, non-zero value on failure | |
| 372 */ | |
| 373 cx_attr_nonnull | 350 cx_attr_nonnull |
| 374 static inline int cxMapPut( | 351 static inline int cxMapPut( |
| 375 CxMap *map, | 352 CxMap *map, |
| 376 cxstring const &key, | 353 cxstring const &key, |
| 377 void *value | 354 void *value |
| 378 ) { | 355 ) { |
| 379 return map->cl->put(map, cx_hash_key_cxstr(key), value); | 356 return map->cl->put(map, cx_hash_key_cxstr(key), value); |
| 380 } | 357 } |
| 381 | 358 |
| 382 /** | |
| 383 * Puts a key/value-pair into the map. | |
| 384 * | |
| 385 * @param map the map | |
| 386 * @param key the key | |
| 387 * @param value the value | |
| 388 * @return 0 on success, non-zero value on failure | |
| 389 */ | |
| 390 cx_attr_nonnull | 359 cx_attr_nonnull |
| 391 static inline int cxMapPut( | 360 static inline int cxMapPut( |
| 392 CxMap *map, | 361 CxMap *map, |
| 393 cxmutstr const &key, | 362 cxmutstr const &key, |
| 394 void *value | 363 void *value |
| 395 ) { | 364 ) { |
| 396 return map->cl->put(map, cx_hash_key_cxstr(key), value); | 365 return map->cl->put(map, cx_hash_key_cxstr(key), value); |
| 397 } | 366 } |
| 398 | 367 |
| 399 /** | |
| 400 * Puts a key/value-pair into the map. | |
| 401 * | |
| 402 * @param map the map | |
| 403 * @param key the key | |
| 404 * @param value the value | |
| 405 * @return 0 on success, non-zero value on failure | |
| 406 */ | |
| 407 cx_attr_nonnull | 368 cx_attr_nonnull |
| 408 cx_attr_cstr_arg(2) | 369 cx_attr_cstr_arg(2) |
| 409 static inline int cxMapPut( | 370 static inline int cxMapPut( |
| 410 CxMap *map, | 371 CxMap *map, |
| 411 const char *key, | 372 const char *key, |
| 412 void *value | 373 void *value |
| 413 ) { | 374 ) { |
| 414 return map->cl->put(map, cx_hash_key_str(key), value); | 375 return map->cl->put(map, cx_hash_key_str(key), value); |
| 415 } | 376 } |
| 416 | 377 |
| 417 /** | |
| 418 * Retrieves a value by using a key. | |
| 419 * | |
| 420 * @param map the map | |
| 421 * @param key the key | |
| 422 * @return the value | |
| 423 */ | |
| 424 cx_attr_nonnull | 378 cx_attr_nonnull |
| 425 cx_attr_nodiscard | 379 cx_attr_nodiscard |
| 426 static inline void *cxMapGet( | 380 static inline void *cxMapGet( |
| 427 const CxMap *map, | 381 const CxMap *map, |
| 428 CxHashKey const &key | 382 CxHashKey const &key |
| 429 ) { | 383 ) { |
| 430 return map->cl->get(map, key); | 384 return map->cl->get(map, key); |
| 431 } | 385 } |
| 432 | 386 |
| 433 /** | |
| 434 * Retrieves a value by using a key. | |
| 435 * | |
| 436 * @param map the map | |
| 437 * @param key the key | |
| 438 * @return the value | |
| 439 */ | |
| 440 cx_attr_nonnull | 387 cx_attr_nonnull |
| 441 cx_attr_nodiscard | 388 cx_attr_nodiscard |
| 442 static inline void *cxMapGet( | 389 static inline void *cxMapGet( |
| 443 const CxMap *map, | 390 const CxMap *map, |
| 444 cxstring const &key | 391 cxstring const &key |
| 445 ) { | 392 ) { |
| 446 return map->cl->get(map, cx_hash_key_cxstr(key)); | 393 return map->cl->get(map, cx_hash_key_cxstr(key)); |
| 447 } | 394 } |
| 448 | 395 |
| 449 /** | |
| 450 * Retrieves a value by using a key. | |
| 451 * | |
| 452 * @param map the map | |
| 453 * @param key the key | |
| 454 * @return the value | |
| 455 */ | |
| 456 cx_attr_nonnull | 396 cx_attr_nonnull |
| 457 cx_attr_nodiscard | 397 cx_attr_nodiscard |
| 458 static inline void *cxMapGet( | 398 static inline void *cxMapGet( |
| 459 const CxMap *map, | 399 const CxMap *map, |
| 460 cxmutstr const &key | 400 cxmutstr const &key |
| 461 ) { | 401 ) { |
| 462 return map->cl->get(map, cx_hash_key_cxstr(key)); | 402 return map->cl->get(map, cx_hash_key_cxstr(key)); |
| 463 } | 403 } |
| 464 | 404 |
| 465 /** | |
| 466 * Retrieves a value by using a key. | |
| 467 * | |
| 468 * @param map the map | |
| 469 * @param key the key | |
| 470 * @return the value | |
| 471 */ | |
| 472 cx_attr_nonnull | 405 cx_attr_nonnull |
| 473 cx_attr_nodiscard | 406 cx_attr_nodiscard |
| 474 cx_attr_cstr_arg(2) | 407 cx_attr_cstr_arg(2) |
| 475 static inline void *cxMapGet( | 408 static inline void *cxMapGet( |
| 476 const CxMap *map, | 409 const CxMap *map, |
| 477 const char *key | 410 const char *key |
| 478 ) { | 411 ) { |
| 479 return map->cl->get(map, cx_hash_key_str(key)); | 412 return map->cl->get(map, cx_hash_key_str(key)); |
| 480 } | 413 } |
| 481 | 414 |
| 482 /** | |
| 483 * Removes a key/value-pair from the map by using the key. | |
| 484 * | |
| 485 * Always invokes the destructors functions, if any, on the removed element. | |
| 486 * | |
| 487 * @param map the map | |
| 488 * @param key the key | |
| 489 * @return zero on success, non-zero if the key was not found | |
| 490 * | |
| 491 * @see cxMapRemoveAndGet() | |
| 492 */ | |
| 493 cx_attr_nonnull | 415 cx_attr_nonnull |
| 494 static inline int cxMapRemove( | 416 static inline int cxMapRemove( |
| 495 CxMap *map, | 417 CxMap *map, |
| 496 CxHashKey const &key | 418 CxHashKey const &key |
| 497 ) { | 419 ) { |
| 498 return map->cl->remove(map, key, nullptr); | 420 return map->cl->remove(map, key, nullptr); |
| 499 } | 421 } |
| 500 | 422 |
| 501 /** | |
| 502 * Removes a key/value-pair from the map by using the key. | |
| 503 * | |
| 504 * Always invokes the destructors functions, if any, on the removed element. | |
| 505 * | |
| 506 * @param map the map | |
| 507 * @param key the key | |
| 508 * @return zero on success, non-zero if the key was not found | |
| 509 * | |
| 510 * @see cxMapRemoveAndGet() | |
| 511 */ | |
| 512 cx_attr_nonnull | 423 cx_attr_nonnull |
| 513 static inline int cxMapRemove( | 424 static inline int cxMapRemove( |
| 514 CxMap *map, | 425 CxMap *map, |
| 515 cxstring const &key | 426 cxstring const &key |
| 516 ) { | 427 ) { |
| 517 return map->cl->remove(map, cx_hash_key_cxstr(key), nullptr); | 428 return map->cl->remove(map, cx_hash_key_cxstr(key), nullptr); |
| 518 } | 429 } |
| 519 | 430 |
| 520 /** | |
| 521 * Removes a key/value-pair from the map by using the key. | |
| 522 * | |
| 523 * Always invokes the destructors functions, if any, on the removed element. | |
| 524 * | |
| 525 * @param map the map | |
| 526 * @param key the key | |
| 527 * @return zero on success, non-zero if the key was not found | |
| 528 * | |
| 529 * @see cxMapRemoveAndGet() | |
| 530 */ | |
| 531 cx_attr_nonnull | 431 cx_attr_nonnull |
| 532 static inline int cxMapRemove( | 432 static inline int cxMapRemove( |
| 533 CxMap *map, | 433 CxMap *map, |
| 534 cxmutstr const &key | 434 cxmutstr const &key |
| 535 ) { | 435 ) { |
| 536 return map->cl->remove(map, cx_hash_key_cxstr(key), nullptr); | 436 return map->cl->remove(map, cx_hash_key_cxstr(key), nullptr); |
| 537 } | 437 } |
| 538 | 438 |
| 539 /** | |
| 540 * Removes a key/value-pair from the map by using the key. | |
| 541 * | |
| 542 * Always invokes the destructors functions, if any, on the removed element. | |
| 543 * | |
| 544 * @param map the map | |
| 545 * @param key the key | |
| 546 * @return zero on success, non-zero if the key was not found | |
| 547 * | |
| 548 * @see cxMapRemoveAndGet() | |
| 549 */ | |
| 550 cx_attr_nonnull | 439 cx_attr_nonnull |
| 551 cx_attr_cstr_arg(2) | 440 cx_attr_cstr_arg(2) |
| 552 static inline int cxMapRemove( | 441 static inline int cxMapRemove( |
| 553 CxMap *map, | 442 CxMap *map, |
| 554 const char *key | 443 const char *key |
| 555 ) { | 444 ) { |
| 556 return map->cl->remove(map, cx_hash_key_str(key), nullptr); | 445 return map->cl->remove(map, cx_hash_key_str(key), nullptr); |
| 557 } | 446 } |
| 558 | 447 |
| 559 /** | |
| 560 * Removes a key/value-pair from the map by using the key. | |
| 561 * | |
| 562 * This function will copy the contents to the target buffer | |
| 563 * which must be guaranteed to be large enough to hold the element. | |
| 564 * The destructor functions, if any, will \em not be called. | |
| 565 * | |
| 566 * If this map is storing pointers, the element is the pointer itself | |
| 567 * and not the object it points to. | |
| 568 * | |
| 569 * @param map the map | |
| 570 * @param key the key | |
| 571 * @param targetbuf the buffer where the element shall be copied to | |
| 572 * @return zero on success, non-zero if the key was not found | |
| 573 * | |
| 574 * @see cxMapStorePointers() | |
| 575 * @see cxMapRemove() | |
| 576 */ | |
| 577 cx_attr_nonnull | 448 cx_attr_nonnull |
| 578 cx_attr_access_w(3) | 449 cx_attr_access_w(3) |
| 579 static inline int cxMapRemoveAndGet( | 450 static inline int cxMapRemoveAndGet( |
| 580 CxMap *map, | 451 CxMap *map, |
| 581 CxHashKey key, | 452 CxHashKey key, |
| 582 void *targetbuf | 453 void *targetbuf |
| 583 ) { | 454 ) { |
| 584 return map->cl->remove(map, key, targetbuf); | 455 return map->cl->remove(map, key, targetbuf); |
| 585 } | 456 } |
| 586 | 457 |
| 587 /** | |
| 588 * Removes a key/value-pair from the map by using the key. | |
| 589 * | |
| 590 * This function will copy the contents to the target buffer | |
| 591 * which must be guaranteed to be large enough to hold the element. | |
| 592 * The destructor functions, if any, will \em not be called. | |
| 593 * | |
| 594 * If this map is storing pointers, the element is the pointer itself | |
| 595 * and not the object it points to. | |
| 596 * | |
| 597 * @param map the map | |
| 598 * @param key the key | |
| 599 * @param targetbuf the buffer where the element shall be copied to | |
| 600 * @return zero on success, non-zero if the key was not found | |
| 601 * | |
| 602 * @see cxMapStorePointers() | |
| 603 * @see cxMapRemove() | |
| 604 */ | |
| 605 cx_attr_nonnull | 458 cx_attr_nonnull |
| 606 cx_attr_access_w(3) | 459 cx_attr_access_w(3) |
| 607 static inline int cxMapRemoveAndGet( | 460 static inline int cxMapRemoveAndGet( |
| 608 CxMap *map, | 461 CxMap *map, |
| 609 cxstring key, | 462 cxstring key, |
| 610 void *targetbuf | 463 void *targetbuf |
| 611 ) { | 464 ) { |
| 612 return map->cl->remove(map, cx_hash_key_cxstr(key), targetbuf); | 465 return map->cl->remove(map, cx_hash_key_cxstr(key), targetbuf); |
| 613 } | 466 } |
| 614 | 467 |
| 615 /** | |
| 616 * Removes a key/value-pair from the map by using the key. | |
| 617 * | |
| 618 * This function will copy the contents to the target buffer | |
| 619 * which must be guaranteed to be large enough to hold the element. | |
| 620 * The destructor functions, if any, will \em not be called. | |
| 621 * | |
| 622 * If this map is storing pointers, the element is the pointer itself | |
| 623 * and not the object it points to. | |
| 624 * | |
| 625 * @param map the map | |
| 626 * @param key the key | |
| 627 * @param targetbuf the buffer where the element shall be copied to | |
| 628 * @return zero on success, non-zero if the key was not found | |
| 629 * | |
| 630 * @see cxMapStorePointers() | |
| 631 * @see cxMapRemove() | |
| 632 */ | |
| 633 cx_attr_nonnull | 468 cx_attr_nonnull |
| 634 cx_attr_access_w(3) | 469 cx_attr_access_w(3) |
| 635 static inline int cxMapRemoveAndGet( | 470 static inline int cxMapRemoveAndGet( |
| 636 CxMap *map, | 471 CxMap *map, |
| 637 cxmutstr key, | 472 cxmutstr key, |
| 638 void *targetbuf | 473 void *targetbuf |
| 639 ) { | 474 ) { |
| 640 return map->cl->remove(map, cx_hash_key_cxstr(key), targetbuf); | 475 return map->cl->remove(map, cx_hash_key_cxstr(key), targetbuf); |
| 641 } | 476 } |
| 642 | 477 |
| 643 /** | |
| 644 * Removes a key/value-pair from the map by using the key. | |
| 645 * | |
| 646 * This function will copy the contents to the target buffer | |
| 647 * which must be guaranteed to be large enough to hold the element. | |
| 648 * The destructor functions, if any, will \em not be called. | |
| 649 * | |
| 650 * If this map is storing pointers, the element is the pointer itself | |
| 651 * and not the object it points to. | |
| 652 * | |
| 653 * @param map the map | |
| 654 * @param key the key | |
| 655 * @param targetbuf the buffer where the element shall be copied to | |
| 656 * @return zero on success, non-zero if the key was not found | |
| 657 * | |
| 658 * @see cxMapStorePointers() | |
| 659 * @see cxMapRemove() | |
| 660 */ | |
| 661 cx_attr_nonnull | 478 cx_attr_nonnull |
| 662 cx_attr_access_w(3) | 479 cx_attr_access_w(3) |
| 663 cx_attr_cstr_arg(2) | 480 cx_attr_cstr_arg(2) |
| 664 static inline int cxMapRemoveAndGet( | 481 static inline int cxMapRemoveAndGet( |
| 665 CxMap *map, | 482 CxMap *map, |
| 670 } | 487 } |
| 671 | 488 |
| 672 #else // __cplusplus | 489 #else // __cplusplus |
| 673 | 490 |
| 674 /** | 491 /** |
| 675 * Puts a key/value-pair into the map. | 492 * @copydoc cxMapPut() |
| 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 */ | 493 */ |
| 682 cx_attr_nonnull | 494 cx_attr_nonnull |
| 683 static inline int cx_map_put( | 495 static inline int cx_map_put( |
| 684 CxMap *map, | 496 CxMap *map, |
| 685 CxHashKey key, | 497 CxHashKey key, |
| 687 ) { | 499 ) { |
| 688 return map->cl->put(map, key, value); | 500 return map->cl->put(map, key, value); |
| 689 } | 501 } |
| 690 | 502 |
| 691 /** | 503 /** |
| 692 * Puts a key/value-pair into the map. | 504 * @copydoc cxMapPut() |
| 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 */ | 505 */ |
| 699 cx_attr_nonnull | 506 cx_attr_nonnull |
| 700 static inline int cx_map_put_cxstr( | 507 static inline int cx_map_put_cxstr( |
| 701 CxMap *map, | 508 CxMap *map, |
| 702 cxstring key, | 509 cxstring key, |
| 704 ) { | 511 ) { |
| 705 return map->cl->put(map, cx_hash_key_cxstr(key), value); | 512 return map->cl->put(map, cx_hash_key_cxstr(key), value); |
| 706 } | 513 } |
| 707 | 514 |
| 708 /** | 515 /** |
| 709 * Puts a key/value-pair into the map. | 516 * @copydoc cxMapPut() |
| 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 */ | 517 */ |
| 716 cx_attr_nonnull | 518 cx_attr_nonnull |
| 717 static inline int cx_map_put_mustr( | 519 static inline int cx_map_put_mustr( |
| 718 CxMap *map, | 520 CxMap *map, |
| 719 cxmutstr key, | 521 cxmutstr key, |
| 721 ) { | 523 ) { |
| 722 return map->cl->put(map, cx_hash_key_cxstr(key), value); | 524 return map->cl->put(map, cx_hash_key_cxstr(key), value); |
| 723 } | 525 } |
| 724 | 526 |
| 725 /** | 527 /** |
| 726 * Puts a key/value-pair into the map. | 528 * @copydoc cxMapPut() |
| 727 * | |
| 728 * @param map the map | |
| 729 * @param key the key | |
| 730 * @param value the value | |
| 731 * @return 0 on success, non-zero value on failure | |
| 732 */ | 529 */ |
| 733 cx_attr_nonnull | 530 cx_attr_nonnull |
| 734 cx_attr_cstr_arg(2) | 531 cx_attr_cstr_arg(2) |
| 735 static inline int cx_map_put_str( | 532 static inline int cx_map_put_str( |
| 736 CxMap *map, | 533 CxMap *map, |
| 741 } | 538 } |
| 742 | 539 |
| 743 /** | 540 /** |
| 744 * Puts a key/value-pair into the map. | 541 * Puts a key/value-pair into the map. |
| 745 * | 542 * |
| 746 * @param map the map | 543 * A possible existing value will be overwritten. |
| 747 * @param key the key | 544 * |
| 748 * @param value the value | 545 * If this map is storing pointers, the @p value pointer is written |
| 749 * @return 0 on success, non-zero value on failure | 546 * to the map. Otherwise, the memory is copied from @p value with |
| 547 * memcpy(). | |
| 548 * | |
| 549 * The @p key is always copied. | |
| 550 * | |
| 551 * @param map (@c CxMap*) the map | |
| 552 * @param key (@c CxHashKey, @c char*, @c cxstring, or @c cxmutstr) the key | |
| 553 * @param value (@c void*) the value | |
| 554 * @retval zero success | |
| 555 * @retval non-zero value on memory allocation failure | |
| 750 */ | 556 */ |
| 751 #define cxMapPut(map, key, value) _Generic((key), \ | 557 #define cxMapPut(map, key, value) _Generic((key), \ |
| 752 CxHashKey: cx_map_put, \ | 558 CxHashKey: cx_map_put, \ |
| 753 cxstring: cx_map_put_cxstr, \ | 559 cxstring: cx_map_put_cxstr, \ |
| 754 cxmutstr: cx_map_put_mustr, \ | 560 cxmutstr: cx_map_put_mustr, \ |
| 755 char*: cx_map_put_str, \ | 561 char*: cx_map_put_str, \ |
| 756 const char*: cx_map_put_str) \ | 562 const char*: cx_map_put_str) \ |
| 757 (map, key, value) | 563 (map, key, value) |
| 758 | 564 |
| 759 /** | 565 /** |
| 760 * Retrieves a value by using a key. | 566 * @copydoc cxMapGet() |
| 761 * | |
| 762 * @param map the map | |
| 763 * @param key the key | |
| 764 * @return the value | |
| 765 */ | 567 */ |
| 766 cx_attr_nonnull | 568 cx_attr_nonnull |
| 767 cx_attr_nodiscard | 569 cx_attr_nodiscard |
| 768 static inline void *cx_map_get( | 570 static inline void *cx_map_get( |
| 769 const CxMap *map, | 571 const CxMap *map, |
| 771 ) { | 573 ) { |
| 772 return map->cl->get(map, key); | 574 return map->cl->get(map, key); |
| 773 } | 575 } |
| 774 | 576 |
| 775 /** | 577 /** |
| 776 * Retrieves a value by using a key. | 578 * @copydoc cxMapGet() |
| 777 * | |
| 778 * @param map the map | |
| 779 * @param key the key | |
| 780 * @return the value | |
| 781 */ | 579 */ |
| 782 cx_attr_nonnull | 580 cx_attr_nonnull |
| 783 cx_attr_nodiscard | 581 cx_attr_nodiscard |
| 784 static inline void *cx_map_get_cxstr( | 582 static inline void *cx_map_get_cxstr( |
| 785 const CxMap *map, | 583 const CxMap *map, |
| 787 ) { | 585 ) { |
| 788 return map->cl->get(map, cx_hash_key_cxstr(key)); | 586 return map->cl->get(map, cx_hash_key_cxstr(key)); |
| 789 } | 587 } |
| 790 | 588 |
| 791 /** | 589 /** |
| 792 * Retrieves a value by using a key. | 590 * @copydoc cxMapGet() |
| 793 * | |
| 794 * @param map the map | |
| 795 * @param key the key | |
| 796 * @return the value | |
| 797 */ | 591 */ |
| 798 cx_attr_nonnull | 592 cx_attr_nonnull |
| 799 cx_attr_nodiscard | 593 cx_attr_nodiscard |
| 800 static inline void *cx_map_get_mustr( | 594 static inline void *cx_map_get_mustr( |
| 801 const CxMap *map, | 595 const CxMap *map, |
| 803 ) { | 597 ) { |
| 804 return map->cl->get(map, cx_hash_key_cxstr(key)); | 598 return map->cl->get(map, cx_hash_key_cxstr(key)); |
| 805 } | 599 } |
| 806 | 600 |
| 807 /** | 601 /** |
| 808 * Retrieves a value by using a key. | 602 * @copydoc cxMapGet() |
| 809 * | |
| 810 * @param map the map | |
| 811 * @param key the key | |
| 812 * @return the value | |
| 813 */ | 603 */ |
| 814 cx_attr_nonnull | 604 cx_attr_nonnull |
| 815 cx_attr_nodiscard | 605 cx_attr_nodiscard |
| 816 cx_attr_cstr_arg(2) | 606 cx_attr_cstr_arg(2) |
| 817 static inline void *cx_map_get_str( | 607 static inline void *cx_map_get_str( |
| 822 } | 612 } |
| 823 | 613 |
| 824 /** | 614 /** |
| 825 * Retrieves a value by using a key. | 615 * Retrieves a value by using a key. |
| 826 * | 616 * |
| 827 * @param map the map | 617 * If this map is storing pointers, the stored pointer is returned. |
| 828 * @param key the key | 618 * Otherwise, a pointer to the element within the map's memory |
| 829 * @return the value | 619 * is returned (which is valid as long as the element stays in the map). |
| 620 * | |
| 621 * @param map (@c CxMap*) the map | |
| 622 * @param key (@c CxHashKey, @c char*, @c cxstring, or @c cxmutstr) the key | |
| 623 * @return (@c void*) the value | |
| 830 */ | 624 */ |
| 831 #define cxMapGet(map, key) _Generic((key), \ | 625 #define cxMapGet(map, key) _Generic((key), \ |
| 832 CxHashKey: cx_map_get, \ | 626 CxHashKey: cx_map_get, \ |
| 833 cxstring: cx_map_get_cxstr, \ | 627 cxstring: cx_map_get_cxstr, \ |
| 834 cxmutstr: cx_map_get_mustr, \ | 628 cxmutstr: cx_map_get_mustr, \ |
| 835 char*: cx_map_get_str, \ | 629 char*: cx_map_get_str, \ |
| 836 const char*: cx_map_get_str) \ | 630 const char*: cx_map_get_str) \ |
| 837 (map, key) | 631 (map, key) |
| 838 | 632 |
| 839 /** | 633 /** |
| 840 * Removes a key/value-pair from the map by using the key. | 634 * @copydoc cxMapRemove() |
| 841 * | |
| 842 * Always invokes the destructors functions, if any, on the removed element. | |
| 843 * | |
| 844 * @param map the map | |
| 845 * @param key the key | |
| 846 * @return zero on success, non-zero if the key was not found | |
| 847 */ | 635 */ |
| 848 cx_attr_nonnull | 636 cx_attr_nonnull |
| 849 static inline int cx_map_remove( | 637 static inline int cx_map_remove( |
| 850 CxMap *map, | 638 CxMap *map, |
| 851 CxHashKey key | 639 CxHashKey key |
| 852 ) { | 640 ) { |
| 853 return map->cl->remove(map, key, NULL); | 641 return map->cl->remove(map, key, NULL); |
| 854 } | 642 } |
| 855 | 643 |
| 856 /** | 644 /** |
| 857 * Removes a key/value-pair from the map by using the key. | 645 * @copydoc cxMapRemove() |
| 858 * | |
| 859 * Always invokes the destructors functions, if any, on the removed element. | |
| 860 * | |
| 861 * @param map the map | |
| 862 * @param key the key | |
| 863 * @return zero on success, non-zero if the key was not found | |
| 864 */ | 646 */ |
| 865 cx_attr_nonnull | 647 cx_attr_nonnull |
| 866 static inline int cx_map_remove_cxstr( | 648 static inline int cx_map_remove_cxstr( |
| 867 CxMap *map, | 649 CxMap *map, |
| 868 cxstring key | 650 cxstring key |
| 869 ) { | 651 ) { |
| 870 return map->cl->remove(map, cx_hash_key_cxstr(key), NULL); | 652 return map->cl->remove(map, cx_hash_key_cxstr(key), NULL); |
| 871 } | 653 } |
| 872 | 654 |
| 873 /** | 655 /** |
| 874 * Removes a key/value-pair from the map by using the key. | 656 * @copydoc cxMapRemove() |
| 875 * | |
| 876 * Always invokes the destructors functions, if any, on the removed element. | |
| 877 * | |
| 878 * @param map the map | |
| 879 * @param key the key | |
| 880 * @return zero on success, non-zero if the key was not found | |
| 881 */ | 657 */ |
| 882 cx_attr_nonnull | 658 cx_attr_nonnull |
| 883 static inline int cx_map_remove_mustr( | 659 static inline int cx_map_remove_mustr( |
| 884 CxMap *map, | 660 CxMap *map, |
| 885 cxmutstr key | 661 cxmutstr key |
| 886 ) { | 662 ) { |
| 887 return map->cl->remove(map, cx_hash_key_cxstr(key), NULL); | 663 return map->cl->remove(map, cx_hash_key_cxstr(key), NULL); |
| 888 } | 664 } |
| 889 | 665 |
| 890 /** | 666 /** |
| 891 * Removes a key/value-pair from the map by using the key. | 667 * @copydoc cxMapRemove() |
| 892 * | |
| 893 * Always invokes the destructors functions, if any, on the removed element. | |
| 894 * | |
| 895 * @param map the map | |
| 896 * @param key the key | |
| 897 * @return zero on success, non-zero if the key was not found | |
| 898 */ | 668 */ |
| 899 cx_attr_nonnull | 669 cx_attr_nonnull |
| 900 cx_attr_cstr_arg(2) | 670 cx_attr_cstr_arg(2) |
| 901 static inline int cx_map_remove_str( | 671 static inline int cx_map_remove_str( |
| 902 CxMap *map, | 672 CxMap *map, |
| 908 /** | 678 /** |
| 909 * Removes a key/value-pair from the map by using the key. | 679 * Removes a key/value-pair from the map by using the key. |
| 910 * | 680 * |
| 911 * Always invokes the destructors functions, if any, on the removed element. | 681 * Always invokes the destructors functions, if any, on the removed element. |
| 912 * | 682 * |
| 913 * @param map the map | 683 * @param map (@c CxMap*) the map |
| 914 * @param key the key | 684 * @param key (@c CxHashKey, @c char*, @c cxstring, or @c cxmutstr) the key |
| 915 * @return zero on success, non-zero if the key was not found | 685 * @retval zero success |
| 686 * @retval non-zero the key was not found | |
| 916 * | 687 * |
| 917 * @see cxMapRemoveAndGet() | 688 * @see cxMapRemoveAndGet() |
| 918 */ | 689 */ |
| 919 #define cxMapRemove(map, key) _Generic((key), \ | 690 #define cxMapRemove(map, key) _Generic((key), \ |
| 920 CxHashKey: cx_map_remove, \ | 691 CxHashKey: cx_map_remove, \ |
| 923 char*: cx_map_remove_str, \ | 694 char*: cx_map_remove_str, \ |
| 924 const char*: cx_map_remove_str) \ | 695 const char*: cx_map_remove_str) \ |
| 925 (map, key) | 696 (map, key) |
| 926 | 697 |
| 927 /** | 698 /** |
| 928 * Removes a key/value-pair from the map by using the key. | 699 * @copydoc cxMapRemoveAndGet() |
| 929 * | |
| 930 * This function will copy the contents to the target buffer | |
| 931 * which must be guaranteed to be large enough to hold the element. | |
| 932 * The destructor functions, if any, will \em not be called. | |
| 933 * | |
| 934 * If this map is storing pointers, the element is the pointer itself | |
| 935 * and not the object it points to. | |
| 936 * | |
| 937 * @param map the map | |
| 938 * @param key the key | |
| 939 * @param targetbuf the buffer where the element shall be copied to | |
| 940 * @return zero on success, non-zero if the key was not found | |
| 941 */ | 700 */ |
| 942 cx_attr_nonnull | 701 cx_attr_nonnull |
| 943 cx_attr_access_w(3) | 702 cx_attr_access_w(3) |
| 944 static inline int cx_map_remove_and_get( | 703 static inline int cx_map_remove_and_get( |
| 945 CxMap *map, | 704 CxMap *map, |
| 948 ) { | 707 ) { |
| 949 return map->cl->remove(map, key, targetbuf); | 708 return map->cl->remove(map, key, targetbuf); |
| 950 } | 709 } |
| 951 | 710 |
| 952 /** | 711 /** |
| 953 * Removes a key/value-pair from the map by using the key. | 712 * @copydoc cxMapRemoveAndGet() |
| 954 * | |
| 955 * This function will copy the contents to the target buffer | |
| 956 * which must be guaranteed to be large enough to hold the element. | |
| 957 * The destructor functions, if any, will \em not be called. | |
| 958 * | |
| 959 * If this map is storing pointers, the element is the pointer itself | |
| 960 * and not the object it points to. | |
| 961 * | |
| 962 * @param map the map | |
| 963 * @param key the key | |
| 964 * @param targetbuf the buffer where the element shall be copied to | |
| 965 * @return zero on success, non-zero if the key was not found | |
| 966 */ | 713 */ |
| 967 cx_attr_nonnull | 714 cx_attr_nonnull |
| 968 cx_attr_access_w(3) | 715 cx_attr_access_w(3) |
| 969 static inline int cx_map_remove_and_get_cxstr( | 716 static inline int cx_map_remove_and_get_cxstr( |
| 970 CxMap *map, | 717 CxMap *map, |
| 973 ) { | 720 ) { |
| 974 return map->cl->remove(map, cx_hash_key_cxstr(key), targetbuf); | 721 return map->cl->remove(map, cx_hash_key_cxstr(key), targetbuf); |
| 975 } | 722 } |
| 976 | 723 |
| 977 /** | 724 /** |
| 978 * Removes a key/value-pair from the map by using the key. | 725 * @copydoc cxMapRemoveAndGet() |
| 979 * | |
| 980 * This function will copy the contents to the target buffer | |
| 981 * which must be guaranteed to be large enough to hold the element. | |
| 982 * The destructor functions, if any, will \em not be called. | |
| 983 * | |
| 984 * If this map is storing pointers, the element is the pointer itself | |
| 985 * and not the object it points to. | |
| 986 * | |
| 987 * @param map the map | |
| 988 * @param key the key | |
| 989 * @param targetbuf the buffer where the element shall be copied to | |
| 990 * @return zero on success, non-zero if the key was not found | |
| 991 */ | 726 */ |
| 992 cx_attr_nonnull | 727 cx_attr_nonnull |
| 993 cx_attr_access_w(3) | 728 cx_attr_access_w(3) |
| 994 static inline int cx_map_remove_and_get_mustr( | 729 static inline int cx_map_remove_and_get_mustr( |
| 995 CxMap *map, | 730 CxMap *map, |
| 998 ) { | 733 ) { |
| 999 return map->cl->remove(map, cx_hash_key_cxstr(key), targetbuf); | 734 return map->cl->remove(map, cx_hash_key_cxstr(key), targetbuf); |
| 1000 } | 735 } |
| 1001 | 736 |
| 1002 /** | 737 /** |
| 1003 * Removes a key/value-pair from the map by using the key. | 738 * @copydoc cxMapRemoveAndGet() |
| 1004 * | |
| 1005 * This function will copy the contents to the target buffer | |
| 1006 * which must be guaranteed to be large enough to hold the element. | |
| 1007 * The destructor functions, if any, will \em not be called. | |
| 1008 * | |
| 1009 * If this map is storing pointers, the element is the pointer itself | |
| 1010 * and not the object it points to. | |
| 1011 * | |
| 1012 * @param map the map | |
| 1013 * @param key the key | |
| 1014 * @param targetbuf the buffer where the element shall be copied to | |
| 1015 * @return zero on success, non-zero if the key was not found | |
| 1016 */ | 739 */ |
| 1017 cx_attr_nonnull | 740 cx_attr_nonnull |
| 1018 cx_attr_access_w(3) | 741 cx_attr_access_w(3) |
| 1019 cx_attr_cstr_arg(2) | 742 cx_attr_cstr_arg(2) |
| 1020 static inline int cx_map_remove_and_get_str( | 743 static inline int cx_map_remove_and_get_str( |
| 1026 } | 749 } |
| 1027 | 750 |
| 1028 /** | 751 /** |
| 1029 * Removes a key/value-pair from the map by using the key. | 752 * Removes a key/value-pair from the map by using the key. |
| 1030 * | 753 * |
| 1031 * This function will copy the contents to the target buffer | 754 * This function will copy the contents of the removed element |
| 1032 * which must be guaranteed to be large enough to hold the element. | 755 * to the target buffer must be guaranteed to be large enough |
| 1033 * The destructor functions, if any, will \em not be called. | 756 * to hold the element (the map's element size). |
| 757 * The destructor functions, if any, will @em not be called. | |
| 1034 * | 758 * |
| 1035 * If this map is storing pointers, the element is the pointer itself | 759 * If this map is storing pointers, the element is the pointer itself |
| 1036 * and not the object it points to. | 760 * and not the object it points to. |
| 1037 * | 761 * |
| 1038 * @param map the map | 762 * @param map (@c CxMap*) the map |
| 1039 * @param key the key | 763 * @param key (@c CxHashKey, @c char*, @c cxstring, or @c cxmutstr) the key |
| 1040 * @param targetbuf the buffer where the element shall be copied to | 764 * @param targetbuf (@c void*) the buffer where the element shall be copied to |
| 1041 * @return zero on success, non-zero if the key was not found | 765 * @retval zero success |
| 766 * @retval non-zero the key was not found | |
| 1042 * | 767 * |
| 1043 * @see cxMapStorePointers() | 768 * @see cxMapStorePointers() |
| 1044 * @see cxMapRemove() | 769 * @see cxMapRemove() |
| 1045 */ | 770 */ |
| 1046 #define cxMapRemoveAndGet(map, key, targetbuf) _Generic((key), \ | 771 #define cxMapRemoveAndGet(map, key, targetbuf) _Generic((key), \ |