| 388 |
388 |
| 389 CxIterator cx_array_iterator_ptr_(CxArray *array) { |
389 CxIterator cx_array_iterator_ptr_(CxArray *array) { |
| 390 return cxIteratorPtr(array->data, array->size); |
390 return cxIteratorPtr(array->data, array->size); |
| 391 } |
391 } |
| 392 |
392 |
| |
393 void cx_array_remove_(CxArray *array, size_t elem_size, size_t index, size_t n, bool fast) { |
| |
394 if (n == 0) return; |
| |
395 if (index >= array->size) return; |
| |
396 if (index + n >= array->size) { |
| |
397 // only tail elements are removed |
| |
398 array->size = index; |
| |
399 return; |
| |
400 } |
| |
401 array->size -= n; |
| |
402 size_t remaining = array->size - index; |
| |
403 char *dest = ((char*)array->data) + index * elem_size; |
| |
404 if (fast) { |
| |
405 char *src = dest + remaining * elem_size; |
| |
406 if (n == 1 && elem_size <= CX_WORDSIZE/8) { |
| |
407 // try to optimize int-sized values |
| |
408 // (from likely to unlikely) |
| |
409 if (elem_size == sizeof(int32_t)) { |
| |
410 *(int32_t*)dest = *(int32_t*)src; |
| |
411 return; |
| |
412 } |
| |
413 #if CX_WORDSIZE == 64 |
| |
414 if (elem_size == sizeof(int64_t)) { |
| |
415 *(int64_t*)dest = *(int64_t*)src; |
| |
416 return; |
| |
417 } |
| |
418 #endif |
| |
419 if (elem_size == sizeof(int8_t)) { |
| |
420 *(int8_t*)dest = *(int8_t*)src; |
| |
421 return; |
| |
422 } |
| |
423 if (elem_size == sizeof(int16_t)) { |
| |
424 *(int16_t*)dest = *(int16_t*)src; |
| |
425 return; |
| |
426 } |
| |
427 // note we cannot optimize the last branch, because |
| |
428 // the elem_size could be crazily misaligned |
| |
429 } |
| |
430 memcpy(dest, src, n * elem_size); |
| |
431 } else { |
| |
432 char *src = dest + n * elem_size; |
| |
433 memmove(dest, src, remaining * elem_size); |
| |
434 } |
| |
435 } |
| |
436 |
| 393 void cx_array_free_(const CxAllocator *allocator, CxArray *array) { |
437 void cx_array_free_(const CxAllocator *allocator, CxArray *array) { |
| 394 cxFree(allocator, array->data); |
438 cxFree(allocator, array->data); |
| 395 array->data = NULL; |
439 array->data = NULL; |
| 396 array->size = array->capacity = 0; |
440 array->size = array->capacity = 0; |
| 397 } |
441 } |
| 783 list->collection.size -= remove; |
827 list->collection.size -= remove; |
| 784 return remove; |
828 return remove; |
| 785 } |
829 } |
| 786 |
830 |
| 787 // just move the elements to the left |
831 // just move the elements to the left |
| 788 char *first_remaining = arl->data; |
|
| 789 first_remaining += (index + remove) * list->collection.elem_size; |
|
| 790 char *dst_move = arl->data; |
832 char *dst_move = arl->data; |
| 791 dst_move += index * list->collection.elem_size; |
833 dst_move += index * list->collection.elem_size; |
| |
834 char *first_remaining = dst_move + remove * list->collection.elem_size; |
| 792 memmove(dst_move, first_remaining, remaining * list->collection.elem_size); |
835 memmove(dst_move, first_remaining, remaining * list->collection.elem_size); |
| 793 |
836 |
| 794 // decrease the size |
837 // decrease the size |
| 795 list->collection.size -= remove; |
838 list->collection.size -= remove; |
| 796 |
839 |