#ifndef LINKED_LIST_H #define LINKED_LIST_H template struct llink { llink* before = nullptr; llink* after = nullptr; T* value; llink () { }; llink (T* val) : value(val) { } ~llink () { this->unlink(); } void unlink (); }; template struct llist { llink* head; llink* tail; llink* __cur; T* cur() { return __cur->value; } int length = 0; llist (); void push ( T* ); T& peek (); T& pop (); /* * Adds two linked lists together. * O(1) time. * destroys new__ in the process, but keeps the elements. * make sure to free(new__) after. */ void operator += (llist& other); int size () { return length; } bool empty () { return length == 0; } void reset (); }; template llist::llist () { this->__cur = this->head = new llink; this->tail = new llink; head->after = tail; tail->before = head; } #define FIRST(lst) (lst)->head->after #define FIRST_V(lst) (lst)->head->after->value #define LAST(lst) (lst)->tail->before #define LAST_V(lst) (lst)->tail->before->value template void llist::push(T* val) { auto l = new llink(val); l->after = FIRST(this); FIRST(this) = l; l->after->before = l; l->before = this->head; ++this->length; // TODO do I want to change that? this->__cur = l; } template void llist::reset () { llink *link = this->head, *next; while (link != this->tail) { next = link->after; delete link; link = next; } this->__cur = this->head; } template void llink::unlink () { if (this->before != nullptr) this->before->after = this->after; if (this->after != nullptr) this->after->before = this->before; } template T& llist::peek() { if (this->empty()) return nullptr; return FIRST(this)->value; } template T& llist::pop() { if (this->empty()) return nullptr; llink* frst = FIRST(this); frst.unlinke(); T& retval = frst->value; --this->length; delete frst; return retval; } template void llist::operator+= (llist& other) { /* Link end of dest onto start of new__. */ LAST(this)->after = FIRST(other); FIRST(other)->before = LAST(this); /* Free the two now not needed end links. */ delete other->head; delete other->tail; /* Update dest with new__ tail ptr. */ this->tail = other->tail; this->length += other->length; } // template // std::ostream& std::operator<<(std::ostream&, llist); #if 0 DEEP_COPY LINK(TYPE)* n = FIRST(src); while (n->after != NULL) { NEW(TYPE, cpy); DEEP_COPY(TYPE)(cpy, n->value); PUSH(LLIST(TYPE)) ( dest, cpy ); n = n->after; } return 0; #endif /* * Resets a linked list by removing all it's objects. * FREE's all elements stored in the list. */ // int RESET(LLIST(TYPE)) ( LLIST(TYPE)* llist ); #if 0 LLIST(TYPE)* RESOLVE(LLIST(TYPE)) (LLIST(TYPE)* dest, LLIST(TYPE)* new_); if (dest == NULL) return new__; APPEND(LLIST(TYPE))(dest, new__); return dest; #endif #endif /* LINKED_LIST_H */