src/linked_list.c

changeset 630
ac5e7f789048
parent 629
6c81ee4f11ad
child 638
eafb45eefc51
     1.1 --- a/src/linked_list.c	Wed Nov 23 22:40:55 2022 +0100
     1.2 +++ b/src/linked_list.c	Sat Nov 26 16:58:41 2022 +0100
     1.3 @@ -643,13 +643,16 @@
     1.4                                    left->follow_ptr, right->follow_ptr, list->cmpfunc);
     1.5  }
     1.6  
     1.7 -static bool cx_ll_iter_valid(CxIterator const *iter) {
     1.8 +static bool cx_ll_iter_valid(void const *it) {
     1.9 +    struct cx_iterator_s const *iter = it;
    1.10      return iter->elem_handle != NULL;
    1.11  }
    1.12  
    1.13 -static void cx_ll_iter_next(CxIterator *iter) {
    1.14 -    if (iter->remove) {
    1.15 -        iter->remove = false;
    1.16 +static void cx_ll_iter_next(void *it) {
    1.17 +    struct cx_iterator_base_s *itbase = it;
    1.18 +    if (itbase->remove) {
    1.19 +        itbase->remove = false;
    1.20 +        struct cx_mut_iterator_s *iter = it;
    1.21          cx_linked_list *ll = iter->src_handle;
    1.22          cx_linked_list_node *node = iter->elem_handle;
    1.23          iter->elem_handle = node->next;
    1.24 @@ -658,48 +661,85 @@
    1.25          ll->base.size--;
    1.26          cxFree(ll->base.allocator, node);
    1.27      } else {
    1.28 +        struct cx_iterator_s *iter = it;
    1.29          iter->index++;
    1.30          cx_linked_list_node *node = iter->elem_handle;
    1.31          iter->elem_handle = node->next;
    1.32      }
    1.33  }
    1.34  
    1.35 -static void *cx_ll_iter_current(CxIterator const *iter) {
    1.36 +static void *cx_ll_iter_current(void const *it) {
    1.37 +    struct cx_iterator_s const *iter = it;
    1.38      cx_linked_list_node *node = iter->elem_handle;
    1.39      return node->payload;
    1.40  }
    1.41  
    1.42 -static void *cx_pll_iter_current(CxIterator const *iter) {
    1.43 +static void *cx_pll_iter_current(void const *it) {
    1.44 +    struct cx_iterator_s const *iter = it;
    1.45      cx_linked_list_node *node = iter->elem_handle;
    1.46      return *(void **) node->payload;
    1.47  }
    1.48  
    1.49 +static bool cx_ll_iter_flag_rm(void *it) {
    1.50 +    struct cx_iterator_base_s *iter = it;
    1.51 +    if (iter->mutating) {
    1.52 +        iter->remove = true;
    1.53 +        return true;
    1.54 +    } else {
    1.55 +        return false;
    1.56 +    }
    1.57 +}
    1.58 +
    1.59  static CxIterator cx_ll_iterator(
    1.60 -        struct cx_list_s *list,
    1.61 +        struct cx_list_s const *list,
    1.62          size_t index
    1.63  ) {
    1.64      CxIterator iter;
    1.65      iter.index = index;
    1.66      iter.src_handle = list;
    1.67      iter.elem_handle = cx_ll_node_at((cx_linked_list const *) list, index);
    1.68 -    iter.valid = cx_ll_iter_valid;
    1.69 -    iter.current = cx_ll_iter_current;
    1.70 -    iter.next = cx_ll_iter_next;
    1.71 -    iter.remove = false;
    1.72 +    iter.base.valid = cx_ll_iter_valid;
    1.73 +    iter.base.current = cx_ll_iter_current;
    1.74 +    iter.base.next = cx_ll_iter_next;
    1.75 +    iter.base.flag_removal = cx_ll_iter_flag_rm;
    1.76 +    iter.base.mutating = false;
    1.77 +    iter.base.remove = false;
    1.78      return iter;
    1.79  }
    1.80  
    1.81  static CxIterator cx_pll_iterator(
    1.82 +        struct cx_list_s const *list,
    1.83 +        size_t index
    1.84 +) {
    1.85 +    CxIterator iter = cx_ll_iterator(list, index);
    1.86 +    iter.base.current = cx_pll_iter_current;
    1.87 +    return iter;
    1.88 +}
    1.89 +
    1.90 +static CxMutIterator cx_ll_mut_iterator(
    1.91          struct cx_list_s *list,
    1.92          size_t index
    1.93  ) {
    1.94 -    CxIterator iter = cx_ll_iterator(list, index);
    1.95 -    iter.current = cx_pll_iter_current;
    1.96 +    CxIterator it = cx_ll_iterator(list, index);
    1.97 +    it.base.mutating = true;
    1.98 +
    1.99 +    // we know the iterators share the same memory layout
   1.100 +    CxMutIterator iter;
   1.101 +    memcpy(&iter, &it, sizeof(CxMutIterator));
   1.102 +    return iter;
   1.103 +}
   1.104 +
   1.105 +static CxMutIterator cx_pll_mut_iterator(
   1.106 +        struct cx_list_s *list,
   1.107 +        size_t index
   1.108 +) {
   1.109 +    CxMutIterator iter = cx_ll_mut_iterator(list, index);
   1.110 +    iter.base.current = cx_pll_iter_current;
   1.111      return iter;
   1.112  }
   1.113  
   1.114  static int cx_ll_insert_iter(
   1.115 -        CxIterator *iter,
   1.116 +        CxMutIterator *iter,
   1.117          void const *elem,
   1.118          int prepend
   1.119  ) {
   1.120 @@ -719,7 +759,7 @@
   1.121  }
   1.122  
   1.123  static int cx_pll_insert_iter(
   1.124 -        CxIterator *iter,
   1.125 +        CxMutIterator *iter,
   1.126          void const *elem,
   1.127          int prepend
   1.128  ) {
   1.129 @@ -750,7 +790,8 @@
   1.130          cx_ll_sort,
   1.131          cx_ll_compare,
   1.132          cx_ll_reverse,
   1.133 -        cx_ll_iterator
   1.134 +        cx_ll_iterator,
   1.135 +        cx_ll_mut_iterator,
   1.136  };
   1.137  
   1.138  static cx_list_class cx_pointer_linked_list_class = {
   1.139 @@ -766,6 +807,7 @@
   1.140          cx_ll_compare,
   1.141          cx_ll_reverse,
   1.142          cx_pll_iterator,
   1.143 +        cx_pll_mut_iterator,
   1.144  };
   1.145  
   1.146  CxList *cxLinkedListCreate(

mercurial