#include #include namespace List { template struct Node { T value; std::unique_ptr> next; Node(T const & _value) : value(_value), next(nullptr) {} }; template class List { protected: std::unique_ptr> root; Node * tailPtr; std::size_t size; public: void Append(T const value) { ++size; if(tailPtr == nullptr) { root = std::make_unique>(value); tailPtr = root.get(); return; } tailPtr->next = std::make_unique>(value); tailPtr = tailPtr->next.get(); } void Prepend(T const value) { ++size; if(root == nullptr) { root = std::make_unique>(value); tailPtr = root.get(); return; } auto newRoot = std::make_unique>(value); newRoot->next.swap(root); root.swap(newRoot); } void Insert(T const value, std::size_t const index) { if(index >= size) { throw std::out_of_range("Index is greater or equal to size."); } if(index == 0u) { Prepend(value); return; } if(index == size - 1u) { Append(value); return; } ++size; Node * prevPtr = root.get(); Node * curPtr = root->next.get(); std::size_t currentIndex = 1u; while(currentIndex < index) { prevPtr = curPtr; curPtr = curPtr->next().get(); } auto newNode = std::make_unique>(value); newNode->next.swap(prevPtr->next); prevPtr->next.swap(newNode); } void Delete(std::size_t const index) { if(index >= size) { throw std::out_of_range("Index is greater or equal to size."); } --size; if(index == 0u) { root.swap(root->next); return; } if(index == size - 1u) { Node * curPtr = root.get(); std::size_t currentIndex = 0u; while(currentIndex < index - 2u) { curPtr = curPtr->next().get(); } curPtr->next.release(); return; } Node * prevPtr = root.get(); Node * curPtr = root->next.get(); std::size_t currentIndex = 1u; while(currentIndex < index) { prevPtr = curPtr; curPtr = curPtr->next().get(); } prevPtr->next.swap(curPtr->next); } T & Front() { if(size == 0u) { throw std::out_of_range("List is empty."); } return root->value; } T & Back() { if(size == 0u) { throw std::out_of_range("List is empty."); } return tailPtr->value; } T & operator[](std::size_t const index) { if(index >= size) { throw std::out_of_range("Index is greater or equal to size."); } Node * currentNode = root.get(); std:size_t currentIndex = 0u; while(currentIndex < index) { currentNode = currentNode->next.get(); } return currentNode->value; } List() : root(nullptr), tailPtr(nullptr) {} }; }