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
     1.1 --- a/src/cx/map.h	Sun May 21 14:56:10 2023 +0200
     1.2 +++ b/src/cx/map.h	Sun May 21 15:07:31 2023 +0200
     1.3 @@ -63,6 +63,24 @@
     1.4  };
     1.5  
     1.6  /**
     1.7 + * The type of iterator for a map.
     1.8 + */
     1.9 +enum cx_map_iterator_type {
    1.10 +    /**
    1.11 +     * Iterates over key/value pairs.
    1.12 +     */
    1.13 +    CX_MAP_ITERATOR_PAIRS,
    1.14 +    /**
    1.15 +     * Iterates over keys only.
    1.16 +     */
    1.17 +    CX_MAP_ITERATOR_KEYS,
    1.18 +    /**
    1.19 +     * Iterates over values only.
    1.20 +     */
    1.21 +    CX_MAP_ITERATOR_VALUES
    1.22 +};
    1.23 +
    1.24 +/**
    1.25   * The class definition for arbitrary maps.
    1.26   */
    1.27  struct cx_map_class_s {
    1.28 @@ -108,40 +126,10 @@
    1.29      );
    1.30  
    1.31      /**
    1.32 -     * Iterator over the key/value pairs.
    1.33 +     * Creates an iterator for this map.
    1.34       */
    1.35      __attribute__((__nonnull__, __warn_unused_result__))
    1.36 -    CxIterator (*iterator)(CxMap const *map);
    1.37 -
    1.38 -    /**
    1.39 -     * Iterator over the keys.
    1.40 -     */
    1.41 -    __attribute__((__nonnull__, __warn_unused_result__))
    1.42 -    CxIterator (*iterator_keys)(CxMap const *map);
    1.43 -
    1.44 -    /**
    1.45 -     * Iterator over the values.
    1.46 -     */
    1.47 -    __attribute__((__nonnull__, __warn_unused_result__))
    1.48 -    CxIterator (*iterator_values)(CxMap const *map);
    1.49 -
    1.50 -    /**
    1.51 -     * Mutating iterator over the key/value pairs.
    1.52 -     */
    1.53 -    __attribute__((__nonnull__, __warn_unused_result__))
    1.54 -    CxMutIterator (*mut_iterator)(CxMap *map);
    1.55 -
    1.56 -    /**
    1.57 -     * Mutating iterator over the keys.
    1.58 -     */
    1.59 -    __attribute__((__nonnull__, __warn_unused_result__))
    1.60 -    CxMutIterator (*mut_iterator_keys)(CxMap *map);
    1.61 -
    1.62 -    /**
    1.63 -     * Mutating iterator over the values.
    1.64 -     */
    1.65 -    __attribute__((__nonnull__, __warn_unused_result__))
    1.66 -    CxMutIterator (*mut_iterator_values)(CxMap *map);
    1.67 +    CxIterator (*iterator)(CxMap const *map, enum cx_map_iterator_type type);
    1.68  };
    1.69  
    1.70  /**
    1.71 @@ -228,7 +216,7 @@
    1.72   */
    1.73  __attribute__((__nonnull__, __warn_unused_result__))
    1.74  static inline CxIterator cxMapIteratorValues(CxMap *map) {
    1.75 -    return map->cl->iterator_values(map);
    1.76 +    return map->cl->iterator(map, CX_MAP_ITERATOR_VALUES);
    1.77  }
    1.78  
    1.79  /**
    1.80 @@ -244,7 +232,7 @@
    1.81   */
    1.82  __attribute__((__nonnull__, __warn_unused_result__))
    1.83  static inline CxIterator cxMapIteratorKeys(CxMap *map) {
    1.84 -    return map->cl->iterator_keys(map);
    1.85 +    return map->cl->iterator(map, CX_MAP_ITERATOR_KEYS);
    1.86  }
    1.87  
    1.88  /**
    1.89 @@ -262,7 +250,7 @@
    1.90   */
    1.91  __attribute__((__nonnull__, __warn_unused_result__))
    1.92  static inline CxIterator cxMapIterator(CxMap *map) {
    1.93 -    return map->cl->iterator(map);
    1.94 +    return map->cl->iterator(map, CX_MAP_ITERATOR_PAIRS);
    1.95  }
    1.96  
    1.97  
    1.98 @@ -276,9 +264,7 @@
    1.99   * @return an iterator for the currently stored values
   1.100   */
   1.101  __attribute__((__nonnull__, __warn_unused_result__))
   1.102 -static inline CxMutIterator cxMapMutIteratorValues(CxMap *map) {
   1.103 -    return map->cl->mut_iterator_values(map);
   1.104 -}
   1.105 +CxMutIterator cxMapMutIteratorValues(CxMap *map);
   1.106  
   1.107  /**
   1.108   * Creates a mutating iterator over the keys of a map.
   1.109 @@ -292,9 +278,7 @@
   1.110   * @return an iterator for the currently stored keys
   1.111   */
   1.112  __attribute__((__nonnull__, __warn_unused_result__))
   1.113 -static inline CxMutIterator cxMapMutIteratorKeys(CxMap *map) {
   1.114 -    return map->cl->mut_iterator_keys(map);
   1.115 -}
   1.116 +CxMutIterator cxMapMutIteratorKeys(CxMap *map);
   1.117  
   1.118  /**
   1.119   * Creates a mutating iterator for a map.
   1.120 @@ -310,9 +294,7 @@
   1.121   * @see cxMapMutIteratorValues()
   1.122   */
   1.123  __attribute__((__nonnull__, __warn_unused_result__))
   1.124 -static inline CxMutIterator cxMapMutIterator(CxMap *map) {
   1.125 -    return map->cl->mut_iterator(map);
   1.126 -}
   1.127 +CxMutIterator cxMapMutIterator(CxMap *map);
   1.128  
   1.129  #ifdef __cplusplus
   1.130  } // end the extern "C" block here, because we want to start overloading
     2.1 --- a/src/hash_map.c	Sun May 21 14:56:10 2023 +0200
     2.2 +++ b/src/hash_map.c	Sun May 21 15:07:31 2023 +0200
     2.3 @@ -26,10 +26,12 @@
     2.4   * POSSIBILITY OF SUCH DAMAGE.
     2.5   */
     2.6  
     2.7 -#include <string.h>
     2.8  #include "cx/hash_map.h"
     2.9  #include "cx/utils.h"
    2.10  
    2.11 +#include <string.h>
    2.12 +#include <assert.h>
    2.13 +
    2.14  struct cx_hash_map_element_s {
    2.15      /** A pointer to the next element in the current bucket. */
    2.16      struct cx_hash_map_element_s *next;
    2.17 @@ -334,13 +336,30 @@
    2.18      }
    2.19  }
    2.20  
    2.21 -static CxIterator cx_hash_map_iterator(CxMap const *map) {
    2.22 +static CxIterator cx_hash_map_iterator(
    2.23 +        CxMap const *map,
    2.24 +        enum cx_map_iterator_type type
    2.25 +) {
    2.26      CxIterator iter;
    2.27  
    2.28      iter.src_handle = map;
    2.29      iter.base.valid = cx_hash_map_iter_valid;
    2.30      iter.base.next = cx_hash_map_iter_next;
    2.31 -    iter.base.current = cx_hash_map_iter_current_entry;
    2.32 +
    2.33 +    switch (type) {
    2.34 +        case CX_MAP_ITERATOR_PAIRS:
    2.35 +            iter.base.current = cx_hash_map_iter_current_entry;
    2.36 +            break;
    2.37 +        case CX_MAP_ITERATOR_KEYS:
    2.38 +            iter.base.current = cx_hash_map_iter_current_key;
    2.39 +            break;
    2.40 +        case CX_MAP_ITERATOR_VALUES:
    2.41 +            iter.base.current = cx_hash_map_iter_current_value;
    2.42 +            break;
    2.43 +        default:
    2.44 +            assert(false);
    2.45 +    }
    2.46 +
    2.47      iter.base.flag_removal = cx_hash_map_iter_flag_rm;
    2.48      iter.base.remove = false;
    2.49      iter.base.mutating = false;
    2.50 @@ -370,40 +389,6 @@
    2.51      return iter;
    2.52  }
    2.53  
    2.54 -static CxIterator cx_hash_map_iterator_keys(CxMap const *map) {
    2.55 -    CxIterator iter = cx_hash_map_iterator(map);
    2.56 -    iter.base.current = cx_hash_map_iter_current_key;
    2.57 -    return iter;
    2.58 -}
    2.59 -
    2.60 -static CxIterator cx_hash_map_iterator_values(CxMap const *map) {
    2.61 -    CxIterator iter = cx_hash_map_iterator(map);
    2.62 -    iter.base.current = cx_hash_map_iter_current_value;
    2.63 -    return iter;
    2.64 -}
    2.65 -
    2.66 -static CxMutIterator cx_hash_map_mut_iterator(CxMap *map) {
    2.67 -    CxIterator it = cx_hash_map_iterator(map);
    2.68 -    it.base.mutating = true;
    2.69 -
    2.70 -    // we know the iterators share the same memory layout
    2.71 -    CxMutIterator iter;
    2.72 -    memcpy(&iter, &it, sizeof(CxMutIterator));
    2.73 -    return iter;
    2.74 -}
    2.75 -
    2.76 -static CxMutIterator cx_hash_map_mut_iterator_keys(CxMap *map) {
    2.77 -    CxMutIterator iter = cx_hash_map_mut_iterator(map);
    2.78 -    iter.base.current = cx_hash_map_iter_current_key;
    2.79 -    return iter;
    2.80 -}
    2.81 -
    2.82 -static CxMutIterator cx_hash_map_mut_iterator_values(CxMap *map) {
    2.83 -    CxMutIterator iter = cx_hash_map_mut_iterator(map);
    2.84 -    iter.base.current = cx_hash_map_iter_current_value;
    2.85 -    return iter;
    2.86 -}
    2.87 -
    2.88  static cx_map_class cx_hash_map_class = {
    2.89          cx_hash_map_destructor,
    2.90          cx_hash_map_clear,
    2.91 @@ -411,11 +396,6 @@
    2.92          cx_hash_map_get,
    2.93          cx_hash_map_remove,
    2.94          cx_hash_map_iterator,
    2.95 -        cx_hash_map_iterator_keys,
    2.96 -        cx_hash_map_iterator_values,
    2.97 -        cx_hash_map_mut_iterator,
    2.98 -        cx_hash_map_mut_iterator_keys,
    2.99 -        cx_hash_map_mut_iterator_values,
   2.100  };
   2.101  
   2.102  CxMap *cxHashMapCreate(
     3.1 --- a/src/map.c	Sun May 21 14:56:10 2023 +0200
     3.2 +++ b/src/map.c	Sun May 21 15:07:31 2023 +0200
     3.3 @@ -27,6 +27,7 @@
     3.4   */
     3.5  
     3.6  #include "cx/map.h"
     3.7 +#include <string.h>
     3.8  
     3.9  // <editor-fold desc="empty map implementation">
    3.10  
    3.11 @@ -45,32 +46,23 @@
    3.12      return false;
    3.13  }
    3.14  
    3.15 -static CxIterator cx_empty_map_iterator(struct cx_map_s const *map) {
    3.16 +static CxIterator cx_empty_map_iterator(
    3.17 +        struct cx_map_s const *map,
    3.18 +        __attribute__((__unused__)) enum cx_map_iterator_type type
    3.19 +) {
    3.20      CxIterator iter = {0};
    3.21      iter.src_handle = map;
    3.22      iter.base.valid = cx_empty_map_iter_valid;
    3.23      return iter;
    3.24  }
    3.25  
    3.26 -static CxMutIterator cx_empty_map_miterator(struct cx_map_s *map) {
    3.27 -    CxMutIterator iter = {0};
    3.28 -    iter.src_handle = map;
    3.29 -    iter.base.valid = cx_empty_map_iter_valid;
    3.30 -    return iter;
    3.31 -}
    3.32 -
    3.33  static struct cx_map_class_s cx_empty_map_class = {
    3.34 -    cx_empty_map_noop,
    3.35 -    cx_empty_map_noop,
    3.36 -    NULL,
    3.37 -    cx_empty_map_get,
    3.38 -    NULL,
    3.39 -    cx_empty_map_iterator,
    3.40 -    cx_empty_map_iterator,
    3.41 -    cx_empty_map_iterator,
    3.42 -    cx_empty_map_miterator,
    3.43 -    cx_empty_map_miterator,
    3.44 -    cx_empty_map_miterator,
    3.45 +        cx_empty_map_noop,
    3.46 +        cx_empty_map_noop,
    3.47 +        NULL,
    3.48 +        cx_empty_map_get,
    3.49 +        NULL,
    3.50 +        cx_empty_map_iterator
    3.51  };
    3.52  
    3.53  CxMap cx_empty_map = {
    3.54 @@ -85,6 +77,36 @@
    3.55          &cx_empty_map_class
    3.56  };
    3.57  
    3.58 -CxMap * const cxEmptyMap = &cx_empty_map;
    3.59 +CxMap *const cxEmptyMap = &cx_empty_map;
    3.60  
    3.61  // </editor-fold>
    3.62 +
    3.63 +CxMutIterator cxMapMutIteratorValues(CxMap *map) {
    3.64 +    CxIterator it = map->cl->iterator(map, CX_MAP_ITERATOR_VALUES);
    3.65 +    it.base.mutating = true;
    3.66 +
    3.67 +    // we know the iterators share the same memory layout
    3.68 +    CxMutIterator iter;
    3.69 +    memcpy(&iter, &it, sizeof(CxMutIterator));
    3.70 +    return iter;
    3.71 +}
    3.72 +
    3.73 +CxMutIterator cxMapMutIteratorKeys(CxMap *map) {
    3.74 +    CxIterator it = map->cl->iterator(map, CX_MAP_ITERATOR_KEYS);
    3.75 +    it.base.mutating = true;
    3.76 +
    3.77 +    // we know the iterators share the same memory layout
    3.78 +    CxMutIterator iter;
    3.79 +    memcpy(&iter, &it, sizeof(CxMutIterator));
    3.80 +    return iter;
    3.81 +}
    3.82 +
    3.83 +CxMutIterator cxMapMutIterator(CxMap *map) {
    3.84 +    CxIterator it = map->cl->iterator(map, CX_MAP_ITERATOR_PAIRS);
    3.85 +    it.base.mutating = true;
    3.86 +
    3.87 +    // we know the iterators share the same memory layout
    3.88 +    CxMutIterator iter;
    3.89 +    memcpy(&iter, &it, sizeof(CxMutIterator));
    3.90 +    return iter;
    3.91 +}

mercurial