| 740 node = node == NULL ? ((cx_linked_list *) list)->begin : CX_LL_PTR(node, ll->loc_next); |
749 node = node == NULL ? ((cx_linked_list *) list)->begin : CX_LL_PTR(node, ll->loc_next); |
| 741 |
750 |
| 742 // we can add the remaining nodes and immediately advance to the inserted node |
751 // we can add the remaining nodes and immediately advance to the inserted node |
| 743 const char *source = array; |
752 const char *source = array; |
| 744 for (size_t i = 1; i < n; i++) { |
753 for (size_t i = 1; i < n; i++) { |
| 745 source += list->collection.elem_size; |
754 if (source != NULL) { |
| |
755 source += list->collection.elem_size; |
| |
756 } |
| 746 if (0 != cx_ll_insert_at(list, node, source)) return i; |
757 if (0 != cx_ll_insert_at(list, node, source)) return i; |
| 747 node = CX_LL_PTR(node, ll->loc_next); |
758 node = CX_LL_PTR(node, ll->loc_next); |
| 748 } |
759 } |
| 749 return n; |
760 return n; |
| 750 } |
761 } |
| 1114 return iter->elem_handle != NULL; |
1125 return iter->elem_handle != NULL; |
| 1115 } |
1126 } |
| 1116 |
1127 |
| 1117 static void cx_ll_iter_next(void *it) { |
1128 static void cx_ll_iter_next(void *it) { |
| 1118 struct cx_iterator_s *iter = it; |
1129 struct cx_iterator_s *iter = it; |
| |
1130 cx_linked_list *ll = iter->src_handle; |
| 1119 if (iter->base.remove) { |
1131 if (iter->base.remove) { |
| 1120 iter->base.remove = false; |
1132 iter->base.remove = false; |
| 1121 struct cx_list_s *list = iter->src_handle.m; |
1133 struct cx_list_s *list = iter->src_handle; |
| 1122 cx_linked_list *ll = iter->src_handle.m; |
|
| 1123 char *node = iter->elem_handle; |
1134 char *node = iter->elem_handle; |
| 1124 iter->elem_handle = CX_LL_PTR(node, ll->loc_next); |
1135 iter->elem_handle = CX_LL_PTR(node, ll->loc_next); |
| 1125 cx_invoke_destructor(list, node + ll->loc_data); |
1136 cx_invoke_destructor(list, node + ll->loc_data); |
| 1126 cx_linked_list_remove(&ll->begin, &ll->end, |
1137 cx_linked_list_remove(&ll->begin, &ll->end, |
| 1127 ll->loc_prev, ll->loc_next, node); |
1138 ll->loc_prev, ll->loc_next, node); |
| 1128 list->collection.size--; |
1139 list->collection.size--; |
| 1129 iter->elem_count--; |
1140 iter->elem_count--; |
| 1130 cxFree(list->collection.allocator, node); |
1141 cxFree(list->collection.allocator, node); |
| 1131 } else { |
1142 } else { |
| 1132 const cx_linked_list *ll = iter->src_handle.c; |
|
| 1133 iter->index++; |
1143 iter->index++; |
| 1134 void *node = iter->elem_handle; |
1144 void *node = iter->elem_handle; |
| 1135 iter->elem_handle = CX_LL_PTR(node, ll->loc_next); |
1145 iter->elem_handle = CX_LL_PTR(node, ll->loc_next); |
| 1136 } |
1146 } |
| 1137 } |
1147 } |
| 1138 |
1148 |
| 1139 static void cx_ll_iter_prev(void *it) { |
1149 static void cx_ll_iter_prev(void *it) { |
| 1140 struct cx_iterator_s *iter = it; |
1150 struct cx_iterator_s *iter = it; |
| |
1151 cx_linked_list *ll = iter->src_handle; |
| 1141 if (iter->base.remove) { |
1152 if (iter->base.remove) { |
| 1142 iter->base.remove = false; |
1153 iter->base.remove = false; |
| 1143 struct cx_list_s *list = iter->src_handle.m; |
1154 struct cx_list_s *list = iter->src_handle; |
| 1144 cx_linked_list *ll = iter->src_handle.m; |
|
| 1145 char *node = iter->elem_handle; |
1155 char *node = iter->elem_handle; |
| 1146 iter->elem_handle = CX_LL_PTR(node, ll->loc_prev); |
1156 iter->elem_handle = CX_LL_PTR(node, ll->loc_prev); |
| 1147 iter->index--; |
1157 iter->index--; |
| 1148 cx_invoke_destructor(list, node + ll->loc_data); |
1158 cx_invoke_destructor(list, node + ll->loc_data); |
| 1149 cx_linked_list_remove(&ll->begin, &ll->end, |
1159 cx_linked_list_remove(&ll->begin, &ll->end, |
| 1150 ll->loc_prev, ll->loc_next, node); |
1160 ll->loc_prev, ll->loc_next, node); |
| 1151 list->collection.size--; |
1161 list->collection.size--; |
| 1152 iter->elem_count--; |
1162 iter->elem_count--; |
| 1153 cxFree(list->collection.allocator, node); |
1163 cxFree(list->collection.allocator, node); |
| 1154 } else { |
1164 } else { |
| 1155 const cx_linked_list *ll = iter->src_handle.c; |
|
| 1156 iter->index--; |
1165 iter->index--; |
| 1157 char *node = iter->elem_handle; |
1166 char *node = iter->elem_handle; |
| 1158 iter->elem_handle = CX_LL_PTR(node, ll->loc_prev); |
1167 iter->elem_handle = CX_LL_PTR(node, ll->loc_prev); |
| 1159 } |
1168 } |
| 1160 } |
1169 } |
| 1161 |
1170 |
| 1162 static void *cx_ll_iter_current(const void *it) { |
1171 static void *cx_ll_iter_current(const void *it) { |
| 1163 const struct cx_iterator_s *iter = it; |
1172 const struct cx_iterator_s *iter = it; |
| 1164 const cx_linked_list *ll = iter->src_handle.c; |
1173 const cx_linked_list *ll = iter->src_handle; |
| 1165 char *node = iter->elem_handle; |
1174 char *node = iter->elem_handle; |
| 1166 return node + ll->loc_data; |
1175 return node + ll->loc_data; |
| 1167 } |
1176 } |
| 1168 |
1177 |
| 1169 static CxIterator cx_ll_iterator( |
1178 static CxIterator cx_ll_iterator( |
| 1171 size_t index, |
1180 size_t index, |
| 1172 bool backwards |
1181 bool backwards |
| 1173 ) { |
1182 ) { |
| 1174 CxIterator iter; |
1183 CxIterator iter; |
| 1175 iter.index = index; |
1184 iter.index = index; |
| 1176 iter.src_handle.c = list; |
1185 iter.src_handle = (void*)list; |
| 1177 iter.elem_handle = cx_ll_node_at((const cx_linked_list *) list, index); |
1186 iter.elem_handle = cx_ll_node_at((const cx_linked_list *) list, index); |
| 1178 iter.elem_size = list->collection.elem_size; |
1187 iter.elem_size = list->collection.elem_size; |
| 1179 iter.elem_count = list->collection.size; |
1188 iter.elem_count = list->collection.size; |
| 1180 iter.base.valid = cx_ll_iter_valid; |
1189 iter.base.valid = cx_ll_iter_valid; |
| 1181 iter.base.current = cx_ll_iter_current; |
1190 iter.base.current = cx_ll_iter_current; |
| 1182 iter.base.next = backwards ? cx_ll_iter_prev : cx_ll_iter_next; |
1191 iter.base.next = backwards ? cx_ll_iter_prev : cx_ll_iter_next; |
| 1183 iter.base.mutating = false; |
1192 iter.base.allow_remove = true; |
| 1184 iter.base.remove = false; |
1193 iter.base.remove = false; |
| 1185 return iter; |
1194 return iter; |
| 1186 } |
1195 } |
| 1187 |
1196 |
| 1188 static int cx_ll_insert_iter( |
1197 static int cx_ll_insert_iter( |
| 1189 CxIterator *iter, |
1198 CxIterator *iter, |
| 1190 const void *elem, |
1199 const void *elem, |
| 1191 int prepend |
1200 int prepend |
| 1192 ) { |
1201 ) { |
| 1193 struct cx_list_s *list = iter->src_handle.m; |
1202 struct cx_list_s *list = iter->src_handle; |
| 1194 cx_linked_list *ll = iter->src_handle.m; |
1203 cx_linked_list *ll = iter->src_handle; |
| 1195 void *node = iter->elem_handle; |
1204 void *node = iter->elem_handle; |
| 1196 if (node != NULL) { |
1205 if (node != NULL) { |
| 1197 assert(prepend >= 0 && prepend <= 1); |
1206 assert(prepend >= 0 && prepend <= 1); |
| 1198 void *choice[2] = {node, CX_LL_PTR(node, ll->loc_prev)}; |
1207 void *choice[2] = {node, CX_LL_PTR(node, ll->loc_prev)}; |
| 1199 int result = cx_ll_insert_at(list, choice[prepend], elem); |
1208 int result = cx_ll_insert_at(list, choice[prepend], elem); |