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(