}
#ifndef CX_ARRAY_SWAP_SBO_SIZE
-#define CX_ARRAY_SWAP_SBO_SIZE 512
+#define CX_ARRAY_SWAP_SBO_SIZE 128
#endif
void cx_array_swap(
typedef struct {
struct cx_list_s base;
void *data;
+ size_t capacity;
struct cx_array_reallocator_s reallocator;
} cx_array_list;
static void cx_arl_destructor(struct cx_list_s *list) {
cx_array_list *arl = (cx_array_list *) list;
+
+ char *ptr = arl->data;
+
+ if (list->simple_destructor) {
+ for (size_t i = 0; i < list->size; i++) {
+ cx_invoke_simple_destructor(list, ptr);
+ ptr += list->item_size;
+ }
+ }
+ if (list->advanced_destructor) {
+ for (size_t i = 0; i < list->size; i++) {
+ cx_invoke_advanced_destructor(list, ptr);
+ ptr += list->item_size;
+ }
+ }
+
cxFree(list->allocator, arl->data);
+ cxFree(list->allocator, list);
}
static size_t cx_arl_insert_array(
// do we need to move some elements?
if (index < list->size) {
char const *first_to_move = (char const *) arl->data;
- first_to_move += index * list->itemsize;
+ first_to_move += index * list->item_size;
size_t elems_to_move = list->size - index;
size_t start_of_moved = index + n;
if (CX_ARRAY_COPY_SUCCESS != cx_array_copy(
&arl->data,
&list->size,
- &list->capacity,
+ &arl->capacity,
start_of_moved,
first_to_move,
- list->itemsize,
+ list->item_size,
elems_to_move,
&arl->reallocator
)) {
if (CX_ARRAY_COPY_SUCCESS == cx_array_copy(
&arl->data,
&list->size,
- &list->capacity,
+ &arl->capacity,
index,
array,
- list->itemsize,
+ list->item_size,
n,
&arl->reallocator
)) {
);
if (result == 0 && prepend != 0) {
iter->index++;
- iter->elem_handle = ((char *) iter->elem_handle) + list->itemsize;
+ iter->elem_handle = ((char *) iter->elem_handle) + list->item_size;
}
return result;
} else {
}
// content destruction
- if (list->content_destructor_type != CX_DESTRUCTOR_NONE) {
- char *ptr = arl->data;
- ptr += index * list->itemsize;
- cx_list_invoke_destructor(list, ptr);
- }
+ cx_invoke_destructor(list, ((char *) arl->data) + index * list->item_size);
// short-circuit removal of last element
if (index == list->size - 1) {
int result = cx_array_copy(
&arl->data,
&list->size,
- &list->capacity,
+ &arl->capacity,
index,
- ((char *) arl->data) + (index + 1) * list->itemsize,
- list->itemsize,
+ ((char *) arl->data) + (index + 1) * list->item_size,
+ list->item_size,
list->size - index - 1,
&arl->reallocator
);
cx_array_list *arl = (cx_array_list *) list;
char *ptr = arl->data;
- switch (list->content_destructor_type) {
- case CX_DESTRUCTOR_SIMPLE: {
- for (size_t i = 0; i < list->size; i++) {
- cx_list_invoke_simple_destructor(list, ptr);
- ptr += list->itemsize;
- }
- break;
+ if (list->simple_destructor) {
+ for (size_t i = 0; i < list->size; i++) {
+ cx_invoke_simple_destructor(list, ptr);
+ ptr += list->item_size;
}
- case CX_DESTRUCTOR_ADVANCED: {
- for (size_t i = 0; i < list->size; i++) {
- cx_list_invoke_advanced_destructor(list, ptr);
- ptr += list->itemsize;
- }
- break;
+ }
+ if (list->advanced_destructor) {
+ for (size_t i = 0; i < list->size; i++) {
+ cx_invoke_advanced_destructor(list, ptr);
+ ptr += list->item_size;
}
- case CX_DESTRUCTOR_NONE:
- break; // nothing
}
- memset(arl->data, 0, list->size * list->itemsize);
+ memset(arl->data, 0, list->size * list->item_size);
list->size = 0;
}
) {
if (i >= list->size || j >= list->size) return 1;
cx_array_list *arl = (cx_array_list *) list;
- cx_array_swap(arl->data, list->itemsize, i, j);
+ cx_array_swap(arl->data, list->item_size, i, j);
return 0;
}
if (index < list->size) {
cx_array_list const *arl = (cx_array_list const *) list;
char *space = arl->data;
- return space + index * list->itemsize;
+ return space + index * list->item_size;
} else {
return NULL;
}
}
-static size_t cx_arl_find(
+static ssize_t cx_arl_find(
struct cx_list_s const *list,
void const *elem
) {
assert(list->cmpfunc != NULL);
+ assert(list->size < SIZE_MAX / 2);
char *cur = ((cx_array_list const *) list)->data;
- for (size_t i = 0; i < list->size; i++) {
+ for (ssize_t i = 0; i < (ssize_t) list->size; i++) {
if (0 == list->cmpfunc(elem, cur)) {
return i;
}
- cur += list->itemsize;
+ cur += list->item_size;
}
- return list->size;
+ return -1;
}
static void cx_arl_sort(struct cx_list_s *list) {
assert(list->cmpfunc != NULL);
qsort(((cx_array_list *) list)->data,
list->size,
- list->itemsize,
+ list->item_size,
list->cmpfunc
);
}
if (d != 0) {
return d;
}
- left += list->itemsize;
- right += other->itemsize;
+ left += list->item_size;
+ right += other->item_size;
}
return 0;
} else {
void *data = ((cx_array_list const *) list)->data;
size_t half = list->size / 2;
for (size_t i = 0; i < half; i++) {
- cx_array_swap(data, list->itemsize, i, list->size - 1 - i);
+ cx_array_swap(data, list->item_size, i, list->size - 1 - i);
}
}
iter->index++;
iter->elem_handle =
((char *) iter->elem_handle)
- + ((struct cx_list_s const *) iter->src_handle)->itemsize;
+ + ((struct cx_list_s const *) iter->src_handle)->item_size;
}
}
iter->index--;
if (iter->index < list->base.size) {
iter->elem_handle = ((char *) list->data)
- + iter->index * list->base.itemsize;
+ + iter->index * list->base.item_size;
}
}
CxList *cxArrayListCreate(
CxAllocator const *allocator,
- CxListComparator comparator,
+ cx_compare_func comparator,
size_t item_size,
size_t initial_capacity
) {
list->base.cl = &cx_array_list_class;
list->base.allocator = allocator;
list->base.cmpfunc = comparator;
- list->base.capacity = initial_capacity;
+ list->capacity = initial_capacity;
if (item_size > 0) {
- list->base.itemsize = item_size;
+ list->base.item_size = item_size;
} else {
- item_size = sizeof(void*);
+ item_size = sizeof(void *);
cxListStorePointers((CxList *) list);
}