Advertisement
MeehoweCK

Untitled

May 13th, 2024
959
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.71 KB | None | 0 0
  1. #include <iostream>
  2. #include <iterator>
  3. #include <memory>
  4. #include <stdexcept>
  5.  
  6. template <typename T>
  7. class MyList {
  8.     friend std::ostream& operator<<(std::ostream& os, const MyList& list) {
  9.         if (list.list_size == 0) {
  10.             os << "The list is empty\n";
  11.         }
  12.         else {
  13.             os << "List elements:\n";
  14.             for (auto i : list) {
  15.                 os << '\t' << i << std::endl;
  16.             }
  17.         }
  18.         return os;
  19.     }
  20. private:
  21.     struct Node {
  22.         T data;
  23.         std::unique_ptr<Node> next;
  24.         Node(T data) : data{ data }, next{ nullptr } {}
  25.     };
  26.  
  27.     std::unique_ptr<Node> head;
  28.     size_t list_size{ 0 };
  29.  
  30. public:
  31.     MyList() : head{ nullptr } {}
  32.     ~MyList() { clear(); }
  33.  
  34.     void push_front(const T& value) {
  35.         std::unique_ptr<Node> newNode{ std::make_unique<Node>(value) };
  36.         newNode->next = std::move(head);
  37.         head = std::move(newNode);
  38.         ++list_size;
  39.     }
  40.  
  41.     T pop_front() {
  42.         if (head == nullptr) {
  43.             throw std::out_of_range("Cannot pop from an empty list");
  44.         }
  45.         T data{ std::move(head->data) };
  46.         head = std::move(head->next);
  47.         --list_size;
  48.         return data;
  49.     }
  50.  
  51.     T& front() {
  52.         if (head == nullptr) {
  53.             throw std::out_of_range("List is empty");
  54.         }
  55.         return head->data;
  56.     }
  57.  
  58.     const T& front() const {
  59.         if (head == nullptr) {
  60.             throw std::out_of_range("List is empty");
  61.         }
  62.         return head->data;
  63.     }
  64.  
  65.     void clear() {
  66.         while (head != nullptr) {
  67.             head = std::move(head->next);
  68.             --list_size;
  69.         }
  70.     }
  71.  
  72.     size_t size() const { return list_size; }
  73.  
  74.     void remove(const T& value) {
  75.         while (head != nullptr && head->data == value) {
  76.             head = std::move(head->next);
  77.             --list_size;
  78.         }
  79.  
  80.         Node* current{ head.get() };
  81.         while (current && current->next) {
  82.             if (current->next->data == value) {
  83.                 current->next = std::move(current->next->next);
  84.                 --list_size;
  85.             }
  86.             else {
  87.                 current = current->next.get();
  88.             }
  89.         }
  90.     }
  91.  
  92.     class ConstIterator {
  93.     private:
  94.         const Node* current;
  95.  
  96.     public:
  97.         using difference_type = std::ptrdiff_t;
  98.         using value_type = T;
  99.         using pointer = const T*;
  100.         using reference = const T&;
  101.         using iterator_category = std::forward_iterator_tag;
  102.  
  103.         ConstIterator(const Node* node) : current{ node } {}
  104.  
  105.         ConstIterator& operator++() {
  106.             if (current) {
  107.                 current = current->next.get();
  108.             }
  109.             return *this;
  110.         }
  111.  
  112.         ConstIterator operator++(int) {
  113.             ConstIterator tmp = *this;
  114.             ++(*this);
  115.             return tmp;
  116.         }
  117.  
  118.         reference operator*() const {
  119.             if (!current) {
  120.                 throw std::out_of_range("Dereferencing a null iterator");
  121.             }
  122.             return current->data;
  123.         }
  124.  
  125.         pointer operator->() const {
  126.             if (!current) {
  127.                 throw std::out_of_range("Dereferencing a null iterator");
  128.             }
  129.             return &current->data;
  130.         }
  131.  
  132.         bool operator!=(const ConstIterator& other) const {
  133.             return current != other.current;
  134.         }
  135.  
  136.         bool operator==(const ConstIterator& other) const {
  137.             return current == other.current;
  138.         }
  139.     };
  140.  
  141.     ConstIterator begin() const {
  142.         return ConstIterator(head.get());
  143.     }
  144.  
  145.     ConstIterator end() const {
  146.         return ConstIterator(nullptr);
  147.     }
  148. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement