49 typedef struct cx_map_s CxMap; |
49 typedef struct cx_map_s CxMap; |
50 |
50 |
51 /** Type for a map entry. */ |
51 /** Type for a map entry. */ |
52 typedef struct cx_map_entry_s CxMapEntry; |
52 typedef struct cx_map_entry_s CxMapEntry; |
53 |
53 |
|
54 /** Type for a map iterator. */ |
|
55 typedef struct cx_map_iterator_s CxMapIterator; |
|
56 |
54 /** Type for map class definitions. */ |
57 /** Type for map class definitions. */ |
55 typedef struct cx_map_class_s cx_map_class; |
58 typedef struct cx_map_class_s cx_map_class; |
56 |
59 |
57 /** Structure for the UCX map. */ |
60 /** Structure for the UCX map. */ |
58 struct cx_map_s { |
61 struct cx_map_s { |
78 CX_MAP_ITERATOR_KEYS, |
95 CX_MAP_ITERATOR_KEYS, |
79 /** |
96 /** |
80 * Iterates over values only. |
97 * Iterates over values only. |
81 */ |
98 */ |
82 CX_MAP_ITERATOR_VALUES |
99 CX_MAP_ITERATOR_VALUES |
|
100 }; |
|
101 |
|
102 /** |
|
103 * Internal iterator struct - use CxMapIterator. |
|
104 */ |
|
105 struct cx_map_iterator_s { |
|
106 /** |
|
107 * Inherited common data for all iterators. |
|
108 */ |
|
109 CX_ITERATOR_BASE; |
|
110 |
|
111 /** |
|
112 * Handle for the source map. |
|
113 */ |
|
114 union { |
|
115 /** |
|
116 * Access for mutating iterators. |
|
117 */ |
|
118 CxMap *m; |
|
119 /** |
|
120 * Access for normal iterators. |
|
121 */ |
|
122 const CxMap *c; |
|
123 } map; |
|
124 |
|
125 /** |
|
126 * Handle for the current element. |
|
127 * |
|
128 * @attention Depends on the map implementation, do not assume a type (better: do not use!). |
|
129 */ |
|
130 void *elem; |
|
131 |
|
132 /** |
|
133 * Reserved memory for a map entry. |
|
134 * |
|
135 * If a map implementation uses an incompatible layout, the iterator needs something |
|
136 * to point to during iteration which @em is compatible. |
|
137 */ |
|
138 CxMapEntry entry; |
|
139 |
|
140 /** |
|
141 * Field for storing the current slot number. |
|
142 * |
|
143 * (Used internally) |
|
144 */ |
|
145 size_t slot; |
|
146 |
|
147 /** |
|
148 * Counts the elements successfully. |
|
149 * It usually does not denote a stable index within the map as it would be for arrays. |
|
150 */ |
|
151 size_t index; |
|
152 |
|
153 /** |
|
154 * The size of a value stored in this map. |
|
155 */ |
|
156 size_t elem_size; |
|
157 |
|
158 /** |
|
159 * May contain the total number of elements, if known. |
|
160 * Set to @c SIZE_MAX when the total number is unknown during iteration. |
|
161 * |
|
162 * @remark The UCX implementations of #CxMap always know the number of elements they store. |
|
163 */ |
|
164 size_t elem_count; |
|
165 |
|
166 /** |
|
167 * The type of this iterator. |
|
168 */ |
|
169 enum cx_map_iterator_type type; |
83 }; |
170 }; |
84 |
171 |
85 /** |
172 /** |
86 * The class definition for arbitrary maps. |
173 * The class definition for arbitrary maps. |
87 */ |
174 */ |
130 ); |
217 ); |
131 |
218 |
132 /** |
219 /** |
133 * Creates an iterator for this map. |
220 * Creates an iterator for this map. |
134 */ |
221 */ |
135 CxIterator (*iterator)(const CxMap *map, enum cx_map_iterator_type type); |
222 CxMapIterator (*iterator)(const CxMap *map, enum cx_map_iterator_type type); |
136 }; |
|
137 |
|
138 /** |
|
139 * A map entry. |
|
140 */ |
|
141 struct cx_map_entry_s { |
|
142 /** |
|
143 * A pointer to the key. |
|
144 */ |
|
145 const CxHashKey *key; |
|
146 /** |
|
147 * A pointer to the value. |
|
148 */ |
|
149 void *value; |
|
150 }; |
223 }; |
151 |
224 |
152 /** |
225 /** |
153 * A shared instance of an empty map. |
226 * A shared instance of an empty map. |
154 * |
227 * |
155 * Writing to that map is not allowed. |
228 * Writing to that map is not allowed. |
156 * |
229 * |
157 * You can use this is a placeholder for initializing CxMap pointers |
230 * You can use this is a placeholder for initializing CxMap pointers |
158 * for which you do not want to reserve memory right from the beginning. |
231 * for which you do not want to reserve memory right from the beginning. |
159 */ |
232 */ |
|
233 cx_attr_export |
160 extern CxMap *const cxEmptyMap; |
234 extern CxMap *const cxEmptyMap; |
161 |
235 |
162 /** |
236 /** |
163 * Advises the map to store copies of the objects (default mode of operation). |
|
164 * |
|
165 * Retrieving objects from this map will yield pointers to the copies stored |
|
166 * within this list. |
|
167 * |
|
168 * @param map the map |
|
169 * @see cxMapStorePointers() |
|
170 */ |
|
171 cx_attr_nonnull |
|
172 static inline void cxMapStoreObjects(CxMap *map) { |
|
173 map->collection.store_pointer = false; |
|
174 } |
|
175 |
|
176 /** |
|
177 * Advises the map to only store pointers to the objects. |
|
178 * |
|
179 * Retrieving objects from this list will yield the original pointers stored. |
|
180 * |
|
181 * @note This function forcibly sets the element size to the size of a pointer. |
|
182 * Invoking this function on a non-empty map that already stores copies of |
|
183 * objects is undefined. |
|
184 * |
|
185 * @param map the map |
|
186 * @see cxMapStoreObjects() |
|
187 */ |
|
188 cx_attr_nonnull |
|
189 static inline void cxMapStorePointers(CxMap *map) { |
|
190 map->collection.store_pointer = true; |
|
191 map->collection.elem_size = sizeof(void *); |
|
192 } |
|
193 |
|
194 /** |
|
195 * Returns true, if this map is storing pointers instead of the actual data. |
|
196 * |
|
197 * @param map |
|
198 * @return true, if this map is storing pointers |
|
199 * @see cxMapStorePointers() |
|
200 */ |
|
201 cx_attr_nonnull |
|
202 static inline bool cxMapIsStoringPointers(const CxMap *map) { |
|
203 return map->collection.store_pointer; |
|
204 } |
|
205 |
|
206 /** |
|
207 * Deallocates the memory of the specified map. |
237 * Deallocates the memory of the specified map. |
208 * |
238 * |
209 * Also calls the content destructor functions for each element, if specified. |
239 * Also calls the content destructor functions for each element, if specified. |
210 * |
240 * |
211 * @param map the map to be freed |
241 * @param map the map to be freed |
212 */ |
242 */ |
|
243 cx_attr_export |
213 void cxMapFree(CxMap *map); |
244 void cxMapFree(CxMap *map); |
214 |
245 |
215 |
246 |
216 /** |
247 /** |
217 * Clears a map by removing all elements. |
248 * Clears a map by removing all elements. |
237 } |
268 } |
238 |
269 |
239 /** |
270 /** |
240 * Creates a value iterator for a map. |
271 * Creates a value iterator for a map. |
241 * |
272 * |
|
273 * When the map is storing pointers, those pointers are returned. |
|
274 * Otherwise, the iterator iterates over pointers to the memory within the map where the |
|
275 * respective elements are stored. |
|
276 * |
242 * @note An iterator iterates over all elements successively. Therefore, the order |
277 * @note An iterator iterates over all elements successively. Therefore, the order |
243 * highly depends on the map implementation and may change arbitrarily when the contents change. |
278 * highly depends on the map implementation and may change arbitrarily when the contents change. |
244 * |
279 * |
245 * @param map the map to create the iterator for |
280 * @param map the map to create the iterator for |
246 * @return an iterator for the currently stored values |
281 * @return an iterator for the currently stored values |
247 */ |
282 */ |
248 cx_attr_nonnull |
283 cx_attr_nonnull |
249 cx_attr_nodiscard |
284 cx_attr_nodiscard |
250 static inline CxIterator cxMapIteratorValues(const CxMap *map) { |
285 static inline CxMapIterator cxMapIteratorValues(const CxMap *map) { |
251 return map->cl->iterator(map, CX_MAP_ITERATOR_VALUES); |
286 return map->cl->iterator(map, CX_MAP_ITERATOR_VALUES); |
252 } |
287 } |
253 |
288 |
254 /** |
289 /** |
255 * Creates a key iterator for a map. |
290 * Creates a key iterator for a map. |
256 * |
291 * |
257 * The elements of the iterator are keys of type CxHashKey. |
292 * The elements of the iterator are keys of type CxHashKey and the pointer returned |
|
293 * during iterator shall be treated as @c const @c CxHashKey* . |
258 * |
294 * |
259 * @note An iterator iterates over all elements successively. Therefore, the order |
295 * @note An iterator iterates over all elements successively. Therefore, the order |
260 * highly depends on the map implementation and may change arbitrarily when the contents change. |
296 * highly depends on the map implementation and may change arbitrarily when the contents change. |
261 * |
297 * |
262 * @param map the map to create the iterator for |
298 * @param map the map to create the iterator for |
263 * @return an iterator for the currently stored keys |
299 * @return an iterator for the currently stored keys |
264 */ |
300 */ |
265 cx_attr_nonnull |
301 cx_attr_nonnull |
266 cx_attr_nodiscard |
302 cx_attr_nodiscard |
267 static inline CxIterator cxMapIteratorKeys(const CxMap *map) { |
303 static inline CxMapIterator cxMapIteratorKeys(const CxMap *map) { |
268 return map->cl->iterator(map, CX_MAP_ITERATOR_KEYS); |
304 return map->cl->iterator(map, CX_MAP_ITERATOR_KEYS); |
269 } |
305 } |
270 |
306 |
271 /** |
307 /** |
272 * Creates an iterator for a map. |
308 * Creates an iterator for a map. |
273 * |
309 * |
274 * The elements of the iterator are key/value pairs of type CxMapEntry. |
310 * The elements of the iterator are key/value pairs of type CxMapEntry and the pointer returned |
|
311 * during iterator shall be treated as @c const @c CxMapEntry* . |
275 * |
312 * |
276 * @note An iterator iterates over all elements successively. Therefore, the order |
313 * @note An iterator iterates over all elements successively. Therefore, the order |
277 * highly depends on the map implementation and may change arbitrarily when the contents change. |
314 * highly depends on the map implementation and may change arbitrarily when the contents change. |
278 * |
315 * |
279 * @param map the map to create the iterator for |
316 * @param map the map to create the iterator for |
281 * @see cxMapIteratorKeys() |
318 * @see cxMapIteratorKeys() |
282 * @see cxMapIteratorValues() |
319 * @see cxMapIteratorValues() |
283 */ |
320 */ |
284 cx_attr_nonnull |
321 cx_attr_nonnull |
285 cx_attr_nodiscard |
322 cx_attr_nodiscard |
286 static inline CxIterator cxMapIterator(const CxMap *map) { |
323 static inline CxMapIterator cxMapIterator(const CxMap *map) { |
287 return map->cl->iterator(map, CX_MAP_ITERATOR_PAIRS); |
324 return map->cl->iterator(map, CX_MAP_ITERATOR_PAIRS); |
288 } |
325 } |
289 |
326 |
290 |
327 |
291 /** |
328 /** |
292 * Creates a mutating iterator over the values of a map. |
329 * Creates a mutating iterator over the values of a map. |
|
330 * |
|
331 * When the map is storing pointers, those pointers are returned. |
|
332 * Otherwise, the iterator iterates over pointers to the memory within the map where the |
|
333 * respective elements are stored. |
293 * |
334 * |
294 * @note An iterator iterates over all elements successively. Therefore, the order |
335 * @note An iterator iterates over all elements successively. Therefore, the order |
295 * highly depends on the map implementation and may change arbitrarily when the contents change. |
336 * highly depends on the map implementation and may change arbitrarily when the contents change. |
296 * |
337 * |
297 * @param map the map to create the iterator for |
338 * @param map the map to create the iterator for |
298 * @return an iterator for the currently stored values |
339 * @return an iterator for the currently stored values |
299 */ |
340 */ |
300 cx_attr_nonnull |
341 cx_attr_nonnull |
301 cx_attr_nodiscard |
342 cx_attr_nodiscard |
302 CxIterator cxMapMutIteratorValues(CxMap *map); |
343 cx_attr_export |
|
344 CxMapIterator cxMapMutIteratorValues(CxMap *map); |
303 |
345 |
304 /** |
346 /** |
305 * Creates a mutating iterator over the keys of a map. |
347 * Creates a mutating iterator over the keys of a map. |
306 * |
348 * |
307 * The elements of the iterator are keys of type CxHashKey. |
349 * The elements of the iterator are keys of type CxHashKey and the pointer returned |
|
350 * during iterator shall be treated as @c const @c CxHashKey* . |
308 * |
351 * |
309 * @note An iterator iterates over all elements successively. Therefore, the order |
352 * @note An iterator iterates over all elements successively. Therefore, the order |
310 * highly depends on the map implementation and may change arbitrarily when the contents change. |
353 * highly depends on the map implementation and may change arbitrarily when the contents change. |
311 * |
354 * |
312 * @param map the map to create the iterator for |
355 * @param map the map to create the iterator for |
313 * @return an iterator for the currently stored keys |
356 * @return an iterator for the currently stored keys |
314 */ |
357 */ |
315 cx_attr_nonnull |
358 cx_attr_nonnull |
316 cx_attr_nodiscard |
359 cx_attr_nodiscard |
317 CxIterator cxMapMutIteratorKeys(CxMap *map); |
360 cx_attr_export |
|
361 CxMapIterator cxMapMutIteratorKeys(CxMap *map); |
318 |
362 |
319 /** |
363 /** |
320 * Creates a mutating iterator for a map. |
364 * Creates a mutating iterator for a map. |
321 * |
365 * |
322 * The elements of the iterator are key/value pairs of type CxMapEntry. |
366 * The elements of the iterator are key/value pairs of type CxMapEntry and the pointer returned |
|
367 * during iterator shall be treated as @c const @c CxMapEntry* . |
323 * |
368 * |
324 * @note An iterator iterates over all elements successively. Therefore, the order |
369 * @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. |
370 * highly depends on the map implementation and may change arbitrarily when the contents change. |
326 * |
371 * |
327 * @param map the map to create the iterator for |
372 * @param map the map to create the iterator for |
536 |
582 |
537 /** |
583 /** |
538 * Puts a key/value-pair into the map. |
584 * Puts a key/value-pair into the map. |
539 * |
585 * |
540 * A possible existing value will be overwritten. |
586 * A possible existing value will be overwritten. |
|
587 * If destructor functions are specified, they are called for |
|
588 * the overwritten element. |
541 * |
589 * |
542 * If this map is storing pointers, the @p value pointer is written |
590 * If this map is storing pointers, the @p value pointer is written |
543 * to the map. Otherwise, the memory is copied from @p value with |
591 * to the map. Otherwise, the memory is copied from @p value with |
544 * memcpy(). |
592 * memcpy(). |
545 * |
593 * |
747 |
795 |
748 /** |
796 /** |
749 * Removes a key/value-pair from the map by using the key. |
797 * Removes a key/value-pair from the map by using the key. |
750 * |
798 * |
751 * This function will copy the contents of the removed element |
799 * This function will copy the contents of the removed element |
752 * to the target buffer must be guaranteed to be large enough |
800 * to the target buffer, which must be guaranteed to be large enough |
753 * to hold the element (the map's element size). |
801 * to hold the element (the map's element size). |
754 * The destructor functions, if any, will @em not be called. |
802 * The destructor functions, if any, will @em not be called. |
755 * |
803 * |
756 * If this map is storing pointers, the element is the pointer itself |
804 * If this map is storing pointers, the element is the pointer itself |
757 * and not the object it points to. |
805 * and not the object it points to. |
759 * @param map (@c CxMap*) the map |
807 * @param map (@c CxMap*) the map |
760 * @param key (@c CxHashKey, @c char*, @c cxstring, or @c cxmutstr) the key |
808 * @param key (@c CxHashKey, @c char*, @c cxstring, or @c cxmutstr) the key |
761 * @param targetbuf (@c void*) the buffer where the element shall be copied to |
809 * @param targetbuf (@c void*) the buffer where the element shall be copied to |
762 * @retval zero success |
810 * @retval zero success |
763 * @retval non-zero the key was not found |
811 * @retval non-zero the key was not found |
764 * |
812 * |
765 * @see cxMapStorePointers() |
|
766 * @see cxMapRemove() |
813 * @see cxMapRemove() |
767 */ |
814 */ |
768 #define cxMapRemoveAndGet(map, key, targetbuf) _Generic((key), \ |
815 #define cxMapRemoveAndGet(map, key, targetbuf) _Generic((key), \ |
769 CxHashKey: cx_map_remove_and_get, \ |
816 CxHashKey: cx_map_remove_and_get, \ |
770 cxstring: cx_map_remove_and_get_cxstr, \ |
817 cxstring: cx_map_remove_and_get_cxstr, \ |