#ifndef __LSTACK_HPP #define __LSTACK_HPP #include #include #include #include "abstract_stack.hpp" template struct StackElement { T data; StackElement* next; }; template class LinkedStack : public AbstractStack { private: // указател към двойната кутия, която е връх на стека StackElement* top; // копиране на стек void copyStack(LinkedStack const&); // изтриване на стек void erase(); public: // създаване на празен стек LinkedStack(); // конструктор за копиране LinkedStack(LinkedStack const&); // операция за присвояване LinkedStack& operator=(LinkedStack const&); // конструктор за преместване LinkedStack(LinkedStack&&); // операция за преместване LinkedStack& operator=(LinkedStack&&); // деструктор ~LinkedStack(); // проверка за празнота bool empty() const; // включване на елемент void push(T const& x); // намиране на последния включен елемент T const& peek() const; // намиране на последния включен елемент с възможност за промяна T& peek(); // безопасно намиране на последния включен елемент с индикация за успех bool peek(T&) const; // изключване на последния включен елемент T pop(); // изключване на последния включен елемент с код за грешка T pop(bool& success); void steal(LinkedStack&& other) { if (top != nullptr) //erase(); throw std::runtime_error("Кражба от непразен обект!"); top = other.top; other.top = nullptr; } }; // създаване на празен стек // O(1) template LinkedStack::LinkedStack() : top(nullptr) {} // копиране на стек template LinkedStack::LinkedStack(LinkedStack const& other) : top(nullptr) { //std::clog << "Копиране на LinkedStack" << std::endl; copyStack(other); } // деструктор template LinkedStack::~LinkedStack() { erase(); } template void LinkedStack::erase() { // !!! delete top; while (!empty()) pop(); // домашно: реализирайте го директно с представянето } template void LinkedStack::copyStack(LinkedStack const& other) { if (other.top != nullptr) { // other не е празен StackElement* lastAdded = top = new StackElement{other.top->data, nullptr}; StackElement* nextToCopy = other.top->next; while (nextToCopy) { lastAdded = lastAdded->next = new StackElement{nextToCopy->data, nullptr}; nextToCopy = nextToCopy->next; } } } template LinkedStack& LinkedStack::operator=(LinkedStack const& other) { //std::clog << "Присвояване на LinkedStack" << std::endl; if (this != &other) { erase(); copyStack(other); } return *this; } // проверка за празнота // O(1) template bool LinkedStack::empty() const { return top == nullptr; } // включване на елемент // O(1) template void LinkedStack::push(T const& x) { top = new StackElement{x, top}; } // поглеждане на последния включен елемент // O(1) template T const& LinkedStack::peek() const { if (empty()) throw std::runtime_error("Опит за поглеждане на елемент в празен стек"); return top->data; } // поглеждане на последния включен елемент с възможност за промяна // O(1) template T& LinkedStack::peek() { if (empty()) throw std::runtime_error("Опит за поглеждане на елемент в празен стек"); return top->data; } // поглеждане на последния включен елемент // O(1) template bool LinkedStack::peek(T& result) const { if (empty()) return false; result = top->data; return true; } // изключване на последния включен елемент // O(1) template T LinkedStack::pop() { if (empty()) throw std::runtime_error("Опит за изключване на елемент в празен стек"); StackElement* newtop = top->next; T x = top->data; delete top; top = newtop; return x; } // изключване на последния включен елемент // O(1) template T LinkedStack::pop(bool& success) { if (empty()) { success = false; return T(); } success = true; return pop(); } // O(1) template LinkedStack::LinkedStack(LinkedStack&& other) : top(other.top) { std::clog << "Конструктор за преместване на LinkedStack" << std::endl; other.top = nullptr; } // template LinkedStack& LinkedStack::operator=(LinkedStack&& other) { std::cout << "Операция за преместване на LinkedStack" << std::endl; if (this != &other) { erase(); top = other.top; other.top = nullptr; } return *this; } #endif