Sun, 21 May 2023 15:07:31 +0200
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; +}