| 225 /** |
213 /** |
| 226 * A shared instance of an empty map. |
214 * A shared instance of an empty map. |
| 227 * |
215 * |
| 228 * Writing to that map is not allowed. |
216 * Writing to that map is not allowed. |
| 229 * |
217 * |
| 230 * You can use this is a placeholder for initializing CxMap pointers |
218 * You can use this as a placeholder for initializing CxMap pointers |
| 231 * 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. |
| 232 */ |
220 */ |
| 233 cx_attr_export |
221 CX_EXPORT extern CxMap *const cxEmptyMap; |
| 234 extern CxMap *const cxEmptyMap; |
|
| 235 |
222 |
| 236 /** |
223 /** |
| 237 * Deallocates the memory of the specified map. |
224 * Deallocates the memory of the specified map. |
| 238 * |
225 * |
| 239 * Also calls the content destructor functions for each element, if specified. |
226 * Also calls the content destructor functions for each element, if specified. |
| 240 * |
227 * |
| 241 * @param map the map to be freed |
228 * @param map the map to be freed |
| 242 */ |
229 */ |
| 243 cx_attr_export |
230 CX_EXPORT void cxMapFree(CxMap *map); |
| 244 void cxMapFree(CxMap *map); |
|
| 245 |
231 |
| 246 |
232 |
| 247 /** |
233 /** |
| 248 * Clears a map by removing all elements. |
234 * Clears a map by removing all elements. |
| 249 * |
235 * |
| 250 * Also calls the content destructor functions for each element, if specified. |
236 * Also calls the content destructor functions for each element, if specified. |
| 251 * |
237 * |
| 252 * @param map the map to be cleared |
238 * @param map the map to be cleared |
| 253 */ |
239 */ |
| 254 cx_attr_nonnull |
240 cx_attr_nonnull |
| 255 static inline void cxMapClear(CxMap *map) { |
241 CX_EXPORT void cxMapClear(CxMap *map); |
| 256 map->cl->clear(map); |
|
| 257 } |
|
| 258 |
242 |
| 259 /** |
243 /** |
| 260 * Returns the number of elements in this map. |
244 * Returns the number of elements in this map. |
| 261 * |
245 * |
| 262 * @param map the map |
246 * @param map the map |
| 263 * @return the number of stored elements |
247 * @return the number of stored elements |
| 264 */ |
248 */ |
| 265 cx_attr_nonnull |
249 cx_attr_nonnull |
| 266 static inline size_t cxMapSize(const CxMap *map) { |
250 CX_EXPORT size_t cxMapSize(const CxMap *map); |
| 267 return map->collection.size; |
|
| 268 } |
|
| 269 |
251 |
| 270 /** |
252 /** |
| 271 * Creates a value iterator for a map. |
253 * Creates a value iterator for a map. |
| 272 * |
254 * |
| 273 * When the map is storing pointers, those pointers are returned. |
255 * When the map is storing pointers, those pointers are returned. |
| 275 * respective elements are stored. |
257 * respective elements are stored. |
| 276 * |
258 * |
| 277 * @note An iterator iterates over all elements successively. Therefore, the order |
259 * @note An iterator iterates over all elements successively. Therefore, the order |
| 278 * highly depends on the map implementation and may change arbitrarily when the contents change. |
260 * highly depends on the map implementation and may change arbitrarily when the contents change. |
| 279 * |
261 * |
| 280 * @param map the map to create the iterator for |
262 * @param map the map to create the iterator for (can be @c NULL) |
| 281 * @return an iterator for the currently stored values |
263 * @return an iterator for the currently stored values |
| 282 */ |
264 */ |
| 283 cx_attr_nonnull |
|
| 284 cx_attr_nodiscard |
265 cx_attr_nodiscard |
| 285 static inline CxMapIterator cxMapIteratorValues(const CxMap *map) { |
266 CX_EXPORT CxMapIterator cxMapIteratorValues(const CxMap *map); |
| 286 return map->cl->iterator(map, CX_MAP_ITERATOR_VALUES); |
|
| 287 } |
|
| 288 |
267 |
| 289 /** |
268 /** |
| 290 * Creates a key iterator for a map. |
269 * Creates a key iterator for a map. |
| 291 * |
270 * |
| 292 * 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 |
| 293 * during iterator shall be treated as @c const @c CxHashKey* . |
272 * during iterator shall be treated as @c const @c CxHashKey* . |
| 294 * |
273 * |
| 295 * @note An iterator iterates over all elements successively. Therefore, the order |
274 * @note An iterator iterates over all elements successively. Therefore, the order |
| 296 * 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. |
| 297 * |
276 * |
| 298 * @param map the map to create the iterator for |
277 * @param map the map to create the iterator for (can be @c NULL) |
| 299 * @return an iterator for the currently stored keys |
278 * @return an iterator for the currently stored keys |
| 300 */ |
279 */ |
| 301 cx_attr_nonnull |
|
| 302 cx_attr_nodiscard |
280 cx_attr_nodiscard |
| 303 static inline CxMapIterator cxMapIteratorKeys(const CxMap *map) { |
281 CX_EXPORT CxMapIterator cxMapIteratorKeys(const CxMap *map); |
| 304 return map->cl->iterator(map, CX_MAP_ITERATOR_KEYS); |
|
| 305 } |
|
| 306 |
282 |
| 307 /** |
283 /** |
| 308 * Creates an iterator for a map. |
284 * Creates an iterator for a map. |
| 309 * |
285 * |
| 310 * 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 |
| 311 * during iterator shall be treated as @c const @c CxMapEntry* . |
287 * during iterator shall be treated as @c const @c CxMapEntry* . |
| 312 * |
288 * |
| 313 * @note An iterator iterates over all elements successively. Therefore, the order |
289 * @note An iterator iterates over all elements successively. Therefore, the order |
| 314 * 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. |
| 315 * |
291 * |
| 316 * @param map the map to create the iterator for |
292 * @param map the map to create the iterator for (can be @c NULL) |
| 317 * @return an iterator for the currently stored entries |
293 * @return an iterator for the currently stored entries |
| 318 * @see cxMapIteratorKeys() |
294 * @see cxMapIteratorKeys() |
| 319 * @see cxMapIteratorValues() |
295 * @see cxMapIteratorValues() |
| 320 */ |
296 */ |
| 321 cx_attr_nonnull |
|
| 322 cx_attr_nodiscard |
297 cx_attr_nodiscard |
| 323 static inline CxMapIterator cxMapIterator(const CxMap *map) { |
298 CX_EXPORT CxMapIterator cxMapIterator(const CxMap *map); |
| 324 return map->cl->iterator(map, CX_MAP_ITERATOR_PAIRS); |
|
| 325 } |
|
| 326 |
|
| 327 |
|
| 328 /** |
|
| 329 * Creates a mutating iterator over the values of a map. |
|
| 330 * |
|
| 331 * When the map is storing pointers, those pointers are returned. |
|
| 332 * Otherwise, the iterator iterates over pointers to the memory within the map where the |
|
| 333 * respective elements are stored. |
|
| 334 * |
|
| 335 * @note An iterator iterates over all elements successively. Therefore, the order |
|
| 336 * highly depends on the map implementation and may change arbitrarily when the contents change. |
|
| 337 * |
|
| 338 * @param map the map to create the iterator for |
|
| 339 * @return an iterator for the currently stored values |
|
| 340 */ |
|
| 341 cx_attr_nonnull |
|
| 342 cx_attr_nodiscard |
|
| 343 cx_attr_export |
|
| 344 CxMapIterator cxMapMutIteratorValues(CxMap *map); |
|
| 345 |
|
| 346 /** |
|
| 347 * Creates a mutating iterator over the keys of a map. |
|
| 348 * |
|
| 349 * The elements of the iterator are keys of type CxHashKey and the pointer returned |
|
| 350 * during iterator shall be treated as @c const @c CxHashKey* . |
|
| 351 * |
|
| 352 * @note An iterator iterates over all elements successively. Therefore, the order |
|
| 353 * highly depends on the map implementation and may change arbitrarily when the contents change. |
|
| 354 * |
|
| 355 * @param map the map to create the iterator for |
|
| 356 * @return an iterator for the currently stored keys |
|
| 357 */ |
|
| 358 cx_attr_nonnull |
|
| 359 cx_attr_nodiscard |
|
| 360 cx_attr_export |
|
| 361 CxMapIterator cxMapMutIteratorKeys(CxMap *map); |
|
| 362 |
|
| 363 /** |
|
| 364 * Creates a mutating iterator for a map. |
|
| 365 * |
|
| 366 * The elements of the iterator are key/value pairs of type CxMapEntry and the pointer returned |
|
| 367 * during iterator shall be treated as @c const @c CxMapEntry* . |
|
| 368 * |
|
| 369 * @note An iterator iterates over all elements successively. Therefore, the order |
|
| 370 * highly depends on the map implementation and may change arbitrarily when the contents change. |
|
| 371 * |
|
| 372 * @param map the map to create the iterator for |
|
| 373 * @return an iterator for the currently stored entries |
|
| 374 * @see cxMapMutIteratorKeys() |
|
| 375 * @see cxMapMutIteratorValues() |
|
| 376 */ |
|
| 377 cx_attr_nonnull |
|
| 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); |
|
| 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); |
|
| 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); |
|
| 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); |
|
| 419 } |
|
| 420 |
|
| 421 cx_attr_nonnull |
|
| 422 cx_attr_nodiscard |
|
| 423 static inline void *cxMapGet( |
|
| 424 const CxMap *map, |
|
| 425 CxHashKey const &key |
|
| 426 ) { |
|
| 427 return map->cl->get(map, key); |
|
| 428 } |
|
| 429 |
|
| 430 cx_attr_nonnull |
|
| 431 cx_attr_nodiscard |
|
| 432 static inline void *cxMapGet( |
|
| 433 const CxMap *map, |
|
| 434 cxstring const &key |
|
| 435 ) { |
|
| 436 return map->cl->get(map, cx_hash_key_cxstr(key)); |
|
| 437 } |
|
| 438 |
|
| 439 cx_attr_nonnull |
|
| 440 cx_attr_nodiscard |
|
| 441 static inline void *cxMapGet( |
|
| 442 const CxMap *map, |
|
| 443 cxmutstr const &key |
|
| 444 ) { |
|
| 445 return map->cl->get(map, cx_hash_key_cxstr(key)); |
|
| 446 } |
|
| 447 |
|
| 448 cx_attr_nonnull |
|
| 449 cx_attr_nodiscard |
|
| 450 cx_attr_cstr_arg(2) |
|
| 451 static inline void *cxMapGet( |
|
| 452 const CxMap *map, |
|
| 453 const char *key |
|
| 454 ) { |
|
| 455 return map->cl->get(map, cx_hash_key_str(key)); |
|
| 456 } |
|
| 457 |
|
| 458 cx_attr_nonnull |
|
| 459 static inline int cxMapRemove( |
|
| 460 CxMap *map, |
|
| 461 CxHashKey const &key |
|
| 462 ) { |
|
| 463 return map->cl->remove(map, key, nullptr); |
|
| 464 } |
|
| 465 |
|
| 466 cx_attr_nonnull |
|
| 467 static inline int cxMapRemove( |
|
| 468 CxMap *map, |
|
| 469 cxstring const &key |
|
| 470 ) { |
|
| 471 return map->cl->remove(map, cx_hash_key_cxstr(key), nullptr); |
|
| 472 } |
|
| 473 |
|
| 474 cx_attr_nonnull |
|
| 475 static inline int cxMapRemove( |
|
| 476 CxMap *map, |
|
| 477 cxmutstr const &key |
|
| 478 ) { |
|
| 479 return map->cl->remove(map, cx_hash_key_cxstr(key), nullptr); |
|
| 480 } |
|
| 481 |
|
| 482 cx_attr_nonnull |
|
| 483 cx_attr_cstr_arg(2) |
|
| 484 static inline int cxMapRemove( |
|
| 485 CxMap *map, |
|
| 486 const char *key |
|
| 487 ) { |
|
| 488 return map->cl->remove(map, cx_hash_key_str(key), nullptr); |
|
| 489 } |
|
| 490 |
|
| 491 cx_attr_nonnull |
|
| 492 cx_attr_access_w(3) |
|
| 493 static inline int cxMapRemoveAndGet( |
|
| 494 CxMap *map, |
|
| 495 CxHashKey key, |
|
| 496 void *targetbuf |
|
| 497 ) { |
|
| 498 return map->cl->remove(map, key, targetbuf); |
|
| 499 } |
|
| 500 |
|
| 501 cx_attr_nonnull |
|
| 502 cx_attr_access_w(3) |
|
| 503 static inline int cxMapRemoveAndGet( |
|
| 504 CxMap *map, |
|
| 505 cxstring key, |
|
| 506 void *targetbuf |
|
| 507 ) { |
|
| 508 return map->cl->remove(map, cx_hash_key_cxstr(key), targetbuf); |
|
| 509 } |
|
| 510 |
|
| 511 cx_attr_nonnull |
|
| 512 cx_attr_access_w(3) |
|
| 513 static inline int cxMapRemoveAndGet( |
|
| 514 CxMap *map, |
|
| 515 cxmutstr key, |
|
| 516 void *targetbuf |
|
| 517 ) { |
|
| 518 return map->cl->remove(map, cx_hash_key_cxstr(key), targetbuf); |
|
| 519 } |
|
| 520 |
|
| 521 cx_attr_nonnull |
|
| 522 cx_attr_access_w(3) |
|
| 523 cx_attr_cstr_arg(2) |
|
| 524 static inline int cxMapRemoveAndGet( |
|
| 525 CxMap *map, |
|
| 526 const char *key, |
|
| 527 void *targetbuf |
|
| 528 ) { |
|
| 529 return map->cl->remove(map, cx_hash_key_str(key), targetbuf); |
|
| 530 } |
|
| 531 |
|
| 532 #else // __cplusplus |
|
| 533 |
|
| 534 /** |
|
| 535 * @copydoc cxMapPut() |
|
| 536 */ |
|
| 537 cx_attr_nonnull |
|
| 538 static inline int cx_map_put( |
|
| 539 CxMap *map, |
|
| 540 CxHashKey key, |
|
| 541 void *value |
|
| 542 ) { |
|
| 543 return map->cl->put(map, key, value); |
|
| 544 } |
|
| 545 |
|
| 546 /** |
|
| 547 * @copydoc cxMapPut() |
|
| 548 */ |
|
| 549 cx_attr_nonnull |
|
| 550 static inline int cx_map_put_cxstr( |
|
| 551 CxMap *map, |
|
| 552 cxstring key, |
|
| 553 void *value |
|
| 554 ) { |
|
| 555 return map->cl->put(map, cx_hash_key_cxstr(key), value); |
|
| 556 } |
|
| 557 |
|
| 558 /** |
|
| 559 * @copydoc cxMapPut() |
|
| 560 */ |
|
| 561 cx_attr_nonnull |
|
| 562 static inline int cx_map_put_mustr( |
|
| 563 CxMap *map, |
|
| 564 cxmutstr key, |
|
| 565 void *value |
|
| 566 ) { |
|
| 567 return map->cl->put(map, cx_hash_key_cxstr(key), value); |
|
| 568 } |
|
| 569 |
|
| 570 /** |
|
| 571 * @copydoc cxMapPut() |
|
| 572 */ |
|
| 573 cx_attr_nonnull |
|
| 574 cx_attr_cstr_arg(2) |
|
| 575 static inline int cx_map_put_str( |
|
| 576 CxMap *map, |
|
| 577 const char *key, |
|
| 578 void *value |
|
| 579 ) { |
|
| 580 return map->cl->put(map, cx_hash_key_str(key), value); |
|
| 581 } |
|
| 582 |
299 |
| 583 /** |
300 /** |
| 584 * Puts a key/value-pair into the map. |
301 * Puts a key/value-pair into the map. |
| 585 * |
302 * |
| 586 * A possible existing value will be overwritten. |
303 * A possible existing value will be overwritten. |
| 591 * 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 |
| 592 * memcpy(). |
309 * memcpy(). |
| 593 * |
310 * |
| 594 * The @p key is always copied. |
311 * The @p key is always copied. |
| 595 * |
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 * |
| 596 * @param map (@c CxMap*) the map |
336 * @param map (@c CxMap*) the map |
| 597 * @param key (@c CxHashKey, @c char*, @c cxstring, or @c cxmutstr) the key |
337 * @param key (any supported key type) the key |
| 598 * @param value (@c void*) the value |
338 * @param value (@c void*) the value |
| 599 * @retval zero success |
339 * @retval zero success |
| 600 * @retval non-zero value on memory allocation failure |
340 * @retval non-zero value on memory allocation failure |
| 601 */ |
341 * @see CX_HASH_KEY() |
| 602 #define cxMapPut(map, key, value) _Generic((key), \ |
342 */ |
| 603 CxHashKey: cx_map_put, \ |
343 #define cxMapPut(map, key, value) cx_map_put(map, CX_HASH_KEY(key), value) |
| 604 cxstring: cx_map_put_cxstr, \ |
344 |
| 605 cxmutstr: cx_map_put_mustr, \ |
345 /** |
| 606 char*: cx_map_put_str, \ |
346 * Allocates memory for a value in the map associated with the specified key. |
| 607 const char*: cx_map_put_str) \ |
347 * |
| 608 (map, key, value) |
348 * A possible existing value will be overwritten. |
| 609 |
349 * If destructor functions are specified, they are called for |
| 610 /** |
350 * the overwritten element. |
| 611 * @copydoc cxMapGet() |
351 * |
| |
352 * If the map is storing pointers, this function returns a @c void** pointer, |
| |
353 * meaning a pointer to that pointer. |
| |
354 * |
| |
355 * The @p key is always copied. |
| |
356 * |
| |
357 * @param map the map |
| |
358 * @param key the key |
| |
359 * @return the pointer to the allocated memory or @c NULL if allocation fails |
| |
360 * @retval zero success |
| |
361 * @retval non-zero value on memory allocation failure |
| |
362 * @see cxMapEmplace() |
| 612 */ |
363 */ |
| 613 cx_attr_nonnull |
364 cx_attr_nonnull |
| 614 cx_attr_nodiscard |
365 CX_EXPORT void *cx_map_emplace(CxMap *map, CxHashKey key); |
| 615 static inline void *cx_map_get( |
366 |
| 616 const CxMap *map, |
367 /** |
| 617 CxHashKey key |
368 * Allocates memory for a value in the map associated with the specified key. |
| 618 ) { |
369 * |
| 619 return map->cl->get(map, key); |
370 * A possible existing value will be overwritten. |
| 620 } |
371 * If destructor functions are specified, they are called for |
| 621 |
372 * the overwritten element. |
| 622 /** |
373 * |
| 623 * @copydoc cxMapGet() |
374 * If the map is storing pointers, this function returns a @c void** pointer, |
| 624 */ |
375 * meaning a pointer to that pointer. |
| 625 cx_attr_nonnull |
376 * |
| 626 cx_attr_nodiscard |
377 * The @p key is always copied. |
| 627 static inline void *cx_map_get_cxstr( |
378 * |
| 628 const CxMap *map, |
379 * @param map (@c CxMap*) the map |
| 629 cxstring key |
380 * @param key (any supported key type) the key |
| 630 ) { |
381 * @return the pointer to the allocated memory or @c NULL if allocation fails |
| 631 return map->cl->get(map, cx_hash_key_cxstr(key)); |
382 * @retval zero success |
| 632 } |
383 * @retval non-zero value on memory allocation failure |
| 633 |
384 * @see CX_HASH_KEY() |
| 634 /** |
385 */ |
| 635 * @copydoc cxMapGet() |
386 #define cxMapEmplace(map, key) cx_map_emplace(map, CX_HASH_KEY(key)) |
| 636 */ |
|
| 637 cx_attr_nonnull |
|
| 638 cx_attr_nodiscard |
|
| 639 static inline void *cx_map_get_mustr( |
|
| 640 const CxMap *map, |
|
| 641 cxmutstr key |
|
| 642 ) { |
|
| 643 return map->cl->get(map, cx_hash_key_cxstr(key)); |
|
| 644 } |
|
| 645 |
|
| 646 /** |
|
| 647 * @copydoc cxMapGet() |
|
| 648 */ |
|
| 649 cx_attr_nonnull |
|
| 650 cx_attr_nodiscard |
|
| 651 cx_attr_cstr_arg(2) |
|
| 652 static inline void *cx_map_get_str( |
|
| 653 const CxMap *map, |
|
| 654 const char *key |
|
| 655 ) { |
|
| 656 return map->cl->get(map, cx_hash_key_str(key)); |
|
| 657 } |
|
| 658 |
387 |
| 659 /** |
388 /** |
| 660 * Retrieves a value by using a key. |
389 * Retrieves a value by using a key. |
| 661 * |
390 * |
| 662 * If this map is storing pointers, the stored pointer is returned. |
391 * If this map is storing pointers, the stored pointer is returned. |
| 663 * Otherwise, a pointer to the element within the map's memory |
392 * Otherwise, a pointer to the element within the map's memory |
| 664 * 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). |
| 665 * |
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 * |
| 666 * @param map (@c CxMap*) the map |
410 * @param map (@c CxMap*) the map |
| 667 * @param key (@c CxHashKey, @c char*, @c cxstring, or @c cxmutstr) the key |
411 * @param key (any supported key type) the key |
| 668 * @return (@c void*) the value |
412 * @return (@c void*) the value or @c NULL when no value with that @p key exists |
| 669 */ |
413 * @see CX_HASH_KEY() |
| 670 #define cxMapGet(map, key) _Generic((key), \ |
414 */ |
| 671 CxHashKey: cx_map_get, \ |
415 #define cxMapGet(map, key) cx_map_get(map, CX_HASH_KEY(key)) |
| 672 cxstring: cx_map_get_cxstr, \ |
416 |
| 673 cxmutstr: cx_map_get_mustr, \ |
417 /** |
| 674 char*: cx_map_get_str, \ |
418 * Checks if a map contains a specific key. |
| 675 const char*: cx_map_get_str) \ |
419 * |
| 676 (map, key) |
420 * @param map (@c CxMap*) the map |
| 677 |
421 * @param key (any supported key type) the key |
| 678 /** |
422 * @retval true if the key exists in the map |
| 679 * @copydoc cxMapRemove() |
423 * @retval false if the key does not exist in the map |
| 680 */ |
424 * @see CX_HASH_KEY() |
| 681 cx_attr_nonnull |
425 */ |
| 682 static inline int cx_map_remove( |
426 #define cxMapContains(map, key) (cxMapGet(map, key) != NULL) |
| 683 CxMap *map, |
|
| 684 CxHashKey key |
|
| 685 ) { |
|
| 686 return map->cl->remove(map, key, NULL); |
|
| 687 } |
|
| 688 |
|
| 689 /** |
|
| 690 * @copydoc cxMapRemove() |
|
| 691 */ |
|
| 692 cx_attr_nonnull |
|
| 693 static inline int cx_map_remove_cxstr( |
|
| 694 CxMap *map, |
|
| 695 cxstring key |
|
| 696 ) { |
|
| 697 return map->cl->remove(map, cx_hash_key_cxstr(key), NULL); |
|
| 698 } |
|
| 699 |
|
| 700 /** |
|
| 701 * @copydoc cxMapRemove() |
|
| 702 */ |
|
| 703 cx_attr_nonnull |
|
| 704 static inline int cx_map_remove_mustr( |
|
| 705 CxMap *map, |
|
| 706 cxmutstr key |
|
| 707 ) { |
|
| 708 return map->cl->remove(map, cx_hash_key_cxstr(key), NULL); |
|
| 709 } |
|
| 710 |
|
| 711 /** |
|
| 712 * @copydoc cxMapRemove() |
|
| 713 */ |
|
| 714 cx_attr_nonnull |
|
| 715 cx_attr_cstr_arg(2) |
|
| 716 static inline int cx_map_remove_str( |
|
| 717 CxMap *map, |
|
| 718 const char *key |
|
| 719 ) { |
|
| 720 return map->cl->remove(map, cx_hash_key_str(key), NULL); |
|
| 721 } |
|
| 722 |
427 |
| 723 /** |
428 /** |
| 724 * 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. |
| 725 * |
430 * |
| 726 * 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. |
| 727 * |
450 * |
| 728 * @param map (@c CxMap*) the map |
451 * @param map (@c CxMap*) the map |
| 729 * @param key (@c CxHashKey, @c char*, @c cxstring, or @c cxmutstr) the key |
452 * @param key (any supported key type) the key |
| 730 * @retval zero success |
453 * @retval zero success |
| 731 * @retval non-zero the key was not found |
454 * @retval non-zero the key was not found |
| 732 * |
455 * |
| 733 * @see cxMapRemoveAndGet() |
456 * @see cxMapRemoveAndGet() |
| 734 */ |
457 * @see CX_HASH_KEY() |
| 735 #define cxMapRemove(map, key) _Generic((key), \ |
458 */ |
| 736 CxHashKey: cx_map_remove, \ |
459 #define cxMapRemove(map, key) cx_map_remove(map, CX_HASH_KEY(key), NULL) |
| 737 cxstring: cx_map_remove_cxstr, \ |
|
| 738 cxmutstr: cx_map_remove_mustr, \ |
|
| 739 char*: cx_map_remove_str, \ |
|
| 740 const char*: cx_map_remove_str) \ |
|
| 741 (map, key) |
|
| 742 |
|
| 743 /** |
|
| 744 * @copydoc cxMapRemoveAndGet() |
|
| 745 */ |
|
| 746 cx_attr_nonnull |
|
| 747 cx_attr_access_w(3) |
|
| 748 static inline int cx_map_remove_and_get( |
|
| 749 CxMap *map, |
|
| 750 CxHashKey key, |
|
| 751 void *targetbuf |
|
| 752 ) { |
|
| 753 return map->cl->remove(map, key, targetbuf); |
|
| 754 } |
|
| 755 |
|
| 756 /** |
|
| 757 * @copydoc cxMapRemoveAndGet() |
|
| 758 */ |
|
| 759 cx_attr_nonnull |
|
| 760 cx_attr_access_w(3) |
|
| 761 static inline int cx_map_remove_and_get_cxstr( |
|
| 762 CxMap *map, |
|
| 763 cxstring key, |
|
| 764 void *targetbuf |
|
| 765 ) { |
|
| 766 return map->cl->remove(map, cx_hash_key_cxstr(key), targetbuf); |
|
| 767 } |
|
| 768 |
|
| 769 /** |
|
| 770 * @copydoc cxMapRemoveAndGet() |
|
| 771 */ |
|
| 772 cx_attr_nonnull |
|
| 773 cx_attr_access_w(3) |
|
| 774 static inline int cx_map_remove_and_get_mustr( |
|
| 775 CxMap *map, |
|
| 776 cxmutstr key, |
|
| 777 void *targetbuf |
|
| 778 ) { |
|
| 779 return map->cl->remove(map, cx_hash_key_cxstr(key), targetbuf); |
|
| 780 } |
|
| 781 |
|
| 782 /** |
|
| 783 * @copydoc cxMapRemoveAndGet() |
|
| 784 */ |
|
| 785 cx_attr_nonnull |
|
| 786 cx_attr_access_w(3) |
|
| 787 cx_attr_cstr_arg(2) |
|
| 788 static inline int cx_map_remove_and_get_str( |
|
| 789 CxMap *map, |
|
| 790 const char *key, |
|
| 791 void *targetbuf |
|
| 792 ) { |
|
| 793 return map->cl->remove(map, cx_hash_key_str(key), targetbuf); |
|
| 794 } |
|
| 795 |
460 |
| 796 /** |
461 /** |
| 797 * 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. |
| 798 * |
463 * |
| 799 * This function will copy the contents of the removed element |
464 * This function will copy the contents of the removed element |
| 803 * |
468 * |
| 804 * 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 |
| 805 * and not the object it points to. |
470 * and not the object it points to. |
| 806 * |
471 * |
| 807 * @param map (@c CxMap*) the map |
472 * @param map (@c CxMap*) the map |
| 808 * @param key (@c CxHashKey, @c char*, @c cxstring, or @c cxmutstr) the key |
473 * @param key (any supported key type) the key |
| 809 * @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 |
| 810 * @retval zero success |
475 * @retval zero success |
| 811 * @retval non-zero the key was not found |
476 * @retval non-zero the key was not found |
| 812 * |
477 * |
| 813 * @see cxMapRemove() |
478 * @see cxMapRemove() |
| 814 */ |
479 * @see CX_HASH_KEY() |
| 815 #define cxMapRemoveAndGet(map, key, targetbuf) _Generic((key), \ |
480 */ |
| 816 CxHashKey: cx_map_remove_and_get, \ |
481 #define cxMapRemoveAndGet(map, key, targetbuf) cx_map_remove(map, CX_HASH_KEY(key), targetbuf) |
| 817 cxstring: cx_map_remove_and_get_cxstr, \ |
482 |
| 818 cxmutstr: cx_map_remove_and_get_mustr, \ |
483 |
| 819 char*: cx_map_remove_and_get_str, \ |
484 /** |
| 820 const char*: cx_map_remove_and_get_str) \ |
485 * Performs a deep clone of one map into another. |
| 821 (map, key, targetbuf) |
486 * |
| 822 |
487 * If the destination map already contains entries, the cloned entries |
| 823 #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 |
| 824 |
609 |
| 825 #endif // UCX_MAP_H |
610 #endif // UCX_MAP_H |