add single instance mode
[uwplayer.git] / ucx / array_list.c
index 5c66d53..e59e648 100644 (file)
@@ -103,7 +103,7 @@ enum cx_array_copy_result cx_array_copy(
 }
 
 #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(
@@ -150,6 +150,7 @@ 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;
 
@@ -168,7 +169,24 @@ static void *cx_arl_realloc(
 
 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(
@@ -186,17 +204,17 @@ 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
         )) {
@@ -213,10 +231,10 @@ static size_t cx_arl_insert_array(
     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
     )) {
@@ -249,7 +267,7 @@ static int cx_arl_insert_iter(
         );
         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 {
@@ -271,11 +289,7 @@ static int cx_arl_remove(
     }
 
     // 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) {
@@ -287,10 +301,10 @@ static int cx_arl_remove(
     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
     );
@@ -307,26 +321,20 @@ static void cx_arl_clear(struct cx_list_s *list) {
     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;
 }
 
@@ -337,7 +345,7 @@ static int cx_arl_swap(
 ) {
     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;
 }
 
@@ -348,34 +356,35 @@ static void *cx_arl_at(
     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
     );
 }
@@ -393,8 +402,8 @@ static int cx_arl_compare(
             if (d != 0) {
                 return d;
             }
-            left += list->itemsize;
-            right += other->itemsize;
+            left += list->item_size;
+            right += other->item_size;
         }
         return 0;
     } else {
@@ -407,7 +416,7 @@ static void cx_arl_reverse(struct cx_list_s *list) {
     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);
     }
 }
 
@@ -433,7 +442,7 @@ static void cx_arl_iter_next(void *it) {
         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;
     }
 }
 
@@ -448,7 +457,7 @@ static void cx_arl_iter_prev(void *it) {
     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;
     }
 }
 
@@ -500,7 +509,7 @@ static cx_list_class cx_array_list_class = {
 
 CxList *cxArrayListCreate(
         CxAllocator const *allocator,
-        CxListComparator comparator,
+        cx_compare_func comparator,
         size_t item_size,
         size_t initial_capacity
 ) {
@@ -514,12 +523,12 @@ CxList *cxArrayListCreate(
     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);
     }