add support for NULL in map iterators

Mon, 18 Aug 2025 23:06:27 +0200

author
Mike Becker <universe@uap-core.de>
date
Mon, 18 Aug 2025 23:06:27 +0200
changeset 1344
8afaeb395b3c
parent 1343
b2ba79f4cb62
child 1345
79a865252b16

add support for NULL in map iterators

CHANGELOG file | annotate | diff | comparison | revisions
docs/Writerside/topics/list.h.md file | annotate | diff | comparison | revisions
docs/Writerside/topics/map.h.md file | annotate | diff | comparison | revisions
src/cx/map.h file | annotate | diff | comparison | revisions
--- a/CHANGELOG	Mon Aug 18 23:00:55 2025 +0200
+++ b/CHANGELOG	Mon Aug 18 23:06:27 2025 +0200
@@ -21,7 +21,7 @@
  * changes grow strategy for the mempory pool to reduce reallocations
  * changes grow strategy for CxBuffer, which does now take the page size into account
  * changes the implementation of cx_strreplacen() for improved efficiency
- * changes all cxListIterator() without index to also accept NULL as list argument
+ * changes all cxListIterator() and cxMapIterator() family of functions to also accept NULL as argument
  * changes insert_element member function of CxList to accept NULL source and return a pointer to the inserted element
  * fixes critical memory overflow in the stack-based array reallocator (this unfortunately breaks the function signature)
  * fixes mempool implementation not supporting NULL as argument for realloc
--- a/docs/Writerside/topics/list.h.md	Mon Aug 18 23:00:55 2025 +0200
+++ b/docs/Writerside/topics/list.h.md	Mon Aug 18 23:06:27 2025 +0200
@@ -290,7 +290,7 @@
 The functions with `Mut` in are equivalently, except that they create a [mutating iterator](iterator.h.md#mutating-iterators).
 Removing elements via a mutating iterator will cause an invocation of the [destructor functions](collection.h.md#destructor-functions) for the removed element. 
 
-If is safe to specify an out-of-bounds index, or a `NULL` pointer, in which cases an iterator is returned for which `cxIteratorValid()` returns `false`, immediately.
+If is safe to specify an out-of-bounds index, or a `NULL` pointer, in which cases the returned iterator will behave like an iterator over an empty list.
 
 ## Reorder
 
--- a/docs/Writerside/topics/map.h.md	Mon Aug 18 23:00:55 2025 +0200
+++ b/docs/Writerside/topics/map.h.md	Mon Aug 18 23:06:27 2025 +0200
@@ -282,6 +282,9 @@
 If used, the `void*` elements the iterator yields, shall be directly the stored pointers.
 Otherwise, the iterator shall yield pointers to the map's memory where the value is stored.
 
+It is always safe to call the above functions on a `NULL`-pointer.
+In that case, the returned iterator will behave like an iterator over an empty map.
+
 ## Dispose
 
 ```C
--- a/src/cx/map.h	Mon Aug 18 23:00:55 2025 +0200
+++ b/src/cx/map.h	Mon Aug 18 23:06:27 2025 +0200
@@ -280,12 +280,12 @@
  * @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.
  *
- * @param map the map to create the iterator for
+ * @param map the map to create the iterator for (can be @c NULL)
  * @return an iterator for the currently stored values
  */
-cx_attr_nonnull
 cx_attr_nodiscard
 static inline CxMapIterator cxMapIteratorValues(const CxMap *map) {
+    if (map == NULL) map = cxEmptyMap;
     return map->cl->iterator(map, CX_MAP_ITERATOR_VALUES);
 }
 
@@ -298,12 +298,12 @@
  * @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.
  *
- * @param map the map to create the iterator for
+ * @param map the map to create the iterator for (can be @c NULL)
  * @return an iterator for the currently stored keys
  */
-cx_attr_nonnull
 cx_attr_nodiscard
 static inline CxMapIterator cxMapIteratorKeys(const CxMap *map) {
+    if (map == NULL) map = cxEmptyMap;
     return map->cl->iterator(map, CX_MAP_ITERATOR_KEYS);
 }
 
@@ -316,14 +316,14 @@
  * @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.
  *
- * @param map the map to create the iterator for
+ * @param map the map to create the iterator for (can be @c NULL)
  * @return an iterator for the currently stored entries
  * @see cxMapIteratorKeys()
  * @see cxMapIteratorValues()
  */
-cx_attr_nonnull
 cx_attr_nodiscard
 static inline CxMapIterator cxMapIterator(const CxMap *map) {
+    if (map == NULL) map = cxEmptyMap;
     return map->cl->iterator(map, CX_MAP_ITERATOR_PAIRS);
 }
 
@@ -338,10 +338,9 @@
  * @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.
  *
- * @param map the map to create the iterator for
+ * @param map the map to create the iterator for (can be @c NULL)
  * @return an iterator for the currently stored values
  */
-cx_attr_nonnull
 cx_attr_nodiscard
 cx_attr_export
 CxMapIterator cxMapMutIteratorValues(CxMap *map);
@@ -355,10 +354,9 @@
  * @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.
  *
- * @param map the map to create the iterator for
+ * @param map the map to create the iterator for (can be @c NULL)
  * @return an iterator for the currently stored keys
  */
-cx_attr_nonnull
 cx_attr_nodiscard
 cx_attr_export
 CxMapIterator cxMapMutIteratorKeys(CxMap *map);
@@ -372,12 +370,11 @@
  * @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.
  *
- * @param map the map to create the iterator for
+ * @param map the map to create the iterator for (can be @c NULL)
  * @return an iterator for the currently stored entries
  * @see cxMapMutIteratorKeys()
  * @see cxMapMutIteratorValues()
  */
-cx_attr_nonnull
 cx_attr_nodiscard
 cx_attr_export
 CxMapIterator cxMapMutIterator(CxMap *map);

mercurial