src/cx/map.h

Sat, 26 Nov 2022 16:58:41 +0100

author
Mike Becker <universe@uap-core.de>
date
Sat, 26 Nov 2022 16:58:41 +0100
changeset 630
ac5e7f789048
parent 564
5d8ad7a0ff71
child 658
56c62780582e
permissions
-rw-r--r--

separate iterators and mutating iterators

Trade tons of code duplication for const-correctness.

     1 /*
     2  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
     3  *
     4  * Copyright 2021 Mike Becker, Olaf Wintermann All rights reserved.
     5  *
     6  * Redistribution and use in source and binary forms, with or without
     7  * modification, are permitted provided that the following conditions are met:
     8  *
     9  *   1. Redistributions of source code must retain the above copyright
    10  *      notice, this list of conditions and the following disclaimer.
    11  *
    12  *   2. Redistributions in binary form must reproduce the above copyright
    13  *      notice, this list of conditions and the following disclaimer in the
    14  *      documentation and/or other materials provided with the distribution.
    15  *
    16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
    17  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    19  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
    20  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
    21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
    22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
    23  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
    24  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    25  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    26  * POSSIBILITY OF SUCH DAMAGE.
    27  */
    28 /**
    29  * \file map.h
    30  * \brief Interface for map implementations.
    31  * \author Mike Becker
    32  * \author Olaf Wintermann
    33  * \version 3.0
    34  * \copyright 2-Clause BSD License
    35  */
    37 #ifndef UCX_MAP_H
    38 #define UCX_MAP_H
    40 #include "common.h"
    41 #include "allocator.h"
    42 #include "iterator.h"
    43 #include "hash_key.h"
    45 #ifdef    __cplusplus
    46 extern "C" {
    47 #endif
    49 /** Type for the UCX map. */
    50 typedef struct cx_map_s CxMap;
    52 /** Type for a map entry. */
    53 typedef struct cx_map_entry_s CxMapEntry;
    55 /** Type for map class definitions. */
    56 typedef struct cx_map_class_s cx_map_class;
    58 /** Structure for the UCX map. */
    59 struct cx_map_s {
    60     /** The map class definition. */
    61     cx_map_class *cl;
    62     /** An allocator that is used for the map elements. */
    63     CxAllocator *allocator;
    64     /** The number of elements currently stored. */
    65     size_t size;
    66     // TODO: elemsize + a flag if values shall be copied to the map
    67 };
    69 /**
    70  * The class definition for arbitrary maps.
    71  */
    72 struct cx_map_class_s {
    73     /**
    74      * Deallocates the entire memory.
    75      */
    76     __attribute__((__nonnull__))
    77     void (*destructor)(struct cx_map_s *map);
    79     /**
    80      * Removes all elements.
    81      */
    82     __attribute__((__nonnull__))
    83     void (*clear)(struct cx_map_s *map);
    85     /**
    86      * Add or overwrite an element.
    87      */
    88     __attribute__((__nonnull__))
    89     int (*put)(
    90             CxMap *map,
    91             CxHashKey key,
    92             void *value
    93     );
    95     /**
    96      * Returns an element.
    97      */
    98     __attribute__((__nonnull__, __warn_unused_result__))
    99     void *(*get)(
   100             CxMap const *map,
   101             CxHashKey key
   102     );
   104     /**
   105      * Removes an element.
   106      */
   107     __attribute__((__nonnull__, __warn_unused_result__))
   108     void *(*remove)(
   109             CxMap *map,
   110             CxHashKey key
   111     );
   113     /**
   114      * Iterator over the key/value pairs.
   115      */
   116     __attribute__((__nonnull__, __warn_unused_result__))
   117     CxIterator (*iterator)(CxMap const *map);
   119     /**
   120      * Iterator over the keys.
   121      */
   122     __attribute__((__nonnull__, __warn_unused_result__))
   123     CxIterator (*iterator_keys)(CxMap const *map);
   125     /**
   126      * Iterator over the values.
   127      */
   128     __attribute__((__nonnull__, __warn_unused_result__))
   129     CxIterator (*iterator_values)(CxMap const *map);
   131     /**
   132      * Mutating iterator over the key/value pairs.
   133      */
   134     __attribute__((__nonnull__, __warn_unused_result__))
   135     CxMutIterator (*mut_iterator)(CxMap *map);
   137     /**
   138      * Mutating iterator over the keys.
   139      */
   140     __attribute__((__nonnull__, __warn_unused_result__))
   141     CxMutIterator (*mut_iterator_keys)(CxMap *map);
   143     /**
   144      * Mutating iterator over the values.
   145      */
   146     __attribute__((__nonnull__, __warn_unused_result__))
   147     CxMutIterator (*mut_iterator_values)(CxMap *map);
   148 };
   150 /**
   151  * A map entry.
   152  */
   153 struct cx_map_entry_s {
   154     /**
   155      * A pointer to the key.
   156      */
   157     CxHashKey const *key;
   158     /**
   159      * A pointer to the value.
   160      */
   161     void *value;
   162 };
   165 /**
   166  * Deallocates the memory of the specified map.
   167  *
   168  * @param map the map to be destroyed
   169  */
   170 __attribute__((__nonnull__))
   171 static inline void cxMapDestroy(CxMap *map) {
   172     // TODO: likely to add auto-free feature for contents in the future
   173     map->cl->destructor(map);
   174 }
   177 /**
   178  * Clears a map by removing all elements.
   179  *
   180  * @param map the map to be cleared
   181  */
   182 __attribute__((__nonnull__))
   183 static inline void cxMapClear(CxMap *map) {
   184     map->cl->clear(map);
   185 }
   187 /**
   188  * Puts a key/value-pair into the map.
   189  *
   190  * @param map the map
   191  * @param key the key
   192  * @param value the value
   193  * @return 0 on success, non-zero value on failure
   194  */
   195 __attribute__((__nonnull__))
   196 static inline int cxMapPut(
   197         CxMap *map,
   198         CxHashKey key,
   199         void *value
   200 ) {
   201     return map->cl->put(map, key, value);
   202 }
   204 /**
   205  * Retrieves a value by using a key.
   206  *
   207  * @param map the map
   208  * @param key the key
   209  * @return the value
   210  */
   211 __attribute__((__nonnull__, __warn_unused_result__))
   212 static inline void *cxMapGet(
   213         CxMap const *map,
   214         CxHashKey key
   215 ) {
   216     return map->cl->get(map, key);
   217 }
   219 /**
   220  * Removes a key/value-pair from the map by using the key.
   221  *
   222  * @param map the map
   223  * @param key the key
   224  * @return the removed value
   225  */
   226 __attribute__((__nonnull__, __warn_unused_result__))
   227 static inline void *cxMapRemove(
   228         CxMap *map,
   229         CxHashKey key
   230 ) {
   231     return map->cl->remove(map, key);
   232 }
   234 // TODO: set-like map operations (union, intersect, difference)
   236 /**
   237  * Creates a value iterator for a map.
   238  *
   239  * \note An iterator iterates over all elements successively. Therefore the order
   240  * highly depends on the map implementation and may change arbitrarily when the contents change.
   241  *
   242  * @param map the map to create the iterator for
   243  * @return an iterator for the currently stored values
   244  */
   245 __attribute__((__nonnull__, __warn_unused_result__))
   246 static inline CxIterator cxMapIteratorValues(CxMap *map) {
   247     return map->cl->iterator_values(map);
   248 }
   250 /**
   251  * Creates a key iterator for a map.
   252  *
   253  * The elements of the iterator are keys of type CxHashKey.
   254  *
   255  * \note An iterator iterates over all elements successively. Therefore the order
   256  * highly depends on the map implementation and may change arbitrarily when the contents change.
   257  *
   258  * @param map the map to create the iterator for
   259  * @return an iterator for the currently stored keys
   260  */
   261 __attribute__((__nonnull__, __warn_unused_result__))
   262 static inline CxIterator cxMapIteratorKeys(CxMap *map) {
   263     return map->cl->iterator_keys(map);
   264 }
   266 /**
   267  * Creates an iterator for a map.
   268  *
   269  * The elements of the iterator are key/value pairs of type CxMapEntry.
   270  *
   271  * \note An iterator iterates over all elements successively. Therefore the order
   272  * highly depends on the map implementation and may change arbitrarily when the contents change.
   273  *
   274  * @param map the map to create the iterator for
   275  * @return an iterator for the currently stored entries
   276  * @see cxMapIteratorKeys()
   277  * @see cxMapIteratorValues()
   278  */
   279 __attribute__((__nonnull__, __warn_unused_result__))
   280 static inline CxIterator cxMapIterator(CxMap *map) {
   281     return map->cl->iterator(map);
   282 }
   285 /**
   286  * Creates a mutating iterator over the values of a map.
   287  *
   288  * \note An iterator iterates over all elements successively. Therefore the order
   289  * highly depends on the map implementation and may change arbitrarily when the contents change.
   290  *
   291  * @param map the map to create the iterator for
   292  * @return an iterator for the currently stored values
   293  */
   294 __attribute__((__nonnull__, __warn_unused_result__))
   295 static inline CxMutIterator cxMapMutIteratorValues(CxMap *map) {
   296     return map->cl->mut_iterator_values(map);
   297 }
   299 /**
   300  * Creates a mutating iterator over the keys of a map.
   301  *
   302  * The elements of the iterator are keys of type CxHashKey.
   303  *
   304  * \note An iterator iterates over all elements successively. Therefore the order
   305  * highly depends on the map implementation and may change arbitrarily when the contents change.
   306  *
   307  * @param map the map to create the iterator for
   308  * @return an iterator for the currently stored keys
   309  */
   310 __attribute__((__nonnull__, __warn_unused_result__))
   311 static inline CxMutIterator cxMapMutIteratorKeys(CxMap *map) {
   312     return map->cl->mut_iterator_keys(map);
   313 }
   315 /**
   316  * Creates a mutating iterator for a map.
   317  *
   318  * The elements of the iterator are key/value pairs of type CxMapEntry.
   319  *
   320  * \note An iterator iterates over all elements successively. Therefore the order
   321  * highly depends on the map implementation and may change arbitrarily when the contents change.
   322  *
   323  * @param map the map to create the iterator for
   324  * @return an iterator for the currently stored entries
   325  * @see cxMapMutIteratorKeys()
   326  * @see cxMapMutIteratorValues()
   327  */
   328 __attribute__((__nonnull__, __warn_unused_result__))
   329 static inline CxMutIterator cxMapMutIterator(CxMap *map) {
   330     return map->cl->mut_iterator(map);
   331 }
   333 #ifdef    __cplusplus
   334 }
   335 #endif
   337 #endif // UCX_MAP_H

mercurial