ucx/cx/map.h

changeset 471
063a9f29098c
parent 440
7c4b9cba09ca
--- a/ucx/cx/map.h	Sat Feb 22 18:10:36 2025 +0100
+++ b/ucx/cx/map.h	Sun Feb 23 14:28:47 2025 +0100
@@ -51,6 +51,9 @@
 /** Type for a map entry. */
 typedef struct cx_map_entry_s CxMapEntry;
 
+/** Type for a map iterator. */
+typedef struct cx_map_iterator_s CxMapIterator;
+
 /** Type for map class definitions. */
 typedef struct cx_map_class_s cx_map_class;
 
@@ -65,6 +68,20 @@
 };
 
 /**
+ * A map entry.
+ */
+struct cx_map_entry_s {
+    /**
+     * A pointer to the key.
+     */
+    const CxHashKey *key;
+    /**
+     * A pointer to the value.
+     */
+    void *value;
+};
+
+/**
  * The type of iterator for a map.
  */
 enum cx_map_iterator_type {
@@ -83,6 +100,76 @@
 };
 
 /**
+ * Internal iterator struct - use CxMapIterator.
+ */
+struct cx_map_iterator_s {
+    /**
+     * Inherited common data for all iterators.
+     */
+    CX_ITERATOR_BASE;
+
+    /**
+     * Handle for the source map.
+     */
+    union {
+        /**
+         * Access for mutating iterators.
+         */
+        CxMap *m;
+        /**
+         * Access for normal iterators.
+         */
+        const CxMap *c;
+    } map;
+
+    /**
+     * Handle for the current element.
+     *
+     * @attention Depends on the map implementation, do not assume a type (better: do not use!).
+     */
+    void *elem;
+
+    /**
+     * Reserved memory for a map entry.
+     *
+     * If a map implementation uses an incompatible layout, the iterator needs something
+     * to point to during iteration which @em is compatible.
+     */
+    CxMapEntry entry;
+
+    /**
+     * Field for storing the current slot number.
+     *
+     * (Used internally)
+     */
+    size_t slot;
+
+    /**
+     * Counts the elements successfully.
+     * It usually does not denote a stable index within the map as it would be for arrays.
+     */
+    size_t index;
+
+    /**
+     * The size of a value stored in this map.
+     */
+    size_t elem_size;
+
+    /**
+     * May contain the total number of elements, if known.
+     * Set to @c SIZE_MAX when the total number is unknown during iteration.
+     *
+     * @remark The UCX implementations of #CxMap always know the number of elements they store.
+     */
+    size_t elem_count;
+
+    /**
+     * The type of this iterator.
+     */
+    enum cx_map_iterator_type type;
+};
+
+/**
  * The class definition for arbitrary maps.
  */
 struct cx_map_class_s {
@@ -132,21 +219,7 @@
     /**
      * Creates an iterator for this map.
      */
-    CxIterator (*iterator)(const CxMap *map, enum cx_map_iterator_type type);
-};
-
-/**
- * A map entry.
- */
-struct cx_map_entry_s {
-    /**
-     * A pointer to the key.
-     */
-    const CxHashKey *key;
-    /**
-     * A pointer to the value.
-     */
-    void *value;
+    CxMapIterator (*iterator)(const CxMap *map, enum cx_map_iterator_type type);
 };
 
 /**
@@ -157,59 +230,17 @@
  * You can use this is a placeholder for initializing CxMap pointers
  * for which you do not want to reserve memory right from the beginning.
  */
+cx_attr_export
 extern CxMap *const cxEmptyMap;
 
 /**
- * Advises the map to store copies of the objects (default mode of operation).
- *
- * Retrieving objects from this map will yield pointers to the copies stored
- * within this list.
- *
- * @param map the map
- * @see cxMapStorePointers()
- */
-cx_attr_nonnull
-static inline void cxMapStoreObjects(CxMap *map) {
-    map->collection.store_pointer = false;
-}
-
-/**
- * Advises the map to only store pointers to the objects.
- *
- * Retrieving objects from this list will yield the original pointers stored.
- *
- * @note This function forcibly sets the element size to the size of a pointer.
- * Invoking this function on a non-empty map that already stores copies of
- * objects is undefined.
- *
- * @param map the map
- * @see cxMapStoreObjects()
- */
-cx_attr_nonnull
-static inline void cxMapStorePointers(CxMap *map) {
-    map->collection.store_pointer = true;
-    map->collection.elem_size = sizeof(void *);
-}
-
-/**
- * Returns true, if this map is storing pointers instead of the actual data.
- *
- * @param map
- * @return true, if this map is storing pointers
- * @see cxMapStorePointers()
- */
-cx_attr_nonnull
-static inline bool cxMapIsStoringPointers(const CxMap *map) {
-    return map->collection.store_pointer;
-}
-
-/**
  * Deallocates the memory of the specified map.
  *
  * Also calls the content destructor functions for each element, if specified.
  *
  * @param map the map to be freed
  */
+cx_attr_export
 void cxMapFree(CxMap *map);
 
 
@@ -239,6 +270,10 @@
 /**
  * Creates a value iterator for a map.
  *
+ * When the map is storing pointers, those pointers are returned.
+ * Otherwise, the iterator iterates over pointers to the memory within the map where the
+ * respective elements are stored.
+ *
  * @note An iterator iterates over all elements successively. Therefore, the order
  * highly depends on the map implementation and may change arbitrarily when the contents change.
  *
@@ -247,14 +282,15 @@
  */
 cx_attr_nonnull
 cx_attr_nodiscard
-static inline CxIterator cxMapIteratorValues(const CxMap *map) {
+static inline CxMapIterator cxMapIteratorValues(const CxMap *map) {
     return map->cl->iterator(map, CX_MAP_ITERATOR_VALUES);
 }
 
 /**
  * Creates a key iterator for a map.
  *
- * The elements of the iterator are keys of type CxHashKey.
+ * The elements of the iterator are keys of type CxHashKey and the pointer returned
+ * during iterator shall be treated as @c const @c CxHashKey* .
  *
  * @note An iterator iterates over all elements successively. Therefore, the order
  * highly depends on the map implementation and may change arbitrarily when the contents change.
@@ -264,14 +300,15 @@
  */
 cx_attr_nonnull
 cx_attr_nodiscard
-static inline CxIterator cxMapIteratorKeys(const CxMap *map) {
+static inline CxMapIterator cxMapIteratorKeys(const CxMap *map) {
     return map->cl->iterator(map, CX_MAP_ITERATOR_KEYS);
 }
 
 /**
  * Creates an iterator for a map.
  *
- * The elements of the iterator are key/value pairs of type CxMapEntry.
+ * The elements of the iterator are key/value pairs of type CxMapEntry and the pointer returned
+ * during iterator shall be treated as @c const @c CxMapEntry* .
  *
  * @note An iterator iterates over all elements successively. Therefore, the order
  * highly depends on the map implementation and may change arbitrarily when the contents change.
@@ -283,7 +320,7 @@
  */
 cx_attr_nonnull
 cx_attr_nodiscard
-static inline CxIterator cxMapIterator(const CxMap *map) {
+static inline CxMapIterator cxMapIterator(const CxMap *map) {
     return map->cl->iterator(map, CX_MAP_ITERATOR_PAIRS);
 }
 
@@ -291,6 +328,10 @@
 /**
  * Creates a mutating iterator over the values of a map.
  *
+ * When the map is storing pointers, those pointers are returned.
+ * Otherwise, the iterator iterates over pointers to the memory within the map where the
+ * respective elements are stored.
+ *
  * @note An iterator iterates over all elements successively. Therefore, the order
  * highly depends on the map implementation and may change arbitrarily when the contents change.
  *
@@ -299,12 +340,14 @@
  */
 cx_attr_nonnull
 cx_attr_nodiscard
-CxIterator cxMapMutIteratorValues(CxMap *map);
+cx_attr_export
+CxMapIterator cxMapMutIteratorValues(CxMap *map);
 
 /**
  * Creates a mutating iterator over the keys of a map.
  *
- * The elements of the iterator are keys of type CxHashKey.
+ * The elements of the iterator are keys of type CxHashKey and the pointer returned
+ * during iterator shall be treated as @c const @c CxHashKey* .
  *
  * @note An iterator iterates over all elements successively. Therefore, the order
  * highly depends on the map implementation and may change arbitrarily when the contents change.
@@ -314,12 +357,14 @@
  */
 cx_attr_nonnull
 cx_attr_nodiscard
-CxIterator cxMapMutIteratorKeys(CxMap *map);
+cx_attr_export
+CxMapIterator cxMapMutIteratorKeys(CxMap *map);
 
 /**
  * Creates a mutating iterator for a map.
  *
- * The elements of the iterator are key/value pairs of type CxMapEntry.
+ * The elements of the iterator are key/value pairs of type CxMapEntry and the pointer returned
+ * during iterator shall be treated as @c const @c CxMapEntry* .
  *
  * @note An iterator iterates over all elements successively. Therefore, the order
  * highly depends on the map implementation and may change arbitrarily when the contents change.
@@ -331,7 +376,8 @@
  */
 cx_attr_nonnull
 cx_attr_nodiscard
-CxIterator cxMapMutIterator(CxMap *map);
+cx_attr_export
+CxMapIterator cxMapMutIterator(CxMap *map);
 
 #ifdef __cplusplus
 } // end the extern "C" block here, because we want to start overloading
@@ -538,6 +584,8 @@
  * Puts a key/value-pair into the map.
  *
  * A possible existing value will be overwritten.
+ * If destructor functions are specified, they are called for
+ * the overwritten element.
  *
  * If this map is storing pointers, the @p value pointer is written
  * to the map. Otherwise, the memory is copied from @p value with
@@ -749,7 +797,7 @@
  * Removes a key/value-pair from the map by using the key.
  *
  * This function will copy the contents of the removed element
- * to the target buffer must be guaranteed to be large enough
+ * to the target buffer, which must be guaranteed to be large enough
  * to hold the element (the map's element size).
  * The destructor functions, if any, will @em not be called.
  *
@@ -761,8 +809,7 @@
  * @param targetbuf (@c void*) the buffer where the element shall be copied to
  * @retval zero success
  * @retval non-zero the key was not found
- * 
- * @see cxMapStorePointers()
+ *
  * @see cxMapRemove()
  */
 #define cxMapRemoveAndGet(map, key, targetbuf) _Generic((key), \

mercurial