X-Git-Url: https://develop.uap-core.de/gitweb/uwplayer.git/blobdiff_plain/5cb490b04836ef624cdd0ba975ee5c2ff2e51a23..01d5015ba093f8c5fdb18b669943c7da6450e72f:/ucx/list.c diff --git a/ucx/list.c b/ucx/list.c index ebfff65..cc96710 100644 --- a/ucx/list.c +++ b/ucx/list.c @@ -32,7 +32,7 @@ // -static _Thread_local CxListComparator cx_pl_cmpfunc_impl; +static _Thread_local cx_compare_func cx_pl_cmpfunc_impl; static int cx_pl_cmpfunc( void const *l, @@ -115,12 +115,12 @@ static void *cx_pl_at( return ptr == NULL ? NULL : *ptr; } -static size_t cx_pl_find( +static ssize_t cx_pl_find( struct cx_list_s const *list, void const *elem ) { cx_pl_hack_cmpfunc(list); - size_t ret = list->climpl->find(list, &elem); + ssize_t ret = list->climpl->find(list, &elem); cx_pl_unhack_cmpfunc(list); return ret; } @@ -179,6 +179,7 @@ static cx_list_class cx_pointer_list_class = { }; void cxListStoreObjects(CxList *list) { + list->store_pointer = false; if (list->climpl != NULL) { list->cl = list->climpl; list->climpl = NULL; @@ -186,90 +187,111 @@ void cxListStoreObjects(CxList *list) { } void cxListStorePointers(CxList *list) { - list->itemsize = sizeof(void *); + list->item_size = sizeof(void *); + list->store_pointer = true; list->climpl = list->cl; list->cl = &cx_pointer_list_class; } -bool cxListIsStoringPointers(CxList const *list) { - return list->climpl != NULL; +// + +// + +static void cx_emptyl_noop(__attribute__((__unused__)) CxList *list) { + // this is a noop, but MUST be implemented } -// +static void *cx_emptyl_at( + __attribute__((__unused__)) struct cx_list_s const *list, + __attribute__((__unused__)) size_t index +) { + return NULL; +} -void cx_list_invoke_destructor( - CxList const *list, - void *elem +static ssize_t cx_emptyl_find( + __attribute__((__unused__)) struct cx_list_s const *list, + __attribute__((__unused__)) void const *elem ) { - switch (list->content_destructor_type) { - case CX_DESTRUCTOR_SIMPLE: { - cx_list_invoke_simple_destructor(list, elem); - break; - } - case CX_DESTRUCTOR_ADVANCED: { - cx_list_invoke_advanced_destructor(list, elem); - break; - } - case CX_DESTRUCTOR_NONE: - break; // nothing - } + return -1; } -void cx_list_invoke_simple_destructor( - CxList const *list, - void *elem +static int cx_emptyl_compare( + __attribute__((__unused__)) struct cx_list_s const *list, + struct cx_list_s const *other ) { - if (cxListIsStoringPointers(list)) { - elem = *((void **) elem); - } - list->simple_destructor(elem); + if (other->size == 0) return 0; + return -1; } -void cx_list_invoke_advanced_destructor( - CxList const *list, - void *elem +static bool cx_emptyl_iter_valid(__attribute__((__unused__)) void const *iter) { + return false; +} + +static CxIterator cx_emptyl_iterator( + struct cx_list_s const *list, + size_t index, + __attribute__((__unused__)) bool backwards ) { - if (cxListIsStoringPointers(list)) { - elem = *((void **) elem); - } - list->advanced_destructor.func(list->advanced_destructor.data, elem); + CxIterator iter = {0}; + iter.src_handle = list; + iter.index = index; + iter.base.valid = cx_emptyl_iter_valid; + return iter; } -void cxListDestroy(CxList *list) { - switch (list->content_destructor_type) { - case CX_DESTRUCTOR_SIMPLE: { - CxIterator iter = cxListIterator(list); - cx_foreach(void*, elem, iter) { - // already correctly resolved pointer - immediately invoke dtor - list->simple_destructor(elem); - } - break; - } - case CX_DESTRUCTOR_ADVANCED: { - CxIterator iter = cxListIterator(list); - cx_foreach(void*, elem, iter) { - // already correctly resolved pointer - immediately invoke dtor - list->advanced_destructor.func(list->advanced_destructor.data, elem); - } - break; - } - case CX_DESTRUCTOR_NONE: - break; // nothing - } +static cx_list_class cx_empty_list_class = { + cx_emptyl_noop, + NULL, + NULL, + NULL, + NULL, + cx_emptyl_noop, + NULL, + cx_emptyl_at, + cx_emptyl_find, + cx_emptyl_noop, + cx_emptyl_compare, + cx_emptyl_noop, + cx_emptyl_iterator, +}; + +CxList cx_empty_list = { + NULL, + NULL, + 0, + 0, + NULL, + NULL, + NULL, + false, + &cx_empty_list_class, + NULL +}; + +CxList *const cxEmptyList = &cx_empty_list; +// + +void cxListDestroy(CxList *list) { list->cl->destructor(list); - cxFree(list->allocator, list); } int cxListCompare( CxList const *list, CxList const *other ) { - if (list->cl->compare == other->cl->compare) { - // same compare function, lists are compatible - return list->cl->compare(list, other); - } else { - // different compare functions, use iterator + if ( + // if one is storing pointers but the other is not + (list->store_pointer ^ other->store_pointer) || + + // if one class is wrapped but the other is not + ((list->climpl == NULL) ^ (other->climpl == NULL)) || + + // if the resolved compare functions are not the same + ((list->climpl != NULL ? list->climpl->compare : list->cl->compare) != + (other->climpl != NULL ? other->climpl->compare : other->cl->compare)) + ) { + // lists are definitely different - cannot use internal compare function if (list->size == other->size) { CxIterator left = cxListIterator(list); CxIterator right = cxListIterator(other); @@ -287,6 +309,9 @@ int cxListCompare( } else { return list->size < other->size ? -1 : 1; } + } else { + // lists are compatible + return list->cl->compare(list, other); } }