250 return &elm->key; |
250 return &elm->key; |
251 } |
251 } |
252 |
252 |
253 static void *cx_hash_map_iter_current_value(void const *it) { |
253 static void *cx_hash_map_iter_current_value(void const *it) { |
254 struct cx_iterator_s const *iter = it; |
254 struct cx_iterator_s const *iter = it; |
255 struct cx_hash_map_s const *map = iter->src_handle; |
255 struct cx_hash_map_s const *map = iter->src_handle.c; |
256 struct cx_hash_map_element_s *elm = iter->elem_handle; |
256 struct cx_hash_map_element_s *elm = iter->elem_handle; |
257 if (map->base.store_pointer) { |
257 if (map->base.store_pointer) { |
258 return *(void **) elm->data; |
258 return *(void **) elm->data; |
259 } else { |
259 } else { |
260 return elm->data; |
260 return elm->data; |
267 } |
267 } |
268 |
268 |
269 static void cx_hash_map_iter_next(void *it) { |
269 static void cx_hash_map_iter_next(void *it) { |
270 struct cx_iterator_s *iter = it; |
270 struct cx_iterator_s *iter = it; |
271 struct cx_hash_map_element_s *elm = iter->elem_handle; |
271 struct cx_hash_map_element_s *elm = iter->elem_handle; |
|
272 struct cx_hash_map_s *map = iter->src_handle.m; |
272 |
273 |
273 // remove current element, if asked |
274 // remove current element, if asked |
274 if (iter->base.remove) { |
275 if (iter->remove) { |
275 // obtain mutable pointer to the map |
|
276 struct cx_mut_iterator_s *miter = it; |
|
277 struct cx_hash_map_s *map = miter->src_handle; |
|
278 |
276 |
279 // clear the flag |
277 // clear the flag |
280 iter->base.remove = false; |
278 iter->remove = false; |
281 |
279 |
282 // determine the next element |
280 // determine the next element |
283 struct cx_hash_map_element_s *next = elm->next; |
281 struct cx_hash_map_element_s *next = elm->next; |
284 |
282 |
285 // search the previous element |
283 // search the previous element |
304 elm = elm->next; |
302 elm = elm->next; |
305 iter->index++; |
303 iter->index++; |
306 } |
304 } |
307 |
305 |
308 // search the next bucket, if required |
306 // search the next bucket, if required |
309 struct cx_hash_map_s const *map = iter->src_handle; |
|
310 while (elm == NULL && ++iter->slot < map->bucket_count) { |
307 while (elm == NULL && ++iter->slot < map->bucket_count) { |
311 elm = map->buckets[iter->slot]; |
308 elm = map->buckets[iter->slot]; |
312 } |
309 } |
313 |
310 |
314 // fill the struct with the next element |
311 // fill the struct with the next element |
330 CxMap const *map, |
327 CxMap const *map, |
331 enum cx_map_iterator_type type |
328 enum cx_map_iterator_type type |
332 ) { |
329 ) { |
333 CxIterator iter; |
330 CxIterator iter; |
334 |
331 |
335 iter.src_handle = map; |
332 iter.src_handle.c = map; |
336 iter.elem_count = map->size; |
333 iter.elem_count = map->size; |
337 |
334 |
338 switch (type) { |
335 switch (type) { |
339 case CX_MAP_ITERATOR_PAIRS: |
336 case CX_MAP_ITERATOR_PAIRS: |
340 iter.elem_size = sizeof(CxMapEntry); |
337 iter.elem_size = sizeof(CxMapEntry); |
341 iter.base.current = cx_hash_map_iter_current_entry; |
338 iter.current = cx_hash_map_iter_current_entry; |
342 break; |
339 break; |
343 case CX_MAP_ITERATOR_KEYS: |
340 case CX_MAP_ITERATOR_KEYS: |
344 iter.elem_size = sizeof(CxHashKey); |
341 iter.elem_size = sizeof(CxHashKey); |
345 iter.base.current = cx_hash_map_iter_current_key; |
342 iter.current = cx_hash_map_iter_current_key; |
346 break; |
343 break; |
347 case CX_MAP_ITERATOR_VALUES: |
344 case CX_MAP_ITERATOR_VALUES: |
348 iter.elem_size = map->item_size; |
345 iter.elem_size = map->item_size; |
349 iter.base.current = cx_hash_map_iter_current_value; |
346 iter.current = cx_hash_map_iter_current_value; |
350 break; |
347 break; |
351 default: |
348 default: |
352 assert(false); |
349 assert(false); |
353 } |
350 } |
354 |
351 |
355 iter.base.valid = cx_hash_map_iter_valid; |
352 iter.valid = cx_hash_map_iter_valid; |
356 iter.base.next = cx_hash_map_iter_next; |
353 iter.next = cx_hash_map_iter_next; |
357 iter.base.remove = false; |
354 iter.remove = false; |
358 iter.base.mutating = false; |
355 iter.mutating = false; |
359 |
356 |
360 iter.slot = 0; |
357 iter.slot = 0; |
361 iter.index = 0; |
358 iter.index = 0; |
362 |
359 |
363 if (map->size > 0) { |
360 if (map->size > 0) { |