shushus

Спринт 7. Покоряем итераторы.

Jan 12th, 2023
297
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.91 KB | None | 0 0
  1. #include <cassert>
  2. #include <cstddef>
  3. #include <iterator>
  4. #include <string>
  5. #include <utility>
  6.  
  7. template <typename Type>
  8. class SingleLinkedList {
  9.  
  10.     struct Node {
  11.         Node() = default;
  12.         Node(const Type& val, Node* next) : value(val), next_node(next) {}
  13.         Type value;
  14.         Node* next_node = nullptr;
  15.     };
  16.  
  17.     template <typename ValueType>
  18.     class BasicIterator {
  19.    
  20.         friend class SingleLinkedList;
  21.  
  22.         explicit BasicIterator(Node* node) {
  23.             node_ = node;
  24.         }
  25.  
  26.     public:
  27.         using iterator_category = std::forward_iterator_tag;
  28.         using value_type = Type;
  29.         using difference_type = std::ptrdiff_t;
  30.         using pointer = ValueType*;
  31.         using reference = ValueType&;
  32.  
  33.         BasicIterator() = default;
  34.  
  35.         BasicIterator(const BasicIterator<Type>& other) noexcept {
  36.             node_ = other.node_;
  37.         }
  38.  
  39.         BasicIterator& operator=(const BasicIterator& rhs) = default;
  40.  
  41.         [[nodiscard]] bool operator==(const BasicIterator<const Type>& rhs) const noexcept {
  42.             return node_ == rhs.node_;
  43.         }
  44.  
  45.         [[nodiscard]] bool operator!=(const BasicIterator<const Type>& rhs) const noexcept {
  46.             return node_ != rhs.node_;
  47.         }
  48.  
  49.         [[nodiscard]] bool operator==(const BasicIterator<Type>& rhs) const noexcept {
  50.             return node_ == rhs.node_;
  51.         }
  52.  
  53.         [[nodiscard]] bool operator!=(const BasicIterator<Type>& rhs) const noexcept {
  54.             return node_ != rhs.node_;
  55.         }
  56.  
  57.         BasicIterator& operator++() noexcept {
  58.             node_ = node_->next_node;
  59.             return *this;
  60.         }
  61.  
  62.         BasicIterator operator++(int) noexcept {
  63.             auto old_value(*this);
  64.             ++(*this);
  65.             return old_value;
  66.         }
  67.  
  68.         [[nodiscard]] reference operator*() const noexcept {
  69.             return node_->value;
  70.         }
  71.  
  72.         [[nodiscard]] pointer operator->() const noexcept {
  73.             if(node_){
  74.                 return &node_->value;
  75.             }else{
  76.                 return nullptr;
  77.             }
  78.         }
  79.  
  80.     private:
  81.         Node* node_ = nullptr;
  82.     };
  83.  
  84. public:
  85.     SingleLinkedList() {}
  86.    
  87.     using value_type = Type;
  88.     using reference = value_type&;
  89.     using const_reference = const value_type&;
  90.  
  91.     using Iterator = BasicIterator<Type>;
  92.     using ConstIterator = BasicIterator<const Type>;
  93.  
  94.     [[nodiscard]] Iterator begin() noexcept {
  95.         return Iterator{head_.next_node};
  96.     }
  97.  
  98.     [[nodiscard]] Iterator end() noexcept {
  99.         return Iterator{nullptr};
  100.     }
  101.  
  102.     [[nodiscard]] ConstIterator begin() const noexcept {
  103.         return ConstIterator{head_.next_node};
  104.     }
  105.  
  106.     [[nodiscard]] ConstIterator end() const noexcept {
  107.         return ConstIterator{nullptr};
  108.     }
  109.  
  110.     [[nodiscard]] ConstIterator cbegin() const noexcept {
  111.         return ConstIterator{head_.next_node};
  112.     }
  113.  
  114.     [[nodiscard]] ConstIterator cend() const noexcept {
  115.         return ConstIterator{nullptr};
  116.     }
  117.  
  118.     [[nodiscard]] size_t GetSize() const noexcept {
  119.         return size_;
  120.     }
  121.  
  122.     [[nodiscard]] bool IsEmpty() const noexcept {
  123.         if (!size_) {
  124.         return true;
  125.         }
  126.         return false;
  127.     }
  128.    
  129.     void PushFront(const Type& value) {
  130.         head_.next_node = new Node(value, head_.next_node);
  131.         ++size_;
  132.     }
  133.  
  134.     void Clear() noexcept {
  135.         while (head_.next_node) {
  136.             Node* new_head = head_.next_node->next_node;
  137.             delete head_.next_node;
  138.             head_.next_node = new_head;
  139.         }
  140.         size_ = 0;
  141.     }
  142.    
  143.     ~SingleLinkedList() {
  144.         Clear();
  145.     }
  146.  
  147. private:
  148.     Node head_;
  149.     size_t size_ = 0;
  150. };
  151.  
  152. void Test2() {
  153.     {
  154.         SingleLinkedList<int> list;
  155.  
  156.         const auto& const_list = list;
  157.  
  158.         assert(list.begin() == list.end());
  159.         assert(const_list.begin() == const_list.end());
  160.         assert(list.cbegin() == list.cend());
  161.         assert(list.cbegin() == const_list.begin());
  162.         assert(list.cend() == const_list.end());
  163.     }
  164.  
  165.     {
  166.         SingleLinkedList<int> list;
  167.         const auto& const_list = list;
  168.  
  169.         list.PushFront(1);
  170.         assert(list.GetSize() == 1u);
  171.         assert(!list.IsEmpty());
  172.  
  173.         assert(const_list.begin() != const_list.end());
  174.         assert(const_list.cbegin() != const_list.cend());
  175.         assert(list.begin() != list.end());
  176.  
  177.         assert(const_list.begin() == const_list.cbegin());
  178.  
  179.         assert(*list.cbegin() == 1);
  180.         *list.begin() = -1;
  181.         assert(*list.cbegin() == -1);
  182.  
  183.         const auto old_begin = list.cbegin();
  184.         list.PushFront(2);
  185.         assert(list.GetSize() == 2);
  186.  
  187.         const auto new_begin = list.cbegin();
  188.         assert(new_begin != old_begin);
  189.  
  190.         {
  191.             auto new_begin_copy(new_begin);
  192.             assert((++(new_begin_copy)) == old_begin);
  193.         }
  194.  
  195.         {
  196.             auto new_begin_copy(new_begin);
  197.             assert(((new_begin_copy)++) == new_begin);
  198.             assert(new_begin_copy == old_begin);
  199.         }
  200.  
  201.         {
  202.             auto old_begin_copy(old_begin);
  203.             assert((++old_begin_copy) == list.end());
  204.         }
  205.     }
  206.  
  207.     {
  208.         SingleLinkedList<int> list;
  209.         list.PushFront(1);
  210.  
  211.         SingleLinkedList<int>::ConstIterator const_it(list.begin());
  212.         assert(const_it == list.cbegin());
  213.         assert(*const_it == *list.cbegin());
  214.  
  215.         SingleLinkedList<int>::ConstIterator const_it1;
  216.         const_it1 = list.begin();
  217.         assert(const_it1 == const_it);
  218.     }
  219.  
  220.     {
  221.         using namespace std;
  222.         SingleLinkedList<std::string> string_list;
  223.  
  224.         string_list.PushFront("one"s);
  225.         assert(string_list.cbegin()->length() == 3u);
  226.         string_list.begin()->push_back('!');
  227.         assert(*string_list.begin() == "one!"s);
  228.     }
  229. }
  230.  
  231. int main() {
  232.     Test2();
  233. }
Advertisement
Add Comment
Please, Sign In to add comment