/
dolpement
/
OOP
Обзор
Документация
Войти
/
dolpement
/
OOP
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
stack_base_prj/stack_base/stack_lst_t.hpp
209 строк
5 KB
dolpement
OOP
16 июл 2025, 15:40
16 июл 2025, 15:40
d149512
Код
Авторство
О чём код?
#ifndef STACKLSTT_HPP #define STACKLSTT_HPP #include "stack_base.hpp" #include <initializer_list> #include <stdexcept> #include <utility> #include <cstddef> #include <vector> template <typename T> class StackLstT : public IStackBase<T> { public: using value_type = typename IStackBase<T>::value_type; StackLstT() = default; ~StackLstT() { clear(); } StackLstT(const StackLstT& other) { copyFrom(other); } StackLstT(StackLstT&& other) noexcept : head_(other.head_), tail_(other.tail_) { other.head_ = nullptr; other.tail_ = nullptr; } StackLstT(const std::initializer_list<T>& list) { for (const auto& item : list) { push(item); } } void push(const T& value) override { Node* new_node = new Node{value, nullptr}; if (empty()) { head_ = tail_ = new_node; } else { tail_->next = new_node; tail_ = new_node; } } void pop() override { if (empty()) { throw std::out_of_range("Stack underflow"); } if (head_ == tail_) { delete head_; head_ = tail_ = nullptr; } else { Node* current = head_; while (current->next != tail_) { current = current->next; } delete tail_; tail_ = current; tail_->next = nullptr; } } T& top() const override { if (empty()) { throw std::out_of_range("Stack underflow"); } return tail_->value; } void swap(StackLstT& other) noexcept { std::swap(head_, other.head_); std::swap(tail_, other.tail_); } void swap(IStackBase<T>& other) override { if (auto* p = dynamic_cast<StackLstT*>(&other)) { swap(*p); } else { throw std::invalid_argument("Incompatible stack types for swap"); } } void merge(IStackBase<T>& other) override { if (auto* p = dynamic_cast<StackLstT*>(&other)) { merge(*p); } else { throw std::invalid_argument("Incompatible stack types for merge"); } } void merge(StackLstT& other) { if (other.empty()) return; if (empty()) { head_ = other.head_; tail_ = other.tail_; } else { tail_->next = other.head_; tail_ = other.tail_; } other.head_ = nullptr; other.tail_ = nullptr; } bool empty() const override { return head_ == nullptr; } std::ptrdiff_t size() const override { std::ptrdiff_t count = 0; for (Node* current = head_; current != nullptr; current = current->next) { ++count; } return count; } bool operator==(const IStackBase<T>& rhs) const override { if (auto* p = dynamic_cast<const StackLstT*>(&rhs)) { return *this == *p; } return false; } bool operator==(const StackLstT& rhs) const { Node* current_this = head_; Node* current_rhs = rhs.head_; while (current_this != nullptr && current_rhs != nullptr) { if (current_this->value != current_rhs->value) { return false; } current_this = current_this->next; current_rhs = current_rhs->next; } return current_this == nullptr && current_rhs == nullptr; } bool operator!=(const IStackBase<T>& rhs) const override { return !(*this == rhs); } StackLstT& operator=(const StackLstT& rhs) { if (this != &rhs) { clear(); copyFrom(rhs); } return *this; } StackLstT& operator=(StackLstT&& rhs) noexcept { if (this != &rhs) { clear(); head_ = rhs.head_; tail_ = rhs.tail_; rhs.head_ = nullptr; rhs.tail_ = nullptr; } return *this; } void printToStream(std::ostream& os) const override { os << "{ "; // Собираем элементы в вектор для правильного порядка вывода std::vector<T> elements; for (Node* current = head_; current != nullptr; current = current->next) { elements.push_back(current->value); } for (size_t i = 0; i < elements.size(); ++i) { os << elements[i]; if (i != elements.size() - 1) { os << ", "; } } os << " }"; } private: struct Node { T value; Node* next = nullptr; }; Node* head_ = nullptr; Node* tail_ = nullptr; void clear() { while (!empty()) { pop(); } } void copyFrom(const StackLstT& other) { if (!other.empty()) { Node* current = other.head_; while (current != nullptr) { push(current->value); current = current->next; } } } }; #endif // STACKLSTT_HPP