#pragma once template class LinkedList { struct Node { DataType data; Node* next; Node* previous; Node(DataType data, Node* next, Node* previous): data(data), next(next), previous(previous) {} }; int count = 0; Node* head = nullptr; Node* tail = nullptr; public: class Iterator { Node *node = nullptr; public: Iterator(Node* node) : node(node) {} bool advance(size_t n) { size_t i = 0; if (n == 0) { return true; } for (; node && (i < n); ++i) { node = node->next; } return (i > 0); } DataType& operator* () { return node->data; } DataType* operator-> () { return &(node->data); } Iterator operator++ (int) { assert(advance(1)); Iterator i(node); return i; } bool operator==(const Iterator& right) const { return node == right.node; } bool operator!=(const Iterator& right) const { return node != right.node; } }; void pushFront(DataType data) { auto* new_node = new Node(data, head, nullptr); if (head != nullptr) { head->previous = new_node; } if (tail == nullptr) { tail = new_node; } head = new_node; count++; } void pushBack(DataType data) { auto* new_node = new Node(data, nullptr, tail); if (head == nullptr) { head = new_node; } if (tail != nullptr) { tail->next = new_node; } tail = new_node; count++; } void popFront() { if (head != nullptr) { bool is_last_node = (head == tail); Node* node_to_delete = head; head = node_to_delete->next; if (is_last_node) { tail = nullptr; } delete node_to_delete; count--; } } void popBack() { if (tail != nullptr) { bool is_last_node = (head == tail); Node* node_to_delete = tail; tail = node_to_delete->previous; if (is_last_node) { head = nullptr; } delete node_to_delete; count--; } } DataType back() const { assert(tail != nullptr); return tail->data; } DataType front() const { assert(head != nullptr); return head->data; } Iterator begin() const { return Iterator(head); } Iterator end() const { return Iterator(nullptr); } bool empty() const { return head == nullptr; } int size() const { return count; } DataType operator [] (int i) const { auto iter = begin(); assert(iter.advance(i)); return *iter; } DataType& operator [] (int i) { auto iter = begin(); assert(iter.advance(i)); return *iter; } };