src/array_list.c

changeset 630
ac5e7f789048
parent 629
6c81ee4f11ad
child 638
eafb45eefc51
     1.1 --- a/src/array_list.c	Wed Nov 23 22:40:55 2022 +0100
     1.2 +++ b/src/array_list.c	Sat Nov 26 16:58:41 2022 +0100
     1.3 @@ -243,7 +243,7 @@
     1.4  }
     1.5  
     1.6  static int cx_arl_insert_iter(
     1.7 -        struct cx_iterator_s *iter,
     1.8 +        struct cx_mut_iterator_s *iter,
     1.9          void const *elem,
    1.10          int prepend
    1.11  ) {
    1.12 @@ -367,20 +367,25 @@
    1.13      }
    1.14  }
    1.15  
    1.16 -static bool cx_arl_iter_valid(struct cx_iterator_s const *iter) {
    1.17 +static bool cx_arl_iter_valid(void const *it) {
    1.18 +    struct cx_iterator_s const *iter = it;
    1.19      struct cx_list_s const *list = iter->src_handle;
    1.20      return iter->index < list->size;
    1.21  }
    1.22  
    1.23 -static void *cx_arl_iter_current(struct cx_iterator_s const *iter) {
    1.24 +static void *cx_arl_iter_current(void const *it) {
    1.25 +    struct cx_iterator_s const *iter = it;
    1.26      return iter->elem_handle;
    1.27  }
    1.28  
    1.29 -static void cx_arl_iter_next(struct cx_iterator_s *iter) {
    1.30 -    if (iter->remove) {
    1.31 -        iter->remove = false;
    1.32 +static void cx_arl_iter_next(void *it) {
    1.33 +    struct cx_iterator_base_s *itbase = it;
    1.34 +    if (itbase->remove) {
    1.35 +        struct cx_mut_iterator_s *iter = it;
    1.36 +        itbase->remove = false;
    1.37          cx_arl_remove(iter->src_handle, iter->index);
    1.38      } else {
    1.39 +        struct cx_iterator_s *iter = it;
    1.40          iter->index++;
    1.41          iter->elem_handle =
    1.42                  ((char *) iter->elem_handle)
    1.43 @@ -388,8 +393,18 @@
    1.44      }
    1.45  }
    1.46  
    1.47 +static bool cx_arl_iter_flag_rm(void *it) {
    1.48 +    struct cx_iterator_base_s *iter = it;
    1.49 +    if (iter->mutating) {
    1.50 +        iter->remove = true;
    1.51 +        return true;
    1.52 +    } else {
    1.53 +        return false;
    1.54 +    }
    1.55 +}
    1.56 +
    1.57  static struct cx_iterator_s cx_arl_iterator(
    1.58 -        struct cx_list_s *list,
    1.59 +        struct cx_list_s const *list,
    1.60          size_t index
    1.61  ) {
    1.62      struct cx_iterator_s iter;
    1.63 @@ -397,14 +412,29 @@
    1.64      iter.index = index;
    1.65      iter.src_handle = list;
    1.66      iter.elem_handle = cx_arl_at(list, index);
    1.67 -    iter.valid = cx_arl_iter_valid;
    1.68 -    iter.current = cx_arl_iter_current;
    1.69 -    iter.next = cx_arl_iter_next;
    1.70 -    iter.remove = false;
    1.71 +    iter.base.valid = cx_arl_iter_valid;
    1.72 +    iter.base.current = cx_arl_iter_current;
    1.73 +    iter.base.next = cx_arl_iter_next;
    1.74 +    iter.base.flag_removal = cx_arl_iter_flag_rm;
    1.75 +    iter.base.remove = false;
    1.76 +    iter.base.mutating = false;
    1.77  
    1.78      return iter;
    1.79  }
    1.80  
    1.81 +static struct cx_mut_iterator_s cx_arl_mut_iterator(
    1.82 +        struct cx_list_s *list,
    1.83 +        size_t index
    1.84 +) {
    1.85 +    CxIterator it = cx_arl_iterator(list, index);
    1.86 +    it.base.mutating = true;
    1.87 +
    1.88 +    // we know the iterators share the same memory layout
    1.89 +    CxMutIterator iter;
    1.90 +    memcpy(&iter, &it, sizeof(CxMutIterator));
    1.91 +    return iter;
    1.92 +}
    1.93 +
    1.94  static cx_list_class cx_array_list_class = {
    1.95          cx_arl_destructor,
    1.96          cx_arl_add,
    1.97 @@ -418,6 +448,7 @@
    1.98          cx_arl_compare,
    1.99          cx_arl_reverse,
   1.100          cx_arl_iterator,
   1.101 +        cx_arl_mut_iterator,
   1.102  };
   1.103  
   1.104  CxList *cxArrayListCreate(

mercurial