| 228 /** |
213 /** |
| 229 * A shared instance of an empty map. |
214 * A shared instance of an empty map. |
| 230 * |
215 * |
| 231 * Writing to that map is not allowed. |
216 * Writing to that map is not allowed. |
| 232 * |
217 * |
| 233 * You can use this is a placeholder for initializing CxMap pointers |
218 * You can use this as a placeholder for initializing CxMap pointers |
| 234 * for which you do not want to reserve memory right from the beginning. |
219 * for which you do not want to reserve memory right from the beginning. |
| 235 */ |
220 */ |
| 236 cx_attr_export |
221 CX_EXPORT extern CxMap *const cxEmptyMap; |
| 237 extern CxMap *const cxEmptyMap; |
|
| 238 |
222 |
| 239 /** |
223 /** |
| 240 * Deallocates the memory of the specified map. |
224 * Deallocates the memory of the specified map. |
| 241 * |
225 * |
| 242 * Also calls the content destructor functions for each element, if specified. |
226 * Also calls the content destructor functions for each element, if specified. |
| 243 * |
227 * |
| 244 * @param map the map to be freed |
228 * @param map the map to be freed |
| 245 */ |
229 */ |
| 246 cx_attr_export |
230 CX_EXPORT void cxMapFree(CxMap *map); |
| 247 void cxMapFree(CxMap *map); |
|
| 248 |
231 |
| 249 |
232 |
| 250 /** |
233 /** |
| 251 * Clears a map by removing all elements. |
234 * Clears a map by removing all elements. |
| 252 * |
235 * |
| 253 * Also calls the content destructor functions for each element, if specified. |
236 * Also calls the content destructor functions for each element, if specified. |
| 254 * |
237 * |
| 255 * @param map the map to be cleared |
238 * @param map the map to be cleared |
| 256 */ |
239 */ |
| 257 cx_attr_nonnull |
240 cx_attr_nonnull |
| 258 static inline void cxMapClear(CxMap *map) { |
241 CX_EXPORT void cxMapClear(CxMap *map); |
| 259 map->cl->clear(map); |
|
| 260 } |
|
| 261 |
242 |
| 262 /** |
243 /** |
| 263 * Returns the number of elements in this map. |
244 * Returns the number of elements in this map. |
| 264 * |
245 * |
| 265 * @param map the map |
246 * @param map the map |
| 266 * @return the number of stored elements |
247 * @return the number of stored elements |
| 267 */ |
248 */ |
| 268 cx_attr_nonnull |
249 cx_attr_nonnull |
| 269 static inline size_t cxMapSize(const CxMap *map) { |
250 CX_EXPORT size_t cxMapSize(const CxMap *map); |
| 270 return map->collection.size; |
|
| 271 } |
|
| 272 |
251 |
| 273 /** |
252 /** |
| 274 * Creates a value iterator for a map. |
253 * Creates a value iterator for a map. |
| 275 * |
254 * |
| 276 * When the map is storing pointers, those pointers are returned. |
255 * When the map is storing pointers, those pointers are returned. |
| 282 * |
261 * |
| 283 * @param map the map to create the iterator for (can be @c NULL) |
262 * @param map the map to create the iterator for (can be @c NULL) |
| 284 * @return an iterator for the currently stored values |
263 * @return an iterator for the currently stored values |
| 285 */ |
264 */ |
| 286 cx_attr_nodiscard |
265 cx_attr_nodiscard |
| 287 static inline CxMapIterator cxMapIteratorValues(const CxMap *map) { |
266 CX_EXPORT CxMapIterator cxMapIteratorValues(const CxMap *map); |
| 288 if (map == NULL) map = cxEmptyMap; |
|
| 289 return map->cl->iterator(map, CX_MAP_ITERATOR_VALUES); |
|
| 290 } |
|
| 291 |
267 |
| 292 /** |
268 /** |
| 293 * Creates a key iterator for a map. |
269 * Creates a key iterator for a map. |
| 294 * |
270 * |
| 295 * The elements of the iterator are keys of type CxHashKey and the pointer returned |
271 * The elements of the iterator are keys of type CxHashKey, and the pointer returned |
| 296 * during iterator shall be treated as @c const @c CxHashKey* . |
272 * during iterator shall be treated as @c const @c CxHashKey* . |
| 297 * |
273 * |
| 298 * @note An iterator iterates over all elements successively. Therefore, the order |
274 * @note An iterator iterates over all elements successively. Therefore, the order |
| 299 * highly depends on the map implementation and may change arbitrarily when the contents change. |
275 * highly depends on the map implementation and may change arbitrarily when the contents change. |
| 300 * |
276 * |
| 301 * @param map the map to create the iterator for (can be @c NULL) |
277 * @param map the map to create the iterator for (can be @c NULL) |
| 302 * @return an iterator for the currently stored keys |
278 * @return an iterator for the currently stored keys |
| 303 */ |
279 */ |
| 304 cx_attr_nodiscard |
280 cx_attr_nodiscard |
| 305 static inline CxMapIterator cxMapIteratorKeys(const CxMap *map) { |
281 CX_EXPORT CxMapIterator cxMapIteratorKeys(const CxMap *map); |
| 306 if (map == NULL) map = cxEmptyMap; |
|
| 307 return map->cl->iterator(map, CX_MAP_ITERATOR_KEYS); |
|
| 308 } |
|
| 309 |
282 |
| 310 /** |
283 /** |
| 311 * Creates an iterator for a map. |
284 * Creates an iterator for a map. |
| 312 * |
285 * |
| 313 * The elements of the iterator are key/value pairs of type CxMapEntry and the pointer returned |
286 * The elements of the iterator are key/value pairs of type CxMapEntry, and the pointer returned |
| 314 * during iterator shall be treated as @c const @c CxMapEntry* . |
287 * during iterator shall be treated as @c const @c CxMapEntry* . |
| 315 * |
288 * |
| 316 * @note An iterator iterates over all elements successively. Therefore, the order |
289 * @note An iterator iterates over all elements successively. Therefore, the order |
| 317 * highly depends on the map implementation and may change arbitrarily when the contents change. |
290 * highly depends on the map implementation and may change arbitrarily when the contents change. |
| 318 * |
291 * |
| 320 * @return an iterator for the currently stored entries |
293 * @return an iterator for the currently stored entries |
| 321 * @see cxMapIteratorKeys() |
294 * @see cxMapIteratorKeys() |
| 322 * @see cxMapIteratorValues() |
295 * @see cxMapIteratorValues() |
| 323 */ |
296 */ |
| 324 cx_attr_nodiscard |
297 cx_attr_nodiscard |
| 325 static inline CxMapIterator cxMapIterator(const CxMap *map) { |
298 CX_EXPORT CxMapIterator cxMapIterator(const CxMap *map); |
| 326 if (map == NULL) map = cxEmptyMap; |
|
| 327 return map->cl->iterator(map, CX_MAP_ITERATOR_PAIRS); |
|
| 328 } |
|
| 329 |
|
| 330 |
|
| 331 /** |
|
| 332 * Creates a mutating iterator over the values of a map. |
|
| 333 * |
|
| 334 * When the map is storing pointers, those pointers are returned. |
|
| 335 * Otherwise, the iterator iterates over pointers to the memory within the map where the |
|
| 336 * respective elements are stored. |
|
| 337 * |
|
| 338 * @note An iterator iterates over all elements successively. Therefore, the order |
|
| 339 * highly depends on the map implementation and may change arbitrarily when the contents change. |
|
| 340 * |
|
| 341 * @param map the map to create the iterator for (can be @c NULL) |
|
| 342 * @return an iterator for the currently stored values |
|
| 343 */ |
|
| 344 cx_attr_nodiscard |
|
| 345 cx_attr_export |
|
| 346 CxMapIterator cxMapMutIteratorValues(CxMap *map); |
|
| 347 |
|
| 348 /** |
|
| 349 * Creates a mutating iterator over the keys of a map. |
|
| 350 * |
|
| 351 * The elements of the iterator are keys of type CxHashKey and the pointer returned |
|
| 352 * during iterator shall be treated as @c const @c CxHashKey* . |
|
| 353 * |
|
| 354 * @note An iterator iterates over all elements successively. Therefore, the order |
|
| 355 * highly depends on the map implementation and may change arbitrarily when the contents change. |
|
| 356 * |
|
| 357 * @param map the map to create the iterator for (can be @c NULL) |
|
| 358 * @return an iterator for the currently stored keys |
|
| 359 */ |
|
| 360 cx_attr_nodiscard |
|
| 361 cx_attr_export |
|
| 362 CxMapIterator cxMapMutIteratorKeys(CxMap *map); |
|
| 363 |
|
| 364 /** |
|
| 365 * Creates a mutating iterator for a map. |
|
| 366 * |
|
| 367 * The elements of the iterator are key/value pairs of type CxMapEntry and the pointer returned |
|
| 368 * during iterator shall be treated as @c const @c CxMapEntry* . |
|
| 369 * |
|
| 370 * @note An iterator iterates over all elements successively. Therefore, the order |
|
| 371 * highly depends on the map implementation and may change arbitrarily when the contents change. |
|
| 372 * |
|
| 373 * @param map the map to create the iterator for (can be @c NULL) |
|
| 374 * @return an iterator for the currently stored entries |
|
| 375 * @see cxMapMutIteratorKeys() |
|
| 376 * @see cxMapMutIteratorValues() |
|
| 377 */ |
|
| 378 cx_attr_nodiscard |
|
| 379 cx_attr_export |
|
| 380 CxMapIterator cxMapMutIterator(CxMap *map); |
|
| 381 |
|
| 382 #ifdef __cplusplus |
|
| 383 } // end the extern "C" block here, because we want to start overloading |
|
| 384 cx_attr_nonnull |
|
| 385 static inline int cxMapPut( |
|
| 386 CxMap *map, |
|
| 387 CxHashKey const &key, |
|
| 388 void *value |
|
| 389 ) { |
|
| 390 return map->cl->put(map, key, value) == NULL; |
|
| 391 } |
|
| 392 |
|
| 393 cx_attr_nonnull |
|
| 394 static inline int cxMapPut( |
|
| 395 CxMap *map, |
|
| 396 cxstring const &key, |
|
| 397 void *value |
|
| 398 ) { |
|
| 399 return map->cl->put(map, cx_hash_key_cxstr(key), value) == NULL; |
|
| 400 } |
|
| 401 |
|
| 402 cx_attr_nonnull |
|
| 403 static inline int cxMapPut( |
|
| 404 CxMap *map, |
|
| 405 cxmutstr const &key, |
|
| 406 void *value |
|
| 407 ) { |
|
| 408 return map->cl->put(map, cx_hash_key_cxstr(key), value) == NULL; |
|
| 409 } |
|
| 410 |
|
| 411 cx_attr_nonnull |
|
| 412 cx_attr_cstr_arg(2) |
|
| 413 static inline int cxMapPut( |
|
| 414 CxMap *map, |
|
| 415 const char *key, |
|
| 416 void *value |
|
| 417 ) { |
|
| 418 return map->cl->put(map, cx_hash_key_str(key), value) == NULL; |
|
| 419 } |
|
| 420 |
|
| 421 cx_attr_nonnull |
|
| 422 static inline void *cxMapEmplace( |
|
| 423 CxMap *map, |
|
| 424 CxHashKey const &key |
|
| 425 ) { |
|
| 426 return map->cl->put(map, key, NULL); |
|
| 427 } |
|
| 428 |
|
| 429 cx_attr_nonnull |
|
| 430 static inline void *cxMapEmplace( |
|
| 431 CxMap *map, |
|
| 432 cxstring const &key |
|
| 433 ) { |
|
| 434 return map->cl->put(map, cx_hash_key_cxstr(key), NULL); |
|
| 435 } |
|
| 436 |
|
| 437 cx_attr_nonnull |
|
| 438 static inline void *cxMapEmplace( |
|
| 439 CxMap *map, |
|
| 440 cxmutstr const &key |
|
| 441 ) { |
|
| 442 return map->cl->put(map, cx_hash_key_cxstr(key), NULL); |
|
| 443 } |
|
| 444 |
|
| 445 cx_attr_nonnull |
|
| 446 cx_attr_cstr_arg(2) |
|
| 447 static inline void *cxMapEmplace( |
|
| 448 CxMap *map, |
|
| 449 const char *key |
|
| 450 ) { |
|
| 451 return map->cl->put(map, cx_hash_key_str(key), NULL); |
|
| 452 } |
|
| 453 |
|
| 454 cx_attr_nonnull |
|
| 455 cx_attr_nodiscard |
|
| 456 static inline void *cxMapGet( |
|
| 457 const CxMap *map, |
|
| 458 CxHashKey const &key |
|
| 459 ) { |
|
| 460 return map->cl->get(map, key); |
|
| 461 } |
|
| 462 |
|
| 463 cx_attr_nonnull |
|
| 464 cx_attr_nodiscard |
|
| 465 static inline void *cxMapGet( |
|
| 466 const CxMap *map, |
|
| 467 cxstring const &key |
|
| 468 ) { |
|
| 469 return map->cl->get(map, cx_hash_key_cxstr(key)); |
|
| 470 } |
|
| 471 |
|
| 472 cx_attr_nonnull |
|
| 473 cx_attr_nodiscard |
|
| 474 static inline void *cxMapGet( |
|
| 475 const CxMap *map, |
|
| 476 cxmutstr const &key |
|
| 477 ) { |
|
| 478 return map->cl->get(map, cx_hash_key_cxstr(key)); |
|
| 479 } |
|
| 480 |
|
| 481 cx_attr_nonnull |
|
| 482 cx_attr_nodiscard |
|
| 483 cx_attr_cstr_arg(2) |
|
| 484 static inline void *cxMapGet( |
|
| 485 const CxMap *map, |
|
| 486 const char *key |
|
| 487 ) { |
|
| 488 return map->cl->get(map, cx_hash_key_str(key)); |
|
| 489 } |
|
| 490 |
|
| 491 cx_attr_nonnull |
|
| 492 static inline int cxMapRemove( |
|
| 493 CxMap *map, |
|
| 494 CxHashKey const &key |
|
| 495 ) { |
|
| 496 return map->cl->remove(map, key, nullptr); |
|
| 497 } |
|
| 498 |
|
| 499 cx_attr_nonnull |
|
| 500 static inline int cxMapRemove( |
|
| 501 CxMap *map, |
|
| 502 cxstring const &key |
|
| 503 ) { |
|
| 504 return map->cl->remove(map, cx_hash_key_cxstr(key), nullptr); |
|
| 505 } |
|
| 506 |
|
| 507 cx_attr_nonnull |
|
| 508 static inline int cxMapRemove( |
|
| 509 CxMap *map, |
|
| 510 cxmutstr const &key |
|
| 511 ) { |
|
| 512 return map->cl->remove(map, cx_hash_key_cxstr(key), nullptr); |
|
| 513 } |
|
| 514 |
|
| 515 cx_attr_nonnull |
|
| 516 cx_attr_cstr_arg(2) |
|
| 517 static inline int cxMapRemove( |
|
| 518 CxMap *map, |
|
| 519 const char *key |
|
| 520 ) { |
|
| 521 return map->cl->remove(map, cx_hash_key_str(key), nullptr); |
|
| 522 } |
|
| 523 |
|
| 524 cx_attr_nonnull |
|
| 525 cx_attr_access_w(3) |
|
| 526 static inline int cxMapRemoveAndGet( |
|
| 527 CxMap *map, |
|
| 528 CxHashKey key, |
|
| 529 void *targetbuf |
|
| 530 ) { |
|
| 531 return map->cl->remove(map, key, targetbuf); |
|
| 532 } |
|
| 533 |
|
| 534 cx_attr_nonnull |
|
| 535 cx_attr_access_w(3) |
|
| 536 static inline int cxMapRemoveAndGet( |
|
| 537 CxMap *map, |
|
| 538 cxstring key, |
|
| 539 void *targetbuf |
|
| 540 ) { |
|
| 541 return map->cl->remove(map, cx_hash_key_cxstr(key), targetbuf); |
|
| 542 } |
|
| 543 |
|
| 544 cx_attr_nonnull |
|
| 545 cx_attr_access_w(3) |
|
| 546 static inline int cxMapRemoveAndGet( |
|
| 547 CxMap *map, |
|
| 548 cxmutstr key, |
|
| 549 void *targetbuf |
|
| 550 ) { |
|
| 551 return map->cl->remove(map, cx_hash_key_cxstr(key), targetbuf); |
|
| 552 } |
|
| 553 |
|
| 554 cx_attr_nonnull |
|
| 555 cx_attr_access_w(3) |
|
| 556 cx_attr_cstr_arg(2) |
|
| 557 static inline int cxMapRemoveAndGet( |
|
| 558 CxMap *map, |
|
| 559 const char *key, |
|
| 560 void *targetbuf |
|
| 561 ) { |
|
| 562 return map->cl->remove(map, cx_hash_key_str(key), targetbuf); |
|
| 563 } |
|
| 564 |
|
| 565 #else // __cplusplus |
|
| 566 |
|
| 567 /** |
|
| 568 * @copydoc cxMapPut() |
|
| 569 */ |
|
| 570 cx_attr_nonnull |
|
| 571 static inline int cx_map_put( |
|
| 572 CxMap *map, |
|
| 573 CxHashKey key, |
|
| 574 void *value |
|
| 575 ) { |
|
| 576 return map->cl->put(map, key, value) == NULL; |
|
| 577 } |
|
| 578 |
|
| 579 /** |
|
| 580 * @copydoc cxMapPut() |
|
| 581 */ |
|
| 582 cx_attr_nonnull |
|
| 583 static inline int cx_map_put_cxstr( |
|
| 584 CxMap *map, |
|
| 585 cxstring key, |
|
| 586 void *value |
|
| 587 ) { |
|
| 588 return map->cl->put(map, cx_hash_key_cxstr(key), value) == NULL; |
|
| 589 } |
|
| 590 |
|
| 591 /** |
|
| 592 * @copydoc cxMapPut() |
|
| 593 */ |
|
| 594 cx_attr_nonnull |
|
| 595 static inline int cx_map_put_mustr( |
|
| 596 CxMap *map, |
|
| 597 cxmutstr key, |
|
| 598 void *value |
|
| 599 ) { |
|
| 600 return map->cl->put(map, cx_hash_key_cxstr(key), value) == NULL; |
|
| 601 } |
|
| 602 |
|
| 603 /** |
|
| 604 * @copydoc cxMapPut() |
|
| 605 */ |
|
| 606 cx_attr_nonnull |
|
| 607 cx_attr_cstr_arg(2) |
|
| 608 static inline int cx_map_put_str( |
|
| 609 CxMap *map, |
|
| 610 const char *key, |
|
| 611 void *value |
|
| 612 ) { |
|
| 613 return map->cl->put(map, cx_hash_key_str(key), value) == NULL; |
|
| 614 } |
|
| 615 |
299 |
| 616 /** |
300 /** |
| 617 * Puts a key/value-pair into the map. |
301 * Puts a key/value-pair into the map. |
| 618 * |
302 * |
| 619 * A possible existing value will be overwritten. |
303 * A possible existing value will be overwritten. |
| 624 * to the map. Otherwise, the memory is copied from @p value with |
308 * to the map. Otherwise, the memory is copied from @p value with |
| 625 * memcpy(). |
309 * memcpy(). |
| 626 * |
310 * |
| 627 * The @p key is always copied. |
311 * The @p key is always copied. |
| 628 * |
312 * |
| |
313 * @param map the map |
| |
314 * @param key the key |
| |
315 * @param value the value |
| |
316 * @retval zero success |
| |
317 * @retval non-zero value on memory allocation failure |
| |
318 * @see cxMapPut() |
| |
319 */ |
| |
320 cx_attr_nonnull |
| |
321 CX_EXPORT int cx_map_put(CxMap *map, CxHashKey key, void *value); |
| |
322 |
| |
323 /** |
| |
324 * Puts a key/value-pair into the map. |
| |
325 * |
| |
326 * A possible existing value will be overwritten. |
| |
327 * If destructor functions are specified, they are called for |
| |
328 * the overwritten element. |
| |
329 * |
| |
330 * If this map is storing pointers, the @p value pointer is written |
| |
331 * to the map. Otherwise, the memory is copied from @p value with |
| |
332 * memcpy(). |
| |
333 * |
| |
334 * The @p key is always copied. |
| |
335 * |
| 629 * @param map (@c CxMap*) the map |
336 * @param map (@c CxMap*) the map |
| 630 * @param key (@c CxHashKey, @c char*, @c cxstring, or @c cxmutstr) the key |
337 * @param key (any supported key type) the key |
| 631 * @param value (@c void*) the value |
338 * @param value (@c void*) the value |
| 632 * @retval zero success |
339 * @retval zero success |
| 633 * @retval non-zero value on memory allocation failure |
340 * @retval non-zero value on memory allocation failure |
| 634 */ |
341 * @see CX_HASH_KEY() |
| 635 #define cxMapPut(map, key, value) _Generic((key), \ |
342 */ |
| 636 CxHashKey: cx_map_put, \ |
343 #define cxMapPut(map, key, value) cx_map_put(map, CX_HASH_KEY(key), value) |
| 637 cxstring: cx_map_put_cxstr, \ |
|
| 638 cxmutstr: cx_map_put_mustr, \ |
|
| 639 char*: cx_map_put_str, \ |
|
| 640 const char*: cx_map_put_str) \ |
|
| 641 (map, key, value) |
|
| 642 |
|
| 643 /** |
|
| 644 * @copydoc cxMapEmplace() |
|
| 645 */ |
|
| 646 cx_attr_nonnull |
|
| 647 static inline void *cx_map_emplace( |
|
| 648 CxMap *map, |
|
| 649 CxHashKey key |
|
| 650 ) { |
|
| 651 return map->cl->put(map, key, NULL); |
|
| 652 } |
|
| 653 |
|
| 654 /** |
|
| 655 * @copydoc cxMapEmplace() |
|
| 656 */ |
|
| 657 cx_attr_nonnull |
|
| 658 static inline void *cx_map_emplace_cxstr( |
|
| 659 CxMap *map, |
|
| 660 cxstring key |
|
| 661 ) { |
|
| 662 return map->cl->put(map, cx_hash_key_cxstr(key), NULL); |
|
| 663 } |
|
| 664 |
|
| 665 /** |
|
| 666 * @copydoc cxMapEmplace() |
|
| 667 */ |
|
| 668 cx_attr_nonnull |
|
| 669 static inline void *cx_map_emplace_mustr( |
|
| 670 CxMap *map, |
|
| 671 cxmutstr key |
|
| 672 ) { |
|
| 673 return map->cl->put(map, cx_hash_key_cxstr(key), NULL); |
|
| 674 } |
|
| 675 |
|
| 676 /** |
|
| 677 * @copydoc cxMapEmplace() |
|
| 678 */ |
|
| 679 cx_attr_nonnull |
|
| 680 cx_attr_cstr_arg(2) |
|
| 681 static inline void *cx_map_emplace_str( |
|
| 682 CxMap *map, |
|
| 683 const char *key |
|
| 684 ) { |
|
| 685 return map->cl->put(map, cx_hash_key_str(key), NULL); |
|
| 686 } |
|
| 687 |
344 |
| 688 /** |
345 /** |
| 689 * Allocates memory for a value in the map associated with the specified key. |
346 * Allocates memory for a value in the map associated with the specified key. |
| 690 * |
347 * |
| 691 * A possible existing value will be overwritten. |
348 * A possible existing value will be overwritten. |
| 695 * If the map is storing pointers, this function returns a @c void** pointer, |
352 * If the map is storing pointers, this function returns a @c void** pointer, |
| 696 * meaning a pointer to that pointer. |
353 * meaning a pointer to that pointer. |
| 697 * |
354 * |
| 698 * The @p key is always copied. |
355 * The @p key is always copied. |
| 699 * |
356 * |
| 700 * @param map (@c CxMap*) the map |
357 * @param map the map |
| 701 * @param key (@c CxHashKey, @c char*, @c cxstring, or @c cxmutstr) the key |
358 * @param key the key |
| 702 * @return the pointer to the allocated memory or @c NULL if allocation fails |
359 * @return the pointer to the allocated memory or @c NULL if allocation fails |
| 703 * @retval zero success |
360 * @retval zero success |
| 704 * @retval non-zero value on memory allocation failure |
361 * @retval non-zero value on memory allocation failure |
| 705 */ |
362 * @see cxMapEmplace() |
| 706 #define cxMapEmplace(map, key) _Generic((key), \ |
|
| 707 CxHashKey: cx_map_emplace, \ |
|
| 708 cxstring: cx_map_emplace_cxstr, \ |
|
| 709 cxmutstr: cx_map_emplace_mustr, \ |
|
| 710 char*: cx_map_emplace_str, \ |
|
| 711 const char*: cx_map_emplace_str) \ |
|
| 712 (map, key) |
|
| 713 |
|
| 714 /** |
|
| 715 * @copydoc cxMapGet() |
|
| 716 */ |
363 */ |
| 717 cx_attr_nonnull |
364 cx_attr_nonnull |
| 718 cx_attr_nodiscard |
365 CX_EXPORT void *cx_map_emplace(CxMap *map, CxHashKey key); |
| 719 static inline void *cx_map_get( |
366 |
| 720 const CxMap *map, |
367 /** |
| 721 CxHashKey key |
368 * Allocates memory for a value in the map associated with the specified key. |
| 722 ) { |
369 * |
| 723 return map->cl->get(map, key); |
370 * A possible existing value will be overwritten. |
| 724 } |
371 * If destructor functions are specified, they are called for |
| 725 |
372 * the overwritten element. |
| 726 /** |
373 * |
| 727 * @copydoc cxMapGet() |
374 * If the map is storing pointers, this function returns a @c void** pointer, |
| 728 */ |
375 * meaning a pointer to that pointer. |
| 729 cx_attr_nonnull |
376 * |
| 730 cx_attr_nodiscard |
377 * The @p key is always copied. |
| 731 static inline void *cx_map_get_cxstr( |
378 * |
| 732 const CxMap *map, |
379 * @param map (@c CxMap*) the map |
| 733 cxstring key |
380 * @param key (any supported key type) the key |
| 734 ) { |
381 * @return the pointer to the allocated memory or @c NULL if allocation fails |
| 735 return map->cl->get(map, cx_hash_key_cxstr(key)); |
382 * @retval zero success |
| 736 } |
383 * @retval non-zero value on memory allocation failure |
| 737 |
384 * @see CX_HASH_KEY() |
| 738 /** |
385 */ |
| 739 * @copydoc cxMapGet() |
386 #define cxMapEmplace(map, key) cx_map_emplace(map, CX_HASH_KEY(key)) |
| 740 */ |
|
| 741 cx_attr_nonnull |
|
| 742 cx_attr_nodiscard |
|
| 743 static inline void *cx_map_get_mustr( |
|
| 744 const CxMap *map, |
|
| 745 cxmutstr key |
|
| 746 ) { |
|
| 747 return map->cl->get(map, cx_hash_key_cxstr(key)); |
|
| 748 } |
|
| 749 |
|
| 750 /** |
|
| 751 * @copydoc cxMapGet() |
|
| 752 */ |
|
| 753 cx_attr_nonnull |
|
| 754 cx_attr_nodiscard |
|
| 755 cx_attr_cstr_arg(2) |
|
| 756 static inline void *cx_map_get_str( |
|
| 757 const CxMap *map, |
|
| 758 const char *key |
|
| 759 ) { |
|
| 760 return map->cl->get(map, cx_hash_key_str(key)); |
|
| 761 } |
|
| 762 |
387 |
| 763 /** |
388 /** |
| 764 * Retrieves a value by using a key. |
389 * Retrieves a value by using a key. |
| 765 * |
390 * |
| 766 * If this map is storing pointers, the stored pointer is returned. |
391 * If this map is storing pointers, the stored pointer is returned. |
| 767 * Otherwise, a pointer to the element within the map's memory |
392 * Otherwise, a pointer to the element within the map's memory |
| 768 * is returned (which is valid as long as the element stays in the map). |
393 * is returned (which is valid as long as the element stays in the map). |
| 769 * |
394 * |
| |
395 * @param map the map |
| |
396 * @param key the key |
| |
397 * @return the value |
| |
398 * @see cxMapGet() |
| |
399 */ |
| |
400 cx_attr_nonnull cx_attr_nodiscard |
| |
401 CX_EXPORT void *cx_map_get(const CxMap *map, CxHashKey key); |
| |
402 |
| |
403 /** |
| |
404 * Retrieves a value by using a key. |
| |
405 * |
| |
406 * If this map is storing pointers, the stored pointer is returned. |
| |
407 * Otherwise, a pointer to the element within the map's memory |
| |
408 * is returned (which is valid as long as the element stays in the map). |
| |
409 * |
| 770 * @param map (@c CxMap*) the map |
410 * @param map (@c CxMap*) the map |
| 771 * @param key (@c CxHashKey, @c char*, @c cxstring, or @c cxmutstr) the key |
411 * @param key (any supported key type) the key |
| 772 * @return (@c void*) the value |
412 * @return (@c void*) the value or @c NULL when no value with that @p key exists |
| 773 */ |
413 * @see CX_HASH_KEY() |
| 774 #define cxMapGet(map, key) _Generic((key), \ |
414 */ |
| 775 CxHashKey: cx_map_get, \ |
415 #define cxMapGet(map, key) cx_map_get(map, CX_HASH_KEY(key)) |
| 776 cxstring: cx_map_get_cxstr, \ |
416 |
| 777 cxmutstr: cx_map_get_mustr, \ |
417 /** |
| 778 char*: cx_map_get_str, \ |
418 * Checks if a map contains a specific key. |
| 779 const char*: cx_map_get_str) \ |
419 * |
| 780 (map, key) |
420 * @param map (@c CxMap*) the map |
| 781 |
421 * @param key (any supported key type) the key |
| 782 /** |
422 * @retval true if the key exists in the map |
| 783 * @copydoc cxMapRemove() |
423 * @retval false if the key does not exist in the map |
| 784 */ |
424 * @see CX_HASH_KEY() |
| 785 cx_attr_nonnull |
425 */ |
| 786 static inline int cx_map_remove( |
426 #define cxMapContains(map, key) (cxMapGet(map, key) != NULL) |
| 787 CxMap *map, |
|
| 788 CxHashKey key |
|
| 789 ) { |
|
| 790 return map->cl->remove(map, key, NULL); |
|
| 791 } |
|
| 792 |
|
| 793 /** |
|
| 794 * @copydoc cxMapRemove() |
|
| 795 */ |
|
| 796 cx_attr_nonnull |
|
| 797 static inline int cx_map_remove_cxstr( |
|
| 798 CxMap *map, |
|
| 799 cxstring key |
|
| 800 ) { |
|
| 801 return map->cl->remove(map, cx_hash_key_cxstr(key), NULL); |
|
| 802 } |
|
| 803 |
|
| 804 /** |
|
| 805 * @copydoc cxMapRemove() |
|
| 806 */ |
|
| 807 cx_attr_nonnull |
|
| 808 static inline int cx_map_remove_mustr( |
|
| 809 CxMap *map, |
|
| 810 cxmutstr key |
|
| 811 ) { |
|
| 812 return map->cl->remove(map, cx_hash_key_cxstr(key), NULL); |
|
| 813 } |
|
| 814 |
|
| 815 /** |
|
| 816 * @copydoc cxMapRemove() |
|
| 817 */ |
|
| 818 cx_attr_nonnull |
|
| 819 cx_attr_cstr_arg(2) |
|
| 820 static inline int cx_map_remove_str( |
|
| 821 CxMap *map, |
|
| 822 const char *key |
|
| 823 ) { |
|
| 824 return map->cl->remove(map, cx_hash_key_str(key), NULL); |
|
| 825 } |
|
| 826 |
427 |
| 827 /** |
428 /** |
| 828 * Removes a key/value-pair from the map by using the key. |
429 * Removes a key/value-pair from the map by using the key. |
| 829 * |
430 * |
| 830 * Always invokes the destructors functions, if any, on the removed element. |
431 * Invokes the destructor functions, if any, on the removed element if and only if the |
| |
432 * @p targetbuf is @c NULL. |
| |
433 * |
| |
434 * @param map the map |
| |
435 * @param key the key |
| |
436 * @param targetbuf the optional buffer where the removed element shall be copied to |
| |
437 * @retval zero success |
| |
438 * @retval non-zero the key was not found |
| |
439 * |
| |
440 * @see cxMapRemove() |
| |
441 * @see cxMapRemoveAndGet() |
| |
442 */ |
| |
443 cx_attr_nonnull_arg(1) |
| |
444 CX_EXPORT int cx_map_remove(CxMap *map, CxHashKey key, void *targetbuf); |
| |
445 |
| |
446 /** |
| |
447 * Removes a key/value-pair from the map by using the key. |
| |
448 * |
| |
449 * Always invokes the destructor functions, if any, on the removed element. |
| 831 * |
450 * |
| 832 * @param map (@c CxMap*) the map |
451 * @param map (@c CxMap*) the map |
| 833 * @param key (@c CxHashKey, @c char*, @c cxstring, or @c cxmutstr) the key |
452 * @param key (any supported key type) the key |
| 834 * @retval zero success |
453 * @retval zero success |
| 835 * @retval non-zero the key was not found |
454 * @retval non-zero the key was not found |
| 836 * |
455 * |
| 837 * @see cxMapRemoveAndGet() |
456 * @see cxMapRemoveAndGet() |
| 838 */ |
457 * @see CX_HASH_KEY() |
| 839 #define cxMapRemove(map, key) _Generic((key), \ |
458 */ |
| 840 CxHashKey: cx_map_remove, \ |
459 #define cxMapRemove(map, key) cx_map_remove(map, CX_HASH_KEY(key), NULL) |
| 841 cxstring: cx_map_remove_cxstr, \ |
|
| 842 cxmutstr: cx_map_remove_mustr, \ |
|
| 843 char*: cx_map_remove_str, \ |
|
| 844 const char*: cx_map_remove_str) \ |
|
| 845 (map, key) |
|
| 846 |
|
| 847 /** |
|
| 848 * @copydoc cxMapRemoveAndGet() |
|
| 849 */ |
|
| 850 cx_attr_nonnull |
|
| 851 cx_attr_access_w(3) |
|
| 852 static inline int cx_map_remove_and_get( |
|
| 853 CxMap *map, |
|
| 854 CxHashKey key, |
|
| 855 void *targetbuf |
|
| 856 ) { |
|
| 857 return map->cl->remove(map, key, targetbuf); |
|
| 858 } |
|
| 859 |
|
| 860 /** |
|
| 861 * @copydoc cxMapRemoveAndGet() |
|
| 862 */ |
|
| 863 cx_attr_nonnull |
|
| 864 cx_attr_access_w(3) |
|
| 865 static inline int cx_map_remove_and_get_cxstr( |
|
| 866 CxMap *map, |
|
| 867 cxstring key, |
|
| 868 void *targetbuf |
|
| 869 ) { |
|
| 870 return map->cl->remove(map, cx_hash_key_cxstr(key), targetbuf); |
|
| 871 } |
|
| 872 |
|
| 873 /** |
|
| 874 * @copydoc cxMapRemoveAndGet() |
|
| 875 */ |
|
| 876 cx_attr_nonnull |
|
| 877 cx_attr_access_w(3) |
|
| 878 static inline int cx_map_remove_and_get_mustr( |
|
| 879 CxMap *map, |
|
| 880 cxmutstr key, |
|
| 881 void *targetbuf |
|
| 882 ) { |
|
| 883 return map->cl->remove(map, cx_hash_key_cxstr(key), targetbuf); |
|
| 884 } |
|
| 885 |
|
| 886 /** |
|
| 887 * @copydoc cxMapRemoveAndGet() |
|
| 888 */ |
|
| 889 cx_attr_nonnull |
|
| 890 cx_attr_access_w(3) |
|
| 891 cx_attr_cstr_arg(2) |
|
| 892 static inline int cx_map_remove_and_get_str( |
|
| 893 CxMap *map, |
|
| 894 const char *key, |
|
| 895 void *targetbuf |
|
| 896 ) { |
|
| 897 return map->cl->remove(map, cx_hash_key_str(key), targetbuf); |
|
| 898 } |
|
| 899 |
460 |
| 900 /** |
461 /** |
| 901 * Removes a key/value-pair from the map by using the key. |
462 * Removes a key/value-pair from the map by using the key. |
| 902 * |
463 * |
| 903 * This function will copy the contents of the removed element |
464 * This function will copy the contents of the removed element |
| 907 * |
468 * |
| 908 * If this map is storing pointers, the element is the pointer itself |
469 * If this map is storing pointers, the element is the pointer itself |
| 909 * and not the object it points to. |
470 * and not the object it points to. |
| 910 * |
471 * |
| 911 * @param map (@c CxMap*) the map |
472 * @param map (@c CxMap*) the map |
| 912 * @param key (@c CxHashKey, @c char*, @c cxstring, or @c cxmutstr) the key |
473 * @param key (any supported key type) the key |
| 913 * @param targetbuf (@c void*) the buffer where the element shall be copied to |
474 * @param targetbuf (@c void*) the buffer where the element shall be copied to |
| 914 * @retval zero success |
475 * @retval zero success |
| 915 * @retval non-zero the key was not found |
476 * @retval non-zero the key was not found |
| 916 * |
477 * |
| 917 * @see cxMapRemove() |
478 * @see cxMapRemove() |
| 918 */ |
479 * @see CX_HASH_KEY() |
| 919 #define cxMapRemoveAndGet(map, key, targetbuf) _Generic((key), \ |
480 */ |
| 920 CxHashKey: cx_map_remove_and_get, \ |
481 #define cxMapRemoveAndGet(map, key, targetbuf) cx_map_remove(map, CX_HASH_KEY(key), targetbuf) |
| 921 cxstring: cx_map_remove_and_get_cxstr, \ |
482 |
| 922 cxmutstr: cx_map_remove_and_get_mustr, \ |
483 |
| 923 char*: cx_map_remove_and_get_str, \ |
484 /** |
| 924 const char*: cx_map_remove_and_get_str) \ |
485 * Performs a deep clone of one map into another. |
| 925 (map, key, targetbuf) |
486 * |
| 926 |
487 * If the destination map already contains entries, the cloned entries |
| 927 #endif // __cplusplus |
488 * are added to that map, possibly overwriting existing elements when |
| |
489 * the keys already exist. |
| |
490 * |
| |
491 * When elements in the destination map need to be replaced, any destructor |
| |
492 * function is called on the replaced elements before replacing them. |
| |
493 * |
| |
494 * @attention If the cloned elements need to be destroyed by a destructor |
| |
495 * function, you must make sure that the destination map also uses this |
| |
496 * destructor function. |
| |
497 * |
| |
498 * @param dst the destination map |
| |
499 * @param src the source map |
| |
500 * @param clone_func the clone function for the values |
| |
501 * @param clone_allocator the allocator that is passed to the clone function |
| |
502 * @param data optional additional data that is passed to the clone function |
| |
503 * @retval zero when all elements were successfully cloned |
| |
504 * @retval non-zero when an allocation error occurred |
| |
505 */ |
| |
506 cx_attr_nonnull_arg(1, 2, 3) |
| |
507 CX_EXPORT int cxMapClone(CxMap *dst, const CxMap *src, |
| |
508 cx_clone_func clone_func, const CxAllocator *clone_allocator, void *data); |
| |
509 |
| |
510 |
| |
511 /** |
| |
512 * Clones entries of a map if their key is not present in another map. |
| |
513 * |
| |
514 * @param dst the destination map |
| |
515 * @param minuend the map to subtract the entries from |
| |
516 * @param subtrahend the map containing the elements to be subtracted |
| |
517 * @param clone_func the clone function for the values |
| |
518 * @param clone_allocator the allocator that is passed to the clone function |
| |
519 * @param data optional additional data that is passed to the clone function |
| |
520 * @retval zero when the elements were successfully cloned |
| |
521 * @retval non-zero when an allocation error occurred |
| |
522 */ |
| |
523 cx_attr_nonnull_arg(1, 2, 3, 4) |
| |
524 CX_EXPORT int cxMapDifference(CxMap *dst, const CxMap *minuend, const CxMap *subtrahend, |
| |
525 cx_clone_func clone_func, const CxAllocator *clone_allocator, void *data); |
| |
526 |
| |
527 /** |
| |
528 * Clones entries of a map if their key is not present in a list. |
| |
529 * |
| |
530 * Note that the list must contain keys of type @c CxKey |
| |
531 * (or pointers to such keys) and must use @c cx_hash_key_cmp |
| |
532 * as the compare function. |
| |
533 * Generic key types cannot be processed in this case. |
| |
534 * |
| |
535 * @param dst the destination map |
| |
536 * @param src the source map |
| |
537 * @param keys the list of @c CxKey items |
| |
538 * @param clone_func the clone function for the values |
| |
539 * @param clone_allocator the allocator that is passed to the clone function |
| |
540 * @param data optional additional data that is passed to the clone function |
| |
541 * @retval zero when the elements were successfully cloned |
| |
542 * @retval non-zero when an allocation error occurred |
| |
543 */ |
| |
544 cx_attr_nonnull_arg(1, 2, 3, 4) |
| |
545 CX_EXPORT int cxMapListDifference(CxMap *dst, const CxMap *src, const CxList *keys, |
| |
546 cx_clone_func clone_func, const CxAllocator *clone_allocator, void *data); |
| |
547 |
| |
548 |
| |
549 /** |
| |
550 * Clones entries of a map only if their key is present in another map. |
| |
551 * |
| |
552 * @param dst the destination map |
| |
553 * @param src the map to clone the entries from |
| |
554 * @param other the map to check for existence of the keys |
| |
555 * @param clone_func the clone function for the values |
| |
556 * @param clone_allocator the allocator that is passed to the clone function |
| |
557 * @param data optional additional data that is passed to the clone function |
| |
558 * @retval zero when the elements were successfully cloned |
| |
559 * @retval non-zero when an allocation error occurred |
| |
560 */ |
| |
561 cx_attr_nonnull_arg(1, 2, 3, 4) |
| |
562 CX_EXPORT int cxMapIntersection(CxMap *dst, const CxMap *src, const CxMap *other, |
| |
563 cx_clone_func clone_func, const CxAllocator *clone_allocator, void *data); |
| |
564 |
| |
565 /** |
| |
566 * Clones entries of a map only if their key is present in a list. |
| |
567 * |
| |
568 * Note that the list must contain keys of type @c CxKey |
| |
569 * (or pointers to such keys) and must use @c cx_hash_key_cmp |
| |
570 * as the compare function. |
| |
571 * Generic key types cannot be processed in this case. |
| |
572 * |
| |
573 * @param dst the destination map |
| |
574 * @param src the source map |
| |
575 * @param keys the list of @c CxKey items |
| |
576 * @param clone_func the clone function for the values |
| |
577 * @param clone_allocator the allocator that is passed to the clone function |
| |
578 * @param data optional additional data that is passed to the clone function |
| |
579 * @retval zero when the elements were successfully cloned |
| |
580 * @retval non-zero when an allocation error occurred |
| |
581 */ |
| |
582 cx_attr_nonnull_arg(1, 2, 3, 4) |
| |
583 CX_EXPORT int cxMapListIntersection(CxMap *dst, const CxMap *src, const CxList *keys, |
| |
584 cx_clone_func clone_func, const CxAllocator *clone_allocator, void *data); |
| |
585 |
| |
586 /** |
| |
587 * Clones entries into a map if their key does not exist yet. |
| |
588 * |
| |
589 * If you want to calculate the union of two maps into a fresh new map, |
| |
590 * you can proceed as follows: |
| |
591 * 1. Clone the first map into a fresh, empty map. |
| |
592 * 2. Use this function to clone the second map into the result from step 1. |
| |
593 * |
| |
594 * @param dst the destination map |
| |
595 * @param src the map to clone the entries from |
| |
596 * @param clone_func the clone function for the values |
| |
597 * @param clone_allocator the allocator that is passed to the clone function |
| |
598 * @param data optional additional data that is passed to the clone function |
| |
599 * @retval zero when the elements were successfully cloned |
| |
600 * @retval non-zero when an allocation error occurred |
| |
601 */ |
| |
602 cx_attr_nonnull_arg(1, 2, 3) |
| |
603 CX_EXPORT int cxMapUnion(CxMap *dst, const CxMap *src, |
| |
604 cx_clone_func clone_func, const CxAllocator *clone_allocator, void *data); |
| |
605 |
| |
606 #ifdef __cplusplus |
| |
607 } // extern "C" |
| |
608 #endif |
| 928 |
609 |
| 929 #endif // UCX_MAP_H |
610 #endif // UCX_MAP_H |