ucx/cx/map.h

changeset 113
dde28a806552
parent 112
c3f2f16fa4b8
equal deleted inserted replaced
112:c3f2f16fa4b8 113:dde28a806552
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);
231 * Writing to that map is not allowed. 216 * Writing to that map is not allowed.
232 * 217 *
233 * You can use this as 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
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
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 299
382 /** 300 /**
383 * Puts a key/value-pair into the map. 301 * Puts a key/value-pair into the map.
384 * 302 *
385 * A possible existing value will be overwritten. 303 * A possible existing value will be overwritten.
398 * @retval zero success 316 * @retval zero success
399 * @retval non-zero value on memory allocation failure 317 * @retval non-zero value on memory allocation failure
400 * @see cxMapPut() 318 * @see cxMapPut()
401 */ 319 */
402 cx_attr_nonnull 320 cx_attr_nonnull
403 static inline int cx_map_put( 321 CX_EXPORT int cx_map_put(CxMap *map, CxHashKey key, void *value);
404 CxMap *map,
405 CxHashKey key,
406 void *value
407 ) {
408 return map->cl->put(map, key, value) == NULL;
409 }
410 322
411 /** 323 /**
412 * Puts a key/value-pair into the map. 324 * Puts a key/value-pair into the map.
413 * 325 *
414 * A possible existing value will be overwritten. 326 * A possible existing value will be overwritten.
448 * @retval zero success 360 * @retval zero success
449 * @retval non-zero value on memory allocation failure 361 * @retval non-zero value on memory allocation failure
450 * @see cxMapEmplace() 362 * @see cxMapEmplace()
451 */ 363 */
452 cx_attr_nonnull 364 cx_attr_nonnull
453 static inline void *cx_map_emplace( 365 CX_EXPORT void *cx_map_emplace(CxMap *map, CxHashKey key);
454 CxMap *map,
455 CxHashKey key
456 ) {
457 return map->cl->put(map, key, NULL);
458 }
459 366
460 /** 367 /**
461 * Allocates memory for a value in the map associated with the specified key. 368 * Allocates memory for a value in the map associated with the specified key.
462 * 369 *
463 * A possible existing value will be overwritten. 370 * A possible existing value will be overwritten.
488 * @param map the map 395 * @param map the map
489 * @param key the key 396 * @param key the key
490 * @return the value 397 * @return the value
491 * @see cxMapGet() 398 * @see cxMapGet()
492 */ 399 */
493 cx_attr_nonnull 400 cx_attr_nonnull cx_attr_nodiscard
494 cx_attr_nodiscard 401 CX_EXPORT void *cx_map_get(const CxMap *map, CxHashKey key);
495 static inline void *cx_map_get(
496 const CxMap *map,
497 CxHashKey key
498 ) {
499 return map->cl->get(map, key);
500 }
501 402
502 /** 403 /**
503 * Retrieves a value by using a key. 404 * Retrieves a value by using a key.
504 * 405 *
505 * If this map is storing pointers, the stored pointer is returned. 406 * If this map is storing pointers, the stored pointer is returned.
506 * Otherwise, a pointer to the element within the map's memory 407 * Otherwise, a pointer to the element within the map's memory
507 * is returned (which is valid as long as the element stays in the map). 408 * is returned (which is valid as long as the element stays in the map).
508 * 409 *
509 * @param map (@c CxMap*) the map 410 * @param map (@c CxMap*) the map
510 * @param key (any supported key type) the key 411 * @param key (any supported key type) the key
511 * @return (@c void*) the value 412 * @return (@c void*) the value or @c NULL when no value with that @p key exists
512 * @see CX_HASH_KEY() 413 * @see CX_HASH_KEY()
513 */ 414 */
514 #define cxMapGet(map, key) cx_map_get(map, CX_HASH_KEY(key)) 415 #define cxMapGet(map, key) cx_map_get(map, CX_HASH_KEY(key))
416
417 /**
418 * Checks if a map contains a specific key.
419 *
420 * @param map (@c CxMap*) the map
421 * @param key (any supported key type) the key
422 * @retval true if the key exists in the map
423 * @retval false if the key does not exist in the map
424 * @see CX_HASH_KEY()
425 */
426 #define cxMapContains(map, key) (cxMapGet(map, key) != NULL)
515 427
516 /** 428 /**
517 * 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.
518 * 430 *
519 * Invokes the destructor functions, if any, on the removed element if and only if the 431 * Invokes the destructor functions, if any, on the removed element if and only if the
527 * 439 *
528 * @see cxMapRemove() 440 * @see cxMapRemove()
529 * @see cxMapRemoveAndGet() 441 * @see cxMapRemoveAndGet()
530 */ 442 */
531 cx_attr_nonnull_arg(1) 443 cx_attr_nonnull_arg(1)
532 static inline int cx_map_remove( 444 CX_EXPORT int cx_map_remove(CxMap *map, CxHashKey key, void *targetbuf);
533 CxMap *map,
534 CxHashKey key,
535 void *targetbuf
536 ) {
537 return map->cl->remove(map, key, targetbuf);
538 }
539 445
540 /** 446 /**
541 * Removes a key/value-pair from the map by using the key. 447 * Removes a key/value-pair from the map by using the key.
542 * 448 *
543 * Always invokes the destructor functions, if any, on the removed element. 449 * Always invokes the destructor functions, if any, on the removed element.
572 * @see cxMapRemove() 478 * @see cxMapRemove()
573 * @see CX_HASH_KEY() 479 * @see CX_HASH_KEY()
574 */ 480 */
575 #define cxMapRemoveAndGet(map, key, targetbuf) cx_map_remove(map, CX_HASH_KEY(key), targetbuf) 481 #define cxMapRemoveAndGet(map, key, targetbuf) cx_map_remove(map, CX_HASH_KEY(key), targetbuf)
576 482
483
484 /**
485 * Performs a deep clone of one map into another.
486 *
487 * If the destination map already contains entries, the cloned entries
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 /**
607 * Performs a shallow clone of one map into another.
608 *
609 * This function uses the default allocator, if needed, and performs
610 * shallow clones with @c memcpy().
611 *
612 * If the destination map already contains entries, the cloned entries
613 * are added to that map, possibly overwriting existing elements when
614 * the keys already exist.
615 *
616 * When elements in the destination map need to be replaced, any destructor
617 * function is called on the replaced elements before replacing them.
618 *
619 * @attention If the cloned elements need to be destroyed by a destructor
620 * function, you must make sure that the destination map also uses this
621 * destructor function.
622 *
623 * @param dst the destination map
624 * @param src the source map
625 * @retval zero when all elements were successfully cloned
626 * @retval non-zero when an allocation error occurred
627 * @see cxMapClone()
628 */
629 cx_attr_nonnull
630 CX_EXPORT int cxMapCloneSimple(CxMap *dst, const CxMap *src);
631
632 /**
633 * Clones entries of a map if their key is not present in another map.
634 *
635 * This function uses the default allocator, if needed, and performs
636 * shallow clones with @c memcpy().
637 *
638 * @param dst the destination map
639 * @param minuend the map to subtract the entries from
640 * @param subtrahend the map containing the elements to be subtracted
641 * @retval zero when the elements were successfully cloned
642 * @retval non-zero when an allocation error occurred
643 */
644 cx_attr_nonnull
645 CX_EXPORT int cxMapDifferenceSimple(CxMap *dst, const CxMap *minuend, const CxMap *subtrahend);
646
647 /**
648 * Clones entries of a map if their key is not present in a list.
649 *
650 * This function uses the default allocator, if needed, and performs
651 * shallow clones with @c memcpy().
652 *
653 * Note that the list must contain keys of type @c CxKey
654 * (or pointers to such keys) and must use @c cx_hash_key_cmp
655 * as the compare function.
656 * Generic key types cannot be processed in this case.
657 *
658 * @param dst the destination map
659 * @param src the source map
660 * @param keys the list of @c CxKey items
661 * @retval zero when the elements were successfully cloned
662 * @retval non-zero when an allocation error occurred
663 * @see cxMapListDifference()
664 */
665 cx_attr_nonnull
666 CX_EXPORT int cxMapListDifferenceSimple(CxMap *dst, const CxMap *src, const CxList *keys);
667
668
669 /**
670 * Clones entries of a map only if their key is present in another map.
671 *
672 * This function uses the default allocator, if needed, and performs
673 * shallow clones with @c memcpy().
674 *
675 * @param dst the destination map
676 * @param src the map to clone the entries from
677 * @param other the map to check for existence of the keys
678 * @retval zero when the elements were successfully cloned
679 * @retval non-zero when an allocation error occurred
680 */
681 cx_attr_nonnull
682 CX_EXPORT int cxMapIntersectionSimple(CxMap *dst, const CxMap *src, const CxMap *other);
683
684 /**
685 * Clones entries of a map only if their key is present in a list.
686 *
687 * This function uses the default allocator, if needed, and performs
688 * shallow clones with @c memcpy().
689 *
690 * Note that the list must contain keys of type @c CxKey
691 * (or pointers to such keys) and must use @c cx_hash_key_cmp
692 * as the compare function.
693 * Generic key types cannot be processed in this case.
694 *
695 * @param dst the destination map
696 * @param src the source map
697 * @param keys the list of @c CxKey items
698 * @retval zero when the elements were successfully cloned
699 * @retval non-zero when an allocation error occurred
700 */
701 cx_attr_nonnull
702 CX_EXPORT int cxMapListIntersectionSimple(CxMap *dst, const CxMap *src, const CxList *keys);
703
704 /**
705 * Clones entries into a map if their key does not exist yet.
706 *
707 * This function uses the default allocator, if needed, and performs
708 * shallow clones with @c memcpy().
709 *
710 * If you want to calculate the union of two maps into a fresh new map,
711 * you can proceed as follows:
712 * 1. Clone the first map into a fresh, empty map.
713 * 2. Use this function to clone the second map into the result from step 1.
714 *
715 * @param dst the destination map
716 * @param src the map to clone the entries from
717 * @retval zero when the elements were successfully cloned
718 * @retval non-zero when an allocation error occurred
719 */
720 cx_attr_nonnull
721 CX_EXPORT int cxMapUnionSimple(CxMap *dst, const CxMap *src);
722
577 #ifdef __cplusplus 723 #ifdef __cplusplus
578 } // extern "C" 724 } // extern "C"
579 #endif 725 #endif
580 726
581 #endif // UCX_MAP_H 727 #endif // UCX_MAP_H

mercurial