simplify map class structure

Sun, 21 May 2023 15:07:31 +0200

author
Mike Becker <universe@uap-core.de>
date
Sun, 21 May 2023 15:07:31 +0200
changeset 709
1e8ba59e7911
parent 708
1caed6c9ba68
child 710
2dd409ed056f

simplify map class structure

src/cx/map.h file | annotate | diff | comparison | revisions
src/hash_map.c file | annotate | diff | comparison | revisions
src/map.c file | annotate | diff | comparison | revisions
--- a/src/cx/map.h	Sun May 21 14:56:10 2023 +0200
+++ b/src/cx/map.h	Sun May 21 15:07:31 2023 +0200
@@ -63,6 +63,24 @@
 };
 
 /**
+ * The type of iterator for a map.
+ */
+enum cx_map_iterator_type {
+    /**
+     * Iterates over key/value pairs.
+     */
+    CX_MAP_ITERATOR_PAIRS,
+    /**
+     * Iterates over keys only.
+     */
+    CX_MAP_ITERATOR_KEYS,
+    /**
+     * Iterates over values only.
+     */
+    CX_MAP_ITERATOR_VALUES
+};
+
+/**
  * The class definition for arbitrary maps.
  */
 struct cx_map_class_s {
@@ -108,40 +126,10 @@
     );
 
     /**
-     * Iterator over the key/value pairs.
-     */
-    __attribute__((__nonnull__, __warn_unused_result__))
-    CxIterator (*iterator)(CxMap const *map);
-
-    /**
-     * Iterator over the keys.
-     */
-    __attribute__((__nonnull__, __warn_unused_result__))
-    CxIterator (*iterator_keys)(CxMap const *map);
-
-    /**
-     * Iterator over the values.
+     * Creates an iterator for this map.
      */
     __attribute__((__nonnull__, __warn_unused_result__))
-    CxIterator (*iterator_values)(CxMap const *map);
-
-    /**
-     * Mutating iterator over the key/value pairs.
-     */
-    __attribute__((__nonnull__, __warn_unused_result__))
-    CxMutIterator (*mut_iterator)(CxMap *map);
-
-    /**
-     * Mutating iterator over the keys.
-     */
-    __attribute__((__nonnull__, __warn_unused_result__))
-    CxMutIterator (*mut_iterator_keys)(CxMap *map);
-
-    /**
-     * Mutating iterator over the values.
-     */
-    __attribute__((__nonnull__, __warn_unused_result__))
-    CxMutIterator (*mut_iterator_values)(CxMap *map);
+    CxIterator (*iterator)(CxMap const *map, enum cx_map_iterator_type type);
 };
 
 /**
@@ -228,7 +216,7 @@
  */
 __attribute__((__nonnull__, __warn_unused_result__))
 static inline CxIterator cxMapIteratorValues(CxMap *map) {
-    return map->cl->iterator_values(map);
+    return map->cl->iterator(map, CX_MAP_ITERATOR_VALUES);
 }
 
 /**
@@ -244,7 +232,7 @@
  */
 __attribute__((__nonnull__, __warn_unused_result__))
 static inline CxIterator cxMapIteratorKeys(CxMap *map) {
-    return map->cl->iterator_keys(map);
+    return map->cl->iterator(map, CX_MAP_ITERATOR_KEYS);
 }
 
 /**
@@ -262,7 +250,7 @@
  */
 __attribute__((__nonnull__, __warn_unused_result__))
 static inline CxIterator cxMapIterator(CxMap *map) {
-    return map->cl->iterator(map);
+    return map->cl->iterator(map, CX_MAP_ITERATOR_PAIRS);
 }
 
 
@@ -276,9 +264,7 @@
  * @return an iterator for the currently stored values
  */
 __attribute__((__nonnull__, __warn_unused_result__))
-static inline CxMutIterator cxMapMutIteratorValues(CxMap *map) {
-    return map->cl->mut_iterator_values(map);
-}
+CxMutIterator cxMapMutIteratorValues(CxMap *map);
 
 /**
  * Creates a mutating iterator over the keys of a map.
@@ -292,9 +278,7 @@
  * @return an iterator for the currently stored keys
  */
 __attribute__((__nonnull__, __warn_unused_result__))
-static inline CxMutIterator cxMapMutIteratorKeys(CxMap *map) {
-    return map->cl->mut_iterator_keys(map);
-}
+CxMutIterator cxMapMutIteratorKeys(CxMap *map);
 
 /**
  * Creates a mutating iterator for a map.
@@ -310,9 +294,7 @@
  * @see cxMapMutIteratorValues()
  */
 __attribute__((__nonnull__, __warn_unused_result__))
-static inline CxMutIterator cxMapMutIterator(CxMap *map) {
-    return map->cl->mut_iterator(map);
-}
+CxMutIterator cxMapMutIterator(CxMap *map);
 
 #ifdef __cplusplus
 } // end the extern "C" block here, because we want to start overloading
--- a/src/hash_map.c	Sun May 21 14:56:10 2023 +0200
+++ b/src/hash_map.c	Sun May 21 15:07:31 2023 +0200
@@ -26,10 +26,12 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
-#include <string.h>
 #include "cx/hash_map.h"
 #include "cx/utils.h"
 
+#include <string.h>
+#include <assert.h>
+
 struct cx_hash_map_element_s {
     /** A pointer to the next element in the current bucket. */
     struct cx_hash_map_element_s *next;
@@ -334,13 +336,30 @@
     }
 }
 
-static CxIterator cx_hash_map_iterator(CxMap const *map) {
+static CxIterator cx_hash_map_iterator(
+        CxMap const *map,
+        enum cx_map_iterator_type type
+) {
     CxIterator iter;
 
     iter.src_handle = map;
     iter.base.valid = cx_hash_map_iter_valid;
     iter.base.next = cx_hash_map_iter_next;
-    iter.base.current = cx_hash_map_iter_current_entry;
+
+    switch (type) {
+        case CX_MAP_ITERATOR_PAIRS:
+            iter.base.current = cx_hash_map_iter_current_entry;
+            break;
+        case CX_MAP_ITERATOR_KEYS:
+            iter.base.current = cx_hash_map_iter_current_key;
+            break;
+        case CX_MAP_ITERATOR_VALUES:
+            iter.base.current = cx_hash_map_iter_current_value;
+            break;
+        default:
+            assert(false);
+    }
+
     iter.base.flag_removal = cx_hash_map_iter_flag_rm;
     iter.base.remove = false;
     iter.base.mutating = false;
@@ -370,40 +389,6 @@
     return iter;
 }
 
-static CxIterator cx_hash_map_iterator_keys(CxMap const *map) {
-    CxIterator iter = cx_hash_map_iterator(map);
-    iter.base.current = cx_hash_map_iter_current_key;
-    return iter;
-}
-
-static CxIterator cx_hash_map_iterator_values(CxMap const *map) {
-    CxIterator iter = cx_hash_map_iterator(map);
-    iter.base.current = cx_hash_map_iter_current_value;
-    return iter;
-}
-
-static CxMutIterator cx_hash_map_mut_iterator(CxMap *map) {
-    CxIterator it = cx_hash_map_iterator(map);
-    it.base.mutating = true;
-
-    // we know the iterators share the same memory layout
-    CxMutIterator iter;
-    memcpy(&iter, &it, sizeof(CxMutIterator));
-    return iter;
-}
-
-static CxMutIterator cx_hash_map_mut_iterator_keys(CxMap *map) {
-    CxMutIterator iter = cx_hash_map_mut_iterator(map);
-    iter.base.current = cx_hash_map_iter_current_key;
-    return iter;
-}
-
-static CxMutIterator cx_hash_map_mut_iterator_values(CxMap *map) {
-    CxMutIterator iter = cx_hash_map_mut_iterator(map);
-    iter.base.current = cx_hash_map_iter_current_value;
-    return iter;
-}
-
 static cx_map_class cx_hash_map_class = {
         cx_hash_map_destructor,
         cx_hash_map_clear,
@@ -411,11 +396,6 @@
         cx_hash_map_get,
         cx_hash_map_remove,
         cx_hash_map_iterator,
-        cx_hash_map_iterator_keys,
-        cx_hash_map_iterator_values,
-        cx_hash_map_mut_iterator,
-        cx_hash_map_mut_iterator_keys,
-        cx_hash_map_mut_iterator_values,
 };
 
 CxMap *cxHashMapCreate(
--- a/src/map.c	Sun May 21 14:56:10 2023 +0200
+++ b/src/map.c	Sun May 21 15:07:31 2023 +0200
@@ -27,6 +27,7 @@
  */
 
 #include "cx/map.h"
+#include <string.h>
 
 // <editor-fold desc="empty map implementation">
 
@@ -45,32 +46,23 @@
     return false;
 }
 
-static CxIterator cx_empty_map_iterator(struct cx_map_s const *map) {
+static CxIterator cx_empty_map_iterator(
+        struct cx_map_s const *map,
+        __attribute__((__unused__)) enum cx_map_iterator_type type
+) {
     CxIterator iter = {0};
     iter.src_handle = map;
     iter.base.valid = cx_empty_map_iter_valid;
     return iter;
 }
 
-static CxMutIterator cx_empty_map_miterator(struct cx_map_s *map) {
-    CxMutIterator iter = {0};
-    iter.src_handle = map;
-    iter.base.valid = cx_empty_map_iter_valid;
-    return iter;
-}
-
 static struct cx_map_class_s cx_empty_map_class = {
-    cx_empty_map_noop,
-    cx_empty_map_noop,
-    NULL,
-    cx_empty_map_get,
-    NULL,
-    cx_empty_map_iterator,
-    cx_empty_map_iterator,
-    cx_empty_map_iterator,
-    cx_empty_map_miterator,
-    cx_empty_map_miterator,
-    cx_empty_map_miterator,
+        cx_empty_map_noop,
+        cx_empty_map_noop,
+        NULL,
+        cx_empty_map_get,
+        NULL,
+        cx_empty_map_iterator
 };
 
 CxMap cx_empty_map = {
@@ -85,6 +77,36 @@
         &cx_empty_map_class
 };
 
-CxMap * const cxEmptyMap = &cx_empty_map;
+CxMap *const cxEmptyMap = &cx_empty_map;
 
 // </editor-fold>
+
+CxMutIterator cxMapMutIteratorValues(CxMap *map) {
+    CxIterator it = map->cl->iterator(map, CX_MAP_ITERATOR_VALUES);
+    it.base.mutating = true;
+
+    // we know the iterators share the same memory layout
+    CxMutIterator iter;
+    memcpy(&iter, &it, sizeof(CxMutIterator));
+    return iter;
+}
+
+CxMutIterator cxMapMutIteratorKeys(CxMap *map) {
+    CxIterator it = map->cl->iterator(map, CX_MAP_ITERATOR_KEYS);
+    it.base.mutating = true;
+
+    // we know the iterators share the same memory layout
+    CxMutIterator iter;
+    memcpy(&iter, &it, sizeof(CxMutIterator));
+    return iter;
+}
+
+CxMutIterator cxMapMutIterator(CxMap *map) {
+    CxIterator it = map->cl->iterator(map, CX_MAP_ITERATOR_PAIRS);
+    it.base.mutating = true;
+
+    // we know the iterators share the same memory layout
+    CxMutIterator iter;
+    memcpy(&iter, &it, sizeof(CxMutIterator));
+    return iter;
+}

mercurial