#ifndef FRAMEWORK_CONTAINER_SINGLYLINKEDLIST_H_ #define FRAMEWORK_CONTAINER_SINGLYLINKEDLIST_H_ #include #include /** * @brief Linked list data structure, * each entry has a pointer to the next entry (singly) * @ingroup container */ template class LinkedElement { public: T *value; class Iterator { public: LinkedElement *value = nullptr; Iterator() {} Iterator(LinkedElement *element) : value(element) { } Iterator& operator++() { value = value->getNext(); return *this; } Iterator operator++(int) { Iterator tmp(*this); operator++(); return tmp; } bool operator==(Iterator other) { return value == other.value; } bool operator!=(Iterator other) { return !(*this == other); } T *operator->() { return value->value; } }; LinkedElement(T* setElement, LinkedElement* setNext = nullptr): value(setElement), next(setNext) {} virtual ~LinkedElement(){} virtual LinkedElement* getNext() const { return next; } virtual void setNext(LinkedElement* next) { this->next = next; } virtual void setEnd() { this->next = nullptr; } LinkedElement* begin() { return this; } LinkedElement* end() { return nullptr; } private: LinkedElement *next; }; template class SinglyLinkedList { public: using ElementIterator = typename LinkedElement::Iterator; SinglyLinkedList() {} SinglyLinkedList(ElementIterator start) : start(start.value) {} SinglyLinkedList(LinkedElement* startElement) : start(startElement) {} ElementIterator begin() const { return ElementIterator::Iterator(start); } /** Returns iterator to nulltr */ ElementIterator end() const { return ElementIterator::Iterator(); } /** * Returns last element in singly linked list. * @return */ ElementIterator back() const { LinkedElement *element = start; while (element->getNext() != nullptr) { element = element->getNext(); } return ElementIterator::Iterator(element); } size_t getSize() const { size_t size = 0; LinkedElement *element = start; while (element != nullptr) { size++; element = element->getNext(); } return size; } void setStart(LinkedElement* firstElement) { start = firstElement; } void setNext(LinkedElement* currentElement, LinkedElement* nextElement) { currentElement->setNext(nextElement); } void setLast(LinkedElement* lastElement) { lastElement->setEnd(); } void insertElement(LinkedElement* element, size_t position) { LinkedElement *currentElement = start; for(size_t count = 0; count < position; count++) { if(currentElement == nullptr) { return; } currentElement = currentElement->getNext(); } LinkedElement* elementAfterCurrent = currentElement->next; currentElement->setNext(element); if(elementAfterCurrent != nullptr) { element->setNext(elementAfterCurrent); } } void insertBack(LinkedElement* lastElement) { back().value->setNext(lastElement); } protected: LinkedElement *start = nullptr; }; #endif /* SINGLYLINKEDLIST_H_ */