Tue, 18 Apr 2023 18:01:41 +0200
add base collection members to map interface
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 "collection.h"
42 #include "hash_key.h"
44 #ifdef __cplusplus
45 extern "C" {
46 #endif
48 /** Type for the UCX map. */
49 typedef struct cx_map_s CxMap;
51 /** Type for a map entry. */
52 typedef struct cx_map_entry_s CxMapEntry;
54 /** Type for map class definitions. */
55 typedef struct cx_map_class_s cx_map_class;
57 /** Structure for the UCX map. */
58 struct cx_map_s {
59 CX_COLLECTION_MEMBERS
60 /** The map class definition. */
61 cx_map_class *cl;
62 };
64 /**
65 * The class definition for arbitrary maps.
66 */
67 struct cx_map_class_s {
68 /**
69 * Deallocates the entire memory.
70 */
71 __attribute__((__nonnull__))
72 void (*destructor)(struct cx_map_s *map);
74 /**
75 * Removes all elements.
76 */
77 __attribute__((__nonnull__))
78 void (*clear)(struct cx_map_s *map);
80 /**
81 * Add or overwrite an element.
82 */
83 __attribute__((__nonnull__))
84 int (*put)(
85 CxMap *map,
86 CxHashKey key,
87 void *value
88 );
90 /**
91 * Returns an element.
92 */
93 __attribute__((__nonnull__, __warn_unused_result__))
94 void *(*get)(
95 CxMap const *map,
96 CxHashKey key
97 );
99 /**
100 * Removes an element.
101 */
102 __attribute__((__nonnull__))
103 void *(*remove)(
104 CxMap *map,
105 CxHashKey key
106 );
108 /**
109 * Iterator over the key/value pairs.
110 */
111 __attribute__((__nonnull__, __warn_unused_result__))
112 CxIterator (*iterator)(CxMap const *map);
114 /**
115 * Iterator over the keys.
116 */
117 __attribute__((__nonnull__, __warn_unused_result__))
118 CxIterator (*iterator_keys)(CxMap const *map);
120 /**
121 * Iterator over the values.
122 */
123 __attribute__((__nonnull__, __warn_unused_result__))
124 CxIterator (*iterator_values)(CxMap const *map);
126 /**
127 * Mutating iterator over the key/value pairs.
128 */
129 __attribute__((__nonnull__, __warn_unused_result__))
130 CxMutIterator (*mut_iterator)(CxMap *map);
132 /**
133 * Mutating iterator over the keys.
134 */
135 __attribute__((__nonnull__, __warn_unused_result__))
136 CxMutIterator (*mut_iterator_keys)(CxMap *map);
138 /**
139 * Mutating iterator over the values.
140 */
141 __attribute__((__nonnull__, __warn_unused_result__))
142 CxMutIterator (*mut_iterator_values)(CxMap *map);
143 };
145 /**
146 * A map entry.
147 */
148 struct cx_map_entry_s {
149 /**
150 * A pointer to the key.
151 */
152 CxHashKey const *key;
153 /**
154 * A pointer to the value.
155 */
156 void *value;
157 };
159 /**
160 * Advises the map to store copies of the objects (default mode of operation).
161 *
162 * Retrieving objects from this map will yield pointers to the copies stored
163 * within this list.
164 *
165 * @param map the map
166 * @see cxMapStorePointers()
167 */
168 __attribute__((__nonnull__))
169 static inline void cxMapStoreObjects(CxMap *map) {
170 map->store_pointer = false;
171 }
173 /**
174 * Advises the map to only store pointers to the objects.
175 *
176 * Retrieving objects from this list will yield the original pointers stored.
177 *
178 * @note This function forcibly sets the element size to the size of a pointer.
179 * Invoking this function on a non-empty map that already stores copies of
180 * objects is undefined.
181 *
182 * @param map the map
183 * @see cxMapStoreObjects()
184 */
185 __attribute__((__nonnull__))
186 static inline void cxMapStorePointers(CxMap *map) {
187 map->store_pointer = true;
188 map->item_size = sizeof(void *);
189 }
192 /**
193 * Deallocates the memory of the specified map.
194 *
195 * @param map the map to be destroyed
196 */
197 __attribute__((__nonnull__))
198 static inline void cxMapDestroy(CxMap *map) {
199 // TODO: likely to add auto-free feature for contents in the future
200 map->cl->destructor(map);
201 }
204 /**
205 * Clears a map by removing all elements.
206 *
207 * @param map the map to be cleared
208 */
209 __attribute__((__nonnull__))
210 static inline void cxMapClear(CxMap *map) {
211 map->cl->clear(map);
212 }
214 /**
215 * Puts a key/value-pair into the map.
216 *
217 * @param map the map
218 * @param key the key
219 * @param value the value
220 * @return 0 on success, non-zero value on failure
221 */
222 __attribute__((__nonnull__))
223 static inline int cxMapPut(
224 CxMap *map,
225 CxHashKey key,
226 void *value
227 ) {
228 return map->cl->put(map, key, value);
229 }
231 /**
232 * Retrieves a value by using a key.
233 *
234 * @param map the map
235 * @param key the key
236 * @return the value
237 */
238 __attribute__((__nonnull__, __warn_unused_result__))
239 static inline void *cxMapGet(
240 CxMap const *map,
241 CxHashKey key
242 ) {
243 return map->cl->get(map, key);
244 }
246 /**
247 * Removes a key/value-pair from the map by using the key.
248 *
249 * If this map is storing pointers, you should make sure that the map
250 * is not the last location where this pointer is stored.
251 * Otherwise, use cxMapRemoveAndGet() to retrieve the pointer while
252 * removing it from the map.
253 *
254 * @param map the map
255 * @param key the key
256 * @see cxMapRemoveAndGet()
257 */
258 __attribute__((__nonnull__))
259 static inline void cxMapRemove(
260 CxMap *map,
261 CxHashKey key
262 ) {
263 (void) map->cl->remove(map, key);
264 }
266 /**
267 * Removes a key/value-pair from the map by using the key.
268 *
269 * This function should only be used when the map is storing pointers,
270 * in order to retrieve the pointer you are about to remove.
271 * In any other case, cxMapRemove() is sufficient.
272 *
273 * @param map the map
274 * @param key the key
275 * @return the stored pointer or \c NULL if either the key is not present
276 * in the map or the map is not storing pointers
277 * @see cxMapStorePointers()
278 */
279 __attribute__((__nonnull__, __warn_unused_result__))
280 static inline void *cxMapRemoveAndGet(
281 CxMap *map,
282 CxHashKey key
283 ) {
284 return map->cl->remove(map, key);
285 }
287 // TODO: set-like map operations (union, intersect, difference)
289 /**
290 * Creates a value iterator for a map.
291 *
292 * \note An iterator iterates over all elements successively. Therefore the order
293 * highly depends on the map implementation and may change arbitrarily when the contents change.
294 *
295 * @param map the map to create the iterator for
296 * @return an iterator for the currently stored values
297 */
298 __attribute__((__nonnull__, __warn_unused_result__))
299 static inline CxIterator cxMapIteratorValues(CxMap *map) {
300 return map->cl->iterator_values(map);
301 }
303 /**
304 * Creates a key iterator for a map.
305 *
306 * The elements of the iterator are keys of type CxHashKey.
307 *
308 * \note An iterator iterates over all elements successively. Therefore the order
309 * highly depends on the map implementation and may change arbitrarily when the contents change.
310 *
311 * @param map the map to create the iterator for
312 * @return an iterator for the currently stored keys
313 */
314 __attribute__((__nonnull__, __warn_unused_result__))
315 static inline CxIterator cxMapIteratorKeys(CxMap *map) {
316 return map->cl->iterator_keys(map);
317 }
319 /**
320 * Creates an iterator for a map.
321 *
322 * The elements of the iterator are key/value pairs of type CxMapEntry.
323 *
324 * \note An iterator iterates over all elements successively. Therefore the order
325 * highly depends on the map implementation and may change arbitrarily when the contents change.
326 *
327 * @param map the map to create the iterator for
328 * @return an iterator for the currently stored entries
329 * @see cxMapIteratorKeys()
330 * @see cxMapIteratorValues()
331 */
332 __attribute__((__nonnull__, __warn_unused_result__))
333 static inline CxIterator cxMapIterator(CxMap *map) {
334 return map->cl->iterator(map);
335 }
338 /**
339 * Creates a mutating iterator over the values of a map.
340 *
341 * \note An iterator iterates over all elements successively. Therefore the order
342 * highly depends on the map implementation and may change arbitrarily when the contents change.
343 *
344 * @param map the map to create the iterator for
345 * @return an iterator for the currently stored values
346 */
347 __attribute__((__nonnull__, __warn_unused_result__))
348 static inline CxMutIterator cxMapMutIteratorValues(CxMap *map) {
349 return map->cl->mut_iterator_values(map);
350 }
352 /**
353 * Creates a mutating iterator over the keys of a map.
354 *
355 * The elements of the iterator are keys of type CxHashKey.
356 *
357 * \note An iterator iterates over all elements successively. Therefore the order
358 * highly depends on the map implementation and may change arbitrarily when the contents change.
359 *
360 * @param map the map to create the iterator for
361 * @return an iterator for the currently stored keys
362 */
363 __attribute__((__nonnull__, __warn_unused_result__))
364 static inline CxMutIterator cxMapMutIteratorKeys(CxMap *map) {
365 return map->cl->mut_iterator_keys(map);
366 }
368 /**
369 * Creates a mutating iterator for a map.
370 *
371 * The elements of the iterator are key/value pairs of type CxMapEntry.
372 *
373 * \note An iterator iterates over all elements successively. Therefore the order
374 * highly depends on the map implementation and may change arbitrarily when the contents change.
375 *
376 * @param map the map to create the iterator for
377 * @return an iterator for the currently stored entries
378 * @see cxMapMutIteratorKeys()
379 * @see cxMapMutIteratorValues()
380 */
381 __attribute__((__nonnull__, __warn_unused_result__))
382 static inline CxMutIterator cxMapMutIterator(CxMap *map) {
383 return map->cl->mut_iterator(map);
384 }
386 #ifdef __cplusplus
387 }
388 #endif
390 #endif // UCX_MAP_H