void list_add_list(List* list, const List* ll) { ListData data; assert(list_is_valid(list)); assert(list_is_valid(ll)); assert(list->type == LIST_LIST); data.list = list_copy(ll); list_add_data(list, &data); }
List* list_new_list(const List* list) { ListData data; assert(list_is_valid(list)); data.list = list_copy(list); return list_new(LIST_LIST, &data); }
List* list_copy(const List* source) { List* list = (List*)source; assert(list_is_valid(list)); list->refc++; return list; }
const Tuple* list_get_tuple(const List* list, ListElem** idxp) { ListData* data; assert(list_is_valid(list)); assert(list->type == LIST_TUPLE); assert(idxp != NULL); data = list_get_data(list, idxp); return (data == NULL) ? TUPLE_NULL : data->tuple; }
const Elem* list_get_elem(const List* list, ListElem** idxp) { ListData* data; assert(list_is_valid(list)); assert(list->type == LIST_ELEM); assert(idxp != NULL); data = list_get_data(list, idxp); return (data == NULL) ? ELEM_NULL : data->elem; }
void list_insert_entry(List* list, const Entry* entry) { ListData data; assert(list_is_valid(list)); assert(entry_is_valid(entry)); assert(list->type == LIST_ENTRY); data.entry = entry_copy(entry); list_insert_data(list, &data); }
void list_insert_tuple(List* list, const Tuple* tuple) { ListData data; assert(list_is_valid(list)); assert(tuple_is_valid(tuple)); assert(list->type == LIST_TUPLE); data.tuple = tuple_copy(tuple); list_insert_data(list, &data); }
void list_insert_elem(List* list, const Elem* elem) { ListData data; assert(list_is_valid(list)); assert(elem_is_valid(elem)); assert(list->type == LIST_ELEM); data.elem = elem_copy(elem); list_insert_data(list, &data); }
const List* list_get_list(const List* list, ListElem** idxp) { ListData* data; assert(list_is_valid(list)); assert(list->type == LIST_LIST); assert(idxp != NULL); data = list_get_data(list, idxp); return (data == NULL) ? LIST_NULL : data->list; }
const Entry* list_get_entry(const List* list, ListElem** idxp) { ListData* data; assert(list_is_valid(list)); assert(list->type == LIST_ENTRY); assert(idxp != NULL); data = list_get_data(list, idxp); return (data == NULL) ? ENTRY_NULL : data->entry; }
static ListData* list_get_data(const List* list, ListElem** idxp) { assert(list_is_valid(list)); assert(idxp != NULL); if (*idxp == NULL) *idxp = list->anchor.next; if (*idxp == &list->anchor) return NULL; *idxp = (*idxp)->next; return &((*idxp)->prev->data); }
static void list_add_data(List* list, const ListData* data) { ListElem* elem = blk_alloc(sizeof(*elem)); assert(list_is_valid(list)); assert(elem != NULL); assert(data != NULL); elem->data = *data; elem->next = &list->anchor; elem->prev = list->anchor.prev; list->anchor.prev->next = elem; list->anchor.prev = elem; list->elems++; }
void list_astarnode::push_back(astarnode *data) { if (!data) return; if (!list_is_valid()) { dataptr = data; lastelem = this; } else { lastelem->next = new linked_astarnode; lastelem->next->prev = lastelem; lastelem = lastelem->next; lastelem->dataptr = data; } }
void list_astarnode::push_front(astarnode *data) { if (!data) return; if (!list_is_valid()) { dataptr = data; lastelem = this; } else { linked_astarnode *oldhead = new linked_astarnode; oldhead->dataptr = dataptr; oldhead->next = next; oldhead->prev = this; if(oldhead->next) oldhead->next->prev = oldhead; dataptr = data; next = oldhead; if (lastelem == this) lastelem = lastelem->next; } }
astarnode *list_astarnode::pop_back(void) { if (!list_is_valid()) return nullptr; astarnode *retval = lastelem->dataptr; if (lastelem == this) { lastelem = nullptr; dataptr = nullptr; prev = nullptr; next = nullptr; } else { lastelem = lastelem->prev; delete lastelem->next; lastelem->next = nullptr; } return retval; }
static List* list_new(ListType type, const ListData* data) { List* list = calloc(1, sizeof(*list)); assert(list != NULL); assert(data != NULL); list->refc = 1; list->elems = 0; list->type = type; list->anchor.prev = &list->anchor; list->anchor.next = &list->anchor; SID_set(list, LIST_SID); assert(list_is_valid(list)); list_add_data(list, data); return list; }
astarnode *list_astarnode::pop_front(void) { if (!list_is_valid()) return nullptr; astarnode *retval = dataptr; if (lastelem == this) { lastelem = nullptr; dataptr = nullptr; prev = nullptr; next = nullptr; } else { dataptr = next->dataptr; next = next->next; prev = nullptr; } return retval; }
void list_free(List* list) { ListElem* p; ListElem* q; assert(list_is_valid(list)); list->refc--; if (list->refc == 0) { SID_del(list); for(p = list->anchor.next; p != &list->anchor; p = q) { q = p->next; switch(list->type) { case LIST_ELEM : elem_free(p->data.elem); break; case LIST_TUPLE : tuple_free(p->data.tuple); break; case LIST_ENTRY : entry_free(p->data.entry); break; case LIST_IDXELEM : break; case LIST_LIST : list_free(p->data.list); break; default : abort(); } blk_free(p, sizeof(*p)); } free(list); } }
int list_get_elems(const List* list) { assert(list_is_valid(list)); return list->elems; }
Bool list_is_elemlist(const List* list) { assert(list_is_valid(list)); return list->type == LIST_ELEM; }
Bool list_is_entrylist(const List* list) { assert(list_is_valid(list)); return list->type == LIST_ENTRY; }
Bool list_is_tuplelist(const List* list) { assert(list_is_valid(list)); return list->type == LIST_TUPLE; }