#ifndef LINKED_QUEUE_IMPL #define LINKED_QUEUE_IMPL #include template class LinkedQueue { private: struct LinkedNode { T data; LinkedNode* next; LinkedNode(const T& argData, LinkedNode* argNext = nullptr) : data {argData}, next{argNext} {} }; LinkedNode* head; // Първия добавен елемент в опашката LinkedNode* tail; // Последния добавен елемент в опашката size_t queueSize; void copy(const LinkedQueue&); void free(); public: LinkedQueue(); LinkedQueue(const LinkedQueue&); LinkedQueue& operator=(const LinkedQueue&); LinkedQueue(LinkedQueue&&) noexcept; LinkedQueue& operator=(LinkedQueue&&) noexcept; void push(const T&); void pop(); const T& front() const; bool empty() const; size_t size() const; ~LinkedQueue(); }; template LinkedQueue::LinkedQueue() : head {nullptr}, tail{nullptr}, queueSize{0} {} template LinkedQueue::LinkedQueue(const LinkedQueue& other) { copy(other); } template LinkedQueue& LinkedQueue::operator=(const LinkedQueue& other) { if(this != &other){ free(); copy(other); } return *this; } template LinkedQueue::LinkedQueue(LinkedQueue&& other) noexcept { head = other.head; tail = other.tail; size = other.size; other.head = nullptr; other.tail = nullptr; } template LinkedQueue& LinkedQueue::operator=(LinkedQueue&& other) noexcept { if(this != &other) { head = other.head; tail = other.tail; size = other.size; other.head = nullptr; other.tail = nullptr; } return *this; } template void LinkedQueue::copy(const LinkedQueue& other) { LinkedNode* iter = other.head; while(iter) { push(iter->data); iter = iter->next; } } template void LinkedQueue::free() { LinkedNode* iter = head; while(iter) { LinkedNode* removeMe = iter; iter = iter->next; delete removeMe; } } template bool LinkedQueue::empty() const { return head == nullptr; } template size_t LinkedQueue::size() const { return queueSize; } template void LinkedQueue::push(const T& elem) { LinkedNode* toPush = new LinkedNode(elem); if(empty()) { tail = toPush; head = toPush; } else { tail->next = toPush; tail = toPush; } ++queueSize; } template void LinkedQueue::pop() { if(empty()) { throw "Empty queue"; } else if(head == tail) { delete head; head = nullptr; tail = nullptr; } else { LinkedNode* deleteMe = head; head = head->next; delete deleteMe; } --queueSize; } template const T& LinkedQueue::front() const { if(empty()){ throw "Empty queue"; } return head->data; } template LinkedQueue::~LinkedQueue() { free(); } #endif