avr39ripe

cppListFwOperatorPlus_operatorMult_clone

Aug 17th, 2021
626
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include <iostream>
  2.  
  3. template <typename ElemT>
  4. class ListFw
  5. {
  6.     class Node
  7.     {
  8.         ElemT data;
  9.         Node* next;
  10.     public:
  11.         Node(const ElemT& dataP, Node* nextP = nullptr) : data{ dataP }, next{ nextP }{}
  12.         friend ListFw;
  13.         template <typename ElemT>
  14.         friend std::ostream& operator<<(std::ostream& out, const ListFw<ElemT>& list);
  15.         template <typename ElemT>
  16.         friend ListFw<ElemT> operator+(const ListFw<ElemT>& lhs, const ListFw<ElemT>& rhs);
  17.         template <typename ElemT>
  18.         friend ListFw<ElemT> operator*(const ListFw<ElemT>& lhs, const ListFw<ElemT>& rhs);
  19.     };
  20.  
  21.     Node* head;
  22.     Node* tail;
  23.     size_t size;
  24.     Node* getNode(size_t idx);
  25. public:
  26.     ListFw() : head{ nullptr }, tail{ nullptr }, size{ 0 } {}
  27.     ListFw(const ListFw& listP) : head{ nullptr }, tail{ nullptr }, size{ 0 }
  28.     {
  29.         for (auto curr{ listP.head }; curr; curr = curr->next)
  30.         {
  31.             push_back(curr->data);
  32.         }
  33.         std::cout << "Copy-shmopy!\n";
  34.     };
  35.     ListFw(ListFw&& listP) : head{ listP.head }, tail{ listP.tail }, size{ listP.size }
  36.     {
  37.         listP.head = nullptr;
  38.         listP.tail = nullptr;
  39.         listP.size = 0;
  40.         std::cout << "I liket to mov'it, mov'it! :[]\n";
  41.     };
  42.     ListFw(const std::initializer_list<ElemT> initList) : head{ nullptr }, tail{ nullptr }, size{ 0 }
  43.     {
  44.         for (const auto& elem : initList)
  45.         {
  46.             push_back(elem);
  47.         }
  48.     };
  49.     bool empty()const { return size == 0; }
  50.     size_t get_size()const { return size; }
  51.     ElemT& front() { return head->data; }
  52.     const ElemT& front()const { return head->data; }
  53.     ElemT& back() { return tail->data; }
  54.     const ElemT& back()const { return tail->data; }
  55.     void push_front(const ElemT& data);
  56.     void push_back(const ElemT& data);
  57.     bool pop_front();
  58.     bool pop_back();
  59.  
  60.     void insert_at(size_t idx, const ElemT& data);
  61.     bool delete_at(size_t idx);
  62.  
  63.     void print()
  64.     {
  65.         if (!head) { std::cout << "[empty]"; }
  66.         else
  67.         {
  68.             for (auto curr{ head }; curr; curr = curr->next)
  69.             {
  70.                 std::cout << curr->data << ' ';
  71.             }
  72.         }
  73.         std::cout << '\n';
  74.     }
  75.  
  76.     void clear();
  77.     ~ListFw();
  78.     template <typename ElemT>
  79.     friend std::ostream& operator<<(std::ostream& out, const ListFw<ElemT>& list);
  80.  
  81.     template <typename ElemT>
  82.     friend ListFw<ElemT> operator+(const ListFw<ElemT>& lhs, const ListFw<ElemT>& rhs)
  83.     {
  84.         ListFw<ElemT> res;
  85.         for (auto curr{ lhs.head }; curr; curr = curr->next)
  86.         {
  87.             res.push_back(curr->data);
  88.         }
  89.         for (auto curr{ rhs.head }; curr; curr = curr->next)
  90.         {
  91.             res.push_back(curr->data);
  92.         }
  93.         return res;
  94.     };
  95.  
  96.     template <typename ElemT>
  97.     friend ListFw<ElemT> operator*(const ListFw<ElemT>& lhs, const ListFw<ElemT>& rhs)
  98.     {
  99.         ListFw<ElemT> res;
  100.         for (auto currL{ lhs.head }; currL; currL = currL->next)
  101.         {
  102.             for (auto currR{ rhs.head }; currR; currR = currR->next)
  103.             {
  104.                 if (currL->data == currR->data)
  105.                 {
  106.                     res.push_back(currL->data);
  107.                     break;
  108.                 }
  109.             }
  110.         }
  111.         return res;
  112.     };
  113. };
  114.  
  115. template <typename ElemT>
  116. std::ostream& operator<<(std::ostream& out, const ListFw<ElemT>& list)
  117. {
  118.     if (!list.head) { out << "[empty]"; }
  119.     else
  120.     {
  121.         for (auto curr{ list.head }; curr; curr = curr->next)
  122.         {
  123.             out << curr->data << ' ';
  124.         }
  125.     }
  126.     return out;
  127. }
  128.  
  129. template <typename ElemT>
  130. void ListFw<ElemT>::push_front(const ElemT& data)
  131. {
  132.     head = new Node{ data, head };
  133.  
  134.     if (!tail) { tail = head; }
  135.     ++size;
  136. }
  137.  
  138. template <typename ElemT>
  139. void ListFw<ElemT>::push_back(const ElemT& data)
  140. {
  141.     if (!head)
  142.     {
  143.         head = new Node{ data, head };
  144.         tail = head;
  145.     }
  146.     else
  147.     {
  148.         tail->next = new Node{ data, nullptr };
  149.         tail = tail->next;
  150.     }
  151.     ++size;
  152. }
  153.  
  154. template <typename ElemT>
  155. bool ListFw<ElemT>::pop_front()
  156. {
  157.     if (head)
  158.     {
  159.         Node* oldHead{ head };
  160.         head = head->next;
  161.         delete oldHead;
  162.         --size;
  163.         if (!size) { tail = nullptr; }
  164.         return true;
  165.     }
  166.     return false;
  167. }
  168.  
  169. template <typename ElemT>
  170. bool ListFw<ElemT>::pop_back()
  171. {
  172.     if (tail)
  173.     {
  174.         if (tail == head)
  175.         {
  176.             delete tail;
  177.             head = nullptr;
  178.             tail = nullptr;
  179.             size = 0;
  180.             return true;
  181.         }
  182.  
  183.         Node* curr{ head };
  184.         for (; !(curr->next == tail); curr = curr->next);
  185.  
  186.         delete tail;
  187.         curr->next = nullptr;
  188.         tail = curr;
  189.         --size;
  190.         return true;
  191.     }
  192.     return false;
  193. }
  194.  
  195. template <typename ElemT>
  196. void ListFw<ElemT>::clear()
  197. {
  198.     while (head)
  199.     {
  200.         std::cout << "Clear for: " << front() << '\n';
  201.         pop_front();
  202.     }
  203. }
  204.  
  205. template <typename ElemT>
  206. ListFw<ElemT>::~ListFw()
  207. {
  208.     while (tail)
  209.     {
  210.         //std::cout << "Destruct for: " << back() << '\n';
  211.         pop_back();
  212.     }
  213. }
  214.  
  215. template <typename ElemT>
  216. void printListState(const ListFw<ElemT>& l)
  217. {
  218.     std::cout << "Size: " << l.get_size() << '\n';
  219.     std::cout << "Front: " << l.front() << '\n';
  220.     std::cout << "Back: " << l.back() << '\n';
  221. }
  222.  
  223. template <typename ElemT>
  224. typename ListFw<ElemT>::Node* ListFw<ElemT>::getNode(size_t idx)
  225. {
  226.     Node* curr{ nullptr };
  227.     size_t currIdx;
  228.  
  229.     if (idx >= 0 and idx < size)
  230.     {
  231.         for (curr = head, currIdx = 0; currIdx < idx; curr = curr->next, ++currIdx);
  232.     }
  233.     return curr;
  234. }
  235.  
  236. template <typename ElemT>
  237. void ListFw<ElemT>::insert_at(size_t idx, const ElemT& data)
  238. {
  239.     Node* prev{ getNode(idx - 1) };
  240.     Node* curr{ prev ? prev->next : nullptr };
  241.  
  242.     if (!curr or curr == head) { push_front(data); return; }
  243.     else
  244.     {
  245.         prev->next = new Node{ data, curr };
  246.     }
  247.     ++size;
  248. }
  249.  
  250. template <typename ElemT>
  251. bool ListFw<ElemT>::delete_at(size_t idx)
  252. {
  253.     if (idx == 0) { pop_front(); return true; }
  254.     Node* prev{ getNode(idx - 1) };
  255.     Node* curr{ prev ? prev->next : nullptr };
  256.  
  257.     if (curr)
  258.     {
  259.         if (curr == head) { head = curr->next; }
  260.         else
  261.         {
  262.             if (curr->next) { prev->next = curr->next; }
  263.             else { tail = prev; prev->next = nullptr; }
  264.         }
  265.         --size;
  266.         delete curr;
  267.         return true;
  268.     }
  269.     return false;
  270. }
  271.  
  272. int main()
  273. {
  274.     ListFw<int> a;
  275.     a.push_back(1);
  276.     a.push_back(2);
  277.     a.push_back(3);
  278.     a.push_back(4);
  279.     std::cout << "a -> " << a << '\n';
  280.  
  281.     ListFw<int> b{ a };
  282.     std::cout << "b -> " << b << '\n';
  283.  
  284.     ListFw<int> c;
  285.     c.push_back(5);
  286.     c.push_back(6);
  287.     c.push_back(7);
  288.     c.push_back(8);
  289.     std::cout << "c -> " << c << '\n';
  290.  
  291.     ListFw<int> d{ b + c };
  292.     std::cout << "d -> " << d << '\n';
  293.  
  294.     ListFw<int> e{ 1,3,5,7,3,5,7,1 };
  295.     ListFw<int> f{ 2,1,4,6,7,1,6,7 };
  296.     std::cout << "e -> " << e << '\n';
  297.     std::cout << "f -> " << f << '\n';
  298.  
  299.     ListFw<int> g{ e * f };
  300.     std::cout << "g -> " << g << '\n';
  301.  
  302.     return 0;
  303. }
RAW Paste Data