ucx/cx/map.h

branch
dav-2
changeset 889
42cdbf9bbd49
parent 886
da79af4baec8
equal deleted inserted replaced
887:26541c37b619 889:42cdbf9bbd49
39 #include "common.h" 39 #include "common.h"
40 #include "collection.h" 40 #include "collection.h"
41 #include "string.h" 41 #include "string.h"
42 #include "hash_key.h" 42 #include "hash_key.h"
43 43
44 #ifndef UCX_LIST_H
45 // forward-declare CxList
46 typedef struct cx_list_s CxList;
47 #endif
48
44 #ifdef __cplusplus 49 #ifdef __cplusplus
45 extern "C" { 50 extern "C" {
46 #endif 51 #endif
47 52
48 /** Type for the UCX map. */ 53 /** Type for the UCX map. */
109 CX_ITERATOR_BASE; 114 CX_ITERATOR_BASE;
110 115
111 /** 116 /**
112 * Handle for the source map. 117 * Handle for the source map.
113 */ 118 */
114 union { 119 CxMap *map;
115 /**
116 * Access for mutating iterators.
117 */
118 CxMap *m;
119 /**
120 * Access for normal iterators.
121 */
122 const CxMap *c;
123 } map;
124 120
125 /** 121 /**
126 * Handle for the current element. 122 * Handle for the current element.
127 * 123 *
128 * @attention Depends on the map implementation, do not assume a type (better: do not use!). 124 * @attention Depends on the map implementation, do not assume a type (better: do not use!).
187 * Add or overwrite an element. 183 * Add or overwrite an element.
188 * If the @p value is @c NULL, the implementation 184 * If the @p value is @c NULL, the implementation
189 * shall only allocate memory instead of adding an existing value to the map. 185 * shall only allocate memory instead of adding an existing value to the map.
190 * Returns a pointer to the allocated memory or @c NULL if allocation fails. 186 * Returns a pointer to the allocated memory or @c NULL if allocation fails.
191 */ 187 */
192 void *(*put)( 188 void *(*put)(CxMap *map, CxHashKey key, void *value);
193 CxMap *map,
194 CxHashKey key,
195 void *value
196 );
197 189
198 /** 190 /**
199 * Returns an element. 191 * Returns an element.
200 */ 192 */
201 void *(*get)( 193 void *(*get)(const CxMap *map, CxHashKey key);
202 const CxMap *map,
203 CxHashKey key
204 );
205 194
206 /** 195 /**
207 * Removes an element. 196 * Removes an element.
208 * 197 *
209 * Implementations SHALL check if @p targetbuf is set and copy the elements 198 * Implementations SHALL check if @p targetbuf is set and copy the elements
211 * When @p targetbuf is not set, the destructors SHALL be invoked. 200 * When @p targetbuf is not set, the destructors SHALL be invoked.
212 * 201 *
213 * The function SHALL return zero when the @p key was found and 202 * The function SHALL return zero when the @p key was found and
214 * non-zero, otherwise. 203 * non-zero, otherwise.
215 */ 204 */
216 int (*remove)( 205 int (*remove)(CxMap *map, CxHashKey key, void *targetbuf);
217 CxMap *map,
218 CxHashKey key,
219 void *targetbuf
220 );
221 206
222 /** 207 /**
223 * Creates an iterator for this map. 208 * Creates an iterator for this map.
224 */ 209 */
225 CxMapIterator (*iterator)(const CxMap *map, enum cx_map_iterator_type type); 210 CxMapIterator (*iterator)(const CxMap *map, enum cx_map_iterator_type type);
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

mercurial