// <editor-fold desc="Store Pointers Functionality">
-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,
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;
}
};
void cxListStoreObjects(CxList *list) {
+ list->store_pointer = false;
if (list->climpl != NULL) {
list->cl = list->climpl;
list->climpl = NULL;
}
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;
+// </editor-fold>
+
+// <editor-fold desc="empty list implementation">
+
+static void cx_emptyl_noop(__attribute__((__unused__)) CxList *list) {
+ // this is a noop, but MUST be implemented
}
-// </editor-fold>
+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;
+// </editor-fold>
+
+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);
} else {
return list->size < other->size ? -1 : 1;
}
+ } else {
+ // lists are compatible
+ return list->cl->compare(list, other);
}
}