166 static void cx_arl_destructor(struct cx_list_s *list) { |
166 static void cx_arl_destructor(struct cx_list_s *list) { |
167 cx_array_list *arl = (cx_array_list *) list; |
167 cx_array_list *arl = (cx_array_list *) list; |
168 cxFree(list->allocator, arl->data); |
168 cxFree(list->allocator, arl->data); |
169 } |
169 } |
170 |
170 |
171 static int cx_arl_add( |
|
172 struct cx_list_s *list, |
|
173 void const *elem |
|
174 ) { |
|
175 cx_array_list *arl = (cx_array_list *) list; |
|
176 return cx_array_copy( |
|
177 &arl->data, |
|
178 &list->size, |
|
179 &list->capacity, |
|
180 list->size, |
|
181 elem, |
|
182 list->itemsize, |
|
183 1, |
|
184 &arl->reallocator |
|
185 ); |
|
186 } |
|
187 |
|
188 static size_t cx_arl_insert_array( |
171 static size_t cx_arl_insert_array( |
189 struct cx_list_s *list, |
172 struct cx_list_s *list, |
190 size_t index, |
173 size_t index, |
191 void const *array, |
174 void const *array, |
192 size_t n |
175 size_t n |
239 // array list implementation is "all or nothing" |
222 // array list implementation is "all or nothing" |
240 return 0; |
223 return 0; |
241 } |
224 } |
242 } |
225 } |
243 |
226 |
244 static size_t cx_arl_add_array( |
|
245 struct cx_list_s *list, |
|
246 void const *array, |
|
247 size_t n |
|
248 ) { |
|
249 return cx_arl_insert_array(list, list->size, array, n); |
|
250 } |
|
251 |
|
252 static int cx_arl_insert( |
|
253 struct cx_list_s *list, |
|
254 size_t index, |
|
255 void const *elem |
|
256 ) { |
|
257 if (index > list->size) { |
|
258 return 1; |
|
259 } else if (index == list->size) { |
|
260 return cx_arl_add(list, elem); |
|
261 } else { |
|
262 cx_array_list *arl = (cx_array_list *) list; |
|
263 |
|
264 // move elements starting at index to the right |
|
265 if (cx_array_copy( |
|
266 &arl->data, |
|
267 &list->size, |
|
268 &list->capacity, |
|
269 index + 1, |
|
270 ((char *) arl->data) + index * list->itemsize, |
|
271 list->itemsize, |
|
272 list->size - index, |
|
273 &arl->reallocator |
|
274 )) { |
|
275 return 1; |
|
276 } |
|
277 |
|
278 // place the element |
|
279 memcpy(((char *) arl->data) + index * list->itemsize, |
|
280 elem, list->itemsize); |
|
281 |
|
282 return 0; |
|
283 } |
|
284 } |
|
285 |
|
286 static int cx_arl_insert_iter( |
227 static int cx_arl_insert_iter( |
287 struct cx_mut_iterator_s *iter, |
228 struct cx_mut_iterator_s *iter, |
288 void const *elem, |
229 void const *elem, |
289 int prepend |
230 int prepend |
290 ) { |
231 ) { |
291 struct cx_list_s *list = iter->src_handle; |
232 struct cx_list_s *list = iter->src_handle; |
292 if (iter->index < list->size) { |
233 if (iter->index < list->size) { |
293 int result = cx_arl_insert( |
234 int result = 1 != cx_arl_insert_array( |
294 list, |
235 list, |
295 iter->index + 1 - prepend, |
236 iter->index + 1 - prepend, |
296 elem |
237 elem, |
|
238 1 |
297 ); |
239 ); |
298 if (result == 0 && prepend != 0) { |
240 if (result == 0 && prepend != 0) { |
299 iter->index++; |
241 iter->index++; |
300 iter->elem_handle = ((char *) iter->elem_handle) + list->itemsize; |
242 iter->elem_handle = ((char *) iter->elem_handle) + list->itemsize; |
301 } |
243 } |
302 return result; |
244 return result; |
303 } else { |
245 } else { |
304 int result = cx_arl_add(list, elem); |
246 int result = 1 != cx_arl_insert_array(list, list->size, elem, 1); |
305 iter->index = list->size; |
247 iter->index = list->size; |
306 return result; |
248 return result; |
307 } |
249 } |
308 } |
250 } |
309 |
251 |
461 iter.base.mutating = false; |
403 iter.base.mutating = false; |
462 |
404 |
463 return iter; |
405 return iter; |
464 } |
406 } |
465 |
407 |
466 static struct cx_mut_iterator_s cx_arl_mut_iterator( |
|
467 struct cx_list_s *list, |
|
468 size_t index |
|
469 ) { |
|
470 CxIterator it = cx_arl_iterator(list, index); |
|
471 it.base.mutating = true; |
|
472 |
|
473 // we know the iterators share the same memory layout |
|
474 CxMutIterator iter; |
|
475 memcpy(&iter, &it, sizeof(CxMutIterator)); |
|
476 return iter; |
|
477 } |
|
478 |
|
479 static cx_list_class cx_array_list_class = { |
408 static cx_list_class cx_array_list_class = { |
480 cx_arl_destructor, |
409 cx_arl_destructor, |
481 cx_arl_add, |
|
482 cx_arl_add_array, |
|
483 cx_arl_insert, |
|
484 cx_arl_insert_array, |
410 cx_arl_insert_array, |
485 cx_arl_insert_iter, |
411 cx_arl_insert_iter, |
486 cx_arl_remove, |
412 cx_arl_remove, |
487 cx_arl_at, |
413 cx_arl_at, |
488 cx_arl_find, |
414 cx_arl_find, |
489 cx_arl_sort, |
415 cx_arl_sort, |
490 cx_arl_compare, |
416 cx_arl_compare, |
491 cx_arl_reverse, |
417 cx_arl_reverse, |
492 cx_arl_iterator, |
418 cx_arl_iterator, |
493 cx_arl_mut_iterator, |
|
494 }; |
419 }; |
495 |
420 |
496 CxList *cxArrayListCreate( |
421 CxList *cxArrayListCreate( |
497 CxAllocator const *allocator, |
422 CxAllocator const *allocator, |
498 CxListComparator comparator, |
423 CxListComparator comparator, |