#ifndef CIRCULARLIST_H #define CIRCULARLIST_H #include "LinkedList.h" namespace Kylin { template class CircularLinkedList : public LinkedList { using Node = typename LinkedList::Node; using Iterator = typename LinkedList::Iterator; public: CircularLinkedList() = default; CircularLinkedList(std::initializer_list init) { this->m_header.next = reinterpret_cast(&this->m_header); this->m_last = reinterpret_cast(&this->m_header); for (auto &value : init) { this->append(value); } } CircularLinkedList(const CircularLinkedList &other) { this->m_header.next = reinterpret_cast(&this->m_header); this->m_last = reinterpret_cast(&this->m_header); auto sourceNode = other.m_header.next; auto targetNode = reinterpret_cast(&this->m_header); for (size_t i = 0; i < other.m_size; i++) { auto newNode = this->create(); if (newNode == nullptr) THROW_EXCEPTION(NoEnoughMemoryException, "No memory to create node ..."); newNode->value = sourceNode->value; targetNode->next = newNode; targetNode = newNode; sourceNode = sourceNode->next; this->m_size++; targetNode->next = this->m_header.next; this->m_last = targetNode; } } CircularLinkedList(CircularLinkedList &&other) { this->m_size = other.m_size; this->m_header = other.m_header; this->m_last = other.m_last; other.m_size = 0; other.m_header.next = nullptr; other.m_last = reinterpret_cast(&other.m_header); } void insert(size_t index, const T &value) override { index = index % (this->m_size + 1); if (index == this->m_size) return this->append(value); LinkedList::insert(index, value); if (index == 0) lastToFirst(); } void removeAt(size_t index) override { if (this->size() <= 0) THROW_EXCEPTION(IndexOutOfBoundsException, "There is no element in the container."); index = mod(index); if (index == 0) { auto toDel = this->m_header.next; this->m_header.next = toDel->next; this->m_size--; if (this->m_size == 0) { this->m_header.next = nullptr; } else { lastToFirst(); } this->destroy(toDel); } else { LinkedList::removeAt(index); } } virtual void clear() { while (this->m_size > 1) { removeAt(1); } if (this->m_size == 1) { auto del = this->m_header.next; this->m_header.next = nullptr; this->m_size = 0; this->destroy(del); } } Iterator end() override { return Iterator(reinterpret_cast(&this->m_header)); } Iterator end() const override { return Iterator(reinterpret_cast(&this->m_header)); } T &operator[](size_t index) override { if (this->m_size <= 0) THROW_EXCEPTION(InvalidOperationException, "There is no element in the container..."); index = mod(index); return this->position(index)->next->value; } virtual ~CircularLinkedList() { clear(); } protected: size_t mod(size_t index) const { return (this->m_size == 0) ? 0 : (index % this->m_size); } void lastToFirst() { this->position(this->m_size - 1)->next->next = this->m_header.next; } }; } // namespace Kylin #endif // CIRCULARLIST_H