shushus

Спринт 7. Вставка элементов и очистка списка.

Jan 12th, 2023
209
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.83 KB | None | 0 0
  1. #include <cassert>
  2. #include <cstddef>
  3. #include <string>
  4. #include <utility>
  5.  
  6. template <typename Type>
  7. class SingleLinkedList {
  8.     struct Node {
  9.         Node() = default;
  10.         Node(const Type& val, Node* next) : value(val), next_node(next) {}
  11.         Type value;
  12.         Node* next_node = nullptr;
  13.     };
  14.  
  15. public:
  16.     SingleLinkedList() {}
  17.  
  18.     [[nodiscard]] size_t GetSize() const noexcept {
  19.         return size_;
  20.     }
  21.  
  22.     [[nodiscard]] bool IsEmpty() const noexcept {
  23.         if (!size_) {
  24.         return true;
  25.         }
  26.         return false;
  27.     }
  28.    
  29.     void PushFront(const Type& value) {
  30.         head_.next_node = new Node(value, head_.next_node);
  31.         ++size_;
  32.     }
  33.  
  34.     void Clear() noexcept {
  35.         while (head_.next_node) {
  36.             Node* new_head = head_.next_node->next_node;
  37.             delete head_.next_node;
  38.             head_.next_node = new_head;
  39.         }
  40.         size_ = 0;
  41.     }
  42.    
  43.     ~SingleLinkedList() {
  44.         Clear();
  45.     }
  46.  
  47. private:
  48.     Node head_;
  49.     size_t size_ = 0;
  50. };
  51.  
  52. void Test1() {
  53.     struct DeletionSpy {
  54.         DeletionSpy() = default;
  55.         explicit DeletionSpy(int& instance_counter) noexcept
  56.             : instance_counter_ptr_(&instance_counter)  
  57.         {
  58.             OnAddInstance();
  59.         }
  60.         DeletionSpy(const DeletionSpy& other) noexcept
  61.             : instance_counter_ptr_(other.instance_counter_ptr_)  
  62.         {
  63.             OnAddInstance();
  64.         }
  65.         DeletionSpy& operator=(const DeletionSpy& rhs) noexcept {
  66.             if (this != &rhs) {
  67.                 auto rhs_copy(rhs);
  68.                 std::swap(instance_counter_ptr_, rhs_copy.instance_counter_ptr_);
  69.             }
  70.             return *this;
  71.         }
  72.         ~DeletionSpy() {
  73.             OnDeleteInstance();
  74.         }
  75.  
  76.     private:
  77.         void OnAddInstance() noexcept {
  78.             if (instance_counter_ptr_) {
  79.                 ++(*instance_counter_ptr_);
  80.             }
  81.         }
  82.         void OnDeleteInstance() noexcept {
  83.             if (instance_counter_ptr_) {
  84.                 assert(*instance_counter_ptr_ != 0);
  85.                 --(*instance_counter_ptr_);
  86.             }
  87.         }
  88.  
  89.         int* instance_counter_ptr_ = nullptr;
  90.     };
  91.  
  92.     {
  93.         SingleLinkedList<int> l;
  94.         assert(l.IsEmpty());
  95.         assert(l.GetSize() == 0u);
  96.  
  97.         l.PushFront(0);
  98.         l.PushFront(1);
  99.         assert(l.GetSize() == 2);
  100.         assert(!l.IsEmpty());
  101.  
  102.         l.Clear();
  103.         assert(l.GetSize() == 0);
  104.         assert(l.IsEmpty());
  105.     }
  106.  
  107.     {
  108.         int item0_counter = 0;
  109.         int item1_counter = 0;
  110.         int item2_counter = 0;
  111.         {
  112.             SingleLinkedList<DeletionSpy> list;
  113.             list.PushFront(DeletionSpy{item0_counter});
  114.             list.PushFront(DeletionSpy{item1_counter});
  115.             list.PushFront(DeletionSpy{item2_counter});
  116.  
  117.             assert(item0_counter == 1);
  118.             assert(item1_counter == 1);
  119.             assert(item2_counter == 1);
  120.             list.Clear();
  121.             assert(item0_counter == 0);
  122.             assert(item1_counter == 0);
  123.             assert(item2_counter == 0);
  124.  
  125.             list.PushFront(DeletionSpy{item0_counter});
  126.             list.PushFront(DeletionSpy{item1_counter});
  127.             list.PushFront(DeletionSpy{item2_counter});
  128.             assert(item0_counter == 1);
  129.             assert(item1_counter == 1);
  130.             assert(item2_counter == 1);
  131.         }
  132.         assert(item0_counter == 0);
  133.         assert(item1_counter == 0);
  134.         assert(item2_counter == 0);
  135.     }
  136.  
  137.     struct ThrowOnCopy {
  138.         ThrowOnCopy() = default;
  139.         explicit ThrowOnCopy(int& copy_counter) noexcept
  140.             : countdown_ptr(&copy_counter) {
  141.         }
  142.         ThrowOnCopy(const ThrowOnCopy& other)
  143.             : countdown_ptr(other.countdown_ptr)  
  144.         {
  145.             if (countdown_ptr) {
  146.                 if (*countdown_ptr == 0) {
  147.                     throw std::bad_alloc();
  148.                 } else {
  149.                     --(*countdown_ptr);
  150.                 }
  151.             }
  152.         }
  153.         ThrowOnCopy& operator=(const ThrowOnCopy& rhs) = delete;
  154.         int* countdown_ptr = nullptr;
  155.     };
  156.  
  157.     {
  158.         bool exception_was_thrown = false;
  159.         for (int max_copy_counter = 5; max_copy_counter >= 0; --max_copy_counter) {
  160.             SingleLinkedList<ThrowOnCopy> list;
  161.             list.PushFront(ThrowOnCopy{});
  162.             try {
  163.                 int copy_counter = max_copy_counter;
  164.                 list.PushFront(ThrowOnCopy(copy_counter));
  165.                 assert(list.GetSize() == 2);
  166.             } catch (const std::bad_alloc&) {
  167.                 exception_was_thrown = true;
  168.                 assert(list.GetSize() == 1);
  169.                 break;
  170.             }
  171.         }
  172.         assert(exception_was_thrown);
  173.     }
  174. }
  175.  
  176. int main() {
  177.     Test1();
  178. }
Advertisement
Add Comment
Please, Sign In to add comment