Sat, 26 Nov 2022 16:58:41 +0100
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