| 150 static int cx_kvl_insert_iter( |
150 static int cx_kvl_insert_iter( |
| 151 struct cx_iterator_s *iter, |
151 struct cx_iterator_s *iter, |
| 152 const void *elem, |
152 const void *elem, |
| 153 int prepend |
153 int prepend |
| 154 ) { |
154 ) { |
| 155 cx_kv_list *kv_list = iter->src_handle.m; |
155 cx_kv_list *kv_list = iter->src_handle; |
| 156 return kv_list->list_methods->insert_iter(iter, elem, prepend); |
156 return kv_list->list_methods->insert_iter(iter, elem, prepend); |
| 157 } |
157 } |
| 158 |
158 |
| 159 static size_t cx_kvl_remove( |
159 static size_t cx_kvl_remove( |
| 160 struct cx_list_s *list, |
160 struct cx_list_s *list, |
| 257 |
257 |
| 258 static void cx_kvl_list_iter_next(void *it) { |
258 static void cx_kvl_list_iter_next(void *it) { |
| 259 struct cx_iterator_s *iter = it; |
259 struct cx_iterator_s *iter = it; |
| 260 if (iter->base.remove) { |
260 if (iter->base.remove) { |
| 261 // remove the assigned key from the map before calling the actual function |
261 // remove the assigned key from the map before calling the actual function |
| 262 cx_kv_list *kv_list = iter->src_handle.m; |
262 cx_kv_list *kv_list = iter->src_handle; |
| 263 cx_kv_list_update_destructors(kv_list); |
263 cx_kv_list_update_destructors(kv_list); |
| 264 char *node = iter->elem_handle; |
264 char *node = iter->elem_handle; |
| 265 CxHashKey *key = cx_kv_list_loc_key(kv_list, node + kv_list->list.loc_data); |
265 CxHashKey *key = cx_kv_list_loc_key(kv_list, node + kv_list->list.loc_data); |
| 266 if (key->hash != 0) { |
266 if (key->hash != 0) { |
| 267 kv_list->map_methods->remove(&kv_list->map->map_base.base, *key, NULL); |
267 kv_list->map_methods->remove(&kv_list->map->map_base.base, *key, NULL); |
| 268 } |
268 } |
| 269 } |
269 } |
| |
270 // note that we do not clear the remove flag, because the next_impl will do that |
| 270 iter->base.next_impl(it); |
271 iter->base.next_impl(it); |
| 271 } |
272 } |
| 272 |
273 |
| 273 static struct cx_iterator_s cx_kvl_iterator( |
274 static struct cx_iterator_s cx_kvl_iterator( |
| 274 const struct cx_list_s *list, |
275 const struct cx_list_s *list, |
| 395 return entry->value; |
396 return entry->value; |
| 396 } |
397 } |
| 397 |
398 |
| 398 static void cx_kvl_iter_next(void *it) { |
399 static void cx_kvl_iter_next(void *it) { |
| 399 CxMapIterator *iter = it; |
400 CxMapIterator *iter = it; |
| 400 cx_kv_list *kv_list = ((struct cx_kv_list_map_s*)iter->map.m)->list; |
401 cx_kv_list *kv_list = ((struct cx_kv_list_map_s*)iter->map)->list; |
| 401 |
402 |
| 402 // find the next list entry that has a key assigned |
403 // find the next list entry that has a key assigned |
| 403 CxHashKey *key = NULL; |
404 CxHashKey *key = NULL; |
| 404 char *next = iter->elem; |
405 char *next = iter->elem; |
| 405 while (true) { |
406 while (true) { |
| 456 |
457 |
| 457 CxMapIterator cx_kvl_map_iterator(const CxMap *map, enum cx_map_iterator_type type) { |
458 CxMapIterator cx_kvl_map_iterator(const CxMap *map, enum cx_map_iterator_type type) { |
| 458 CxMapIterator iter = {0}; |
459 CxMapIterator iter = {0}; |
| 459 |
460 |
| 460 iter.type = type; |
461 iter.type = type; |
| 461 iter.map.c = map; |
462 iter.map = (CxMap*)map; |
| 462 // although we iterate over the list, we only report that many elements that have a key in the map |
463 // although we iterate over the list, we only report that many elements that have a key in the map |
| 463 iter.elem_count = map->collection.size; |
464 iter.elem_count = map->collection.size; |
| 464 |
465 |
| 465 switch (type) { |
466 switch (type) { |
| 466 case CX_MAP_ITERATOR_PAIRS: |
467 case CX_MAP_ITERATOR_PAIRS: |
| 477 break; |
478 break; |
| 478 default: |
479 default: |
| 479 assert(false); // LCOV_EXCL_LINE |
480 assert(false); // LCOV_EXCL_LINE |
| 480 } |
481 } |
| 481 |
482 |
| |
483 iter.base.allow_remove = true; |
| 482 iter.base.next = cx_kvl_iter_next; |
484 iter.base.next = cx_kvl_iter_next; |
| 483 iter.base.valid = cx_kvl_iter_valid; |
485 iter.base.valid = cx_kvl_iter_valid; |
| 484 |
486 |
| 485 // find the first list entry that has a key assigned |
487 // find the first list entry that has a key assigned |
| 486 cx_kv_list *kv_list = ((struct cx_kv_list_map_s*)map)->list; |
488 cx_kv_list *kv_list = ((struct cx_kv_list_map_s*)map)->list; |
| 503 iter.entry.value = (void*)(next + kv_list->list.loc_data); |
505 iter.entry.value = (void*)(next + kv_list->list.loc_data); |
| 504 } |
506 } |
| 505 } |
507 } |
| 506 |
508 |
| 507 return iter; |
509 return iter; |
| |
510 } |
| |
511 |
| |
512 static int cx_kvl_change_capacity(struct cx_list_s *list, |
| |
513 cx_attr_unused size_t cap) { |
| |
514 // since our backing list is a linked list, we don't need to do much here, |
| |
515 // but rehashing the map is quite useful |
| |
516 cx_kv_list *kv_list = (cx_kv_list*)list; |
| |
517 cxMapRehash(&kv_list->map->map_base.base); |
| |
518 return 0; |
| 508 } |
519 } |
| 509 |
520 |
| 510 static cx_list_class cx_kv_list_class = { |
521 static cx_list_class cx_kv_list_class = { |
| 511 cx_kvl_deallocate, |
522 cx_kvl_deallocate, |
| 512 cx_kvl_insert_element, |
523 cx_kvl_insert_element, |