Advertisement
Guest User

Untitled

a guest
Dec 16th, 2019
106
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.76 KB | None | 0 0
  1. #ifndef CONTAINERS_HPP_
  2. #define CONTAINERS_HPP_
  3.  
  4. #include <functional>
  5. #include <fstream>
  6.  
  7. namespace containers
  8. {
  9.  
  10. template <typename T>
  11. struct Node
  12. {
  13.     Node<T> *next;
  14.     T value;
  15.  
  16.     explicit Node(T v, Node<T> *n) : next{n}, value{v} {}
  17. };
  18.  
  19. template <typename T>
  20. class Container
  21. {
  22. protected:
  23.     Node<T> *head;
  24.     Node<T> *tail;
  25.  
  26. public:
  27.     Container() : head{nullptr}, tail{nullptr} {}
  28.  
  29.     virtual void push(T i) = 0;
  30.  
  31.     virtual ~Container()
  32.     {
  33.         auto tmp = head;
  34.         while (tmp) {
  35.             auto next = tmp->next;
  36.             delete tmp;
  37.             tmp = next;
  38.         }
  39.     }
  40.  
  41.     bool empty() const
  42.     {
  43.         return head == nullptr;
  44.     }
  45.  
  46.     template <typename T_ = T,
  47.         typename std::enable_if<std::is_arithmetic<T_>::value, T_>::type* = nullptr>
  48.     void load(std::string filepath)
  49.     {
  50.         std::string s;
  51.         std::ifstream f;
  52.         f.open(filepath);
  53.         while (std::getline(f, s))
  54.             push(std::stoi(s));
  55.     }
  56.  
  57.     template <typename T_ = T,
  58.         typename std::enable_if<std::is_same<T_, std::string>::value, T_>::type* = nullptr>
  59.     void load(std::string filepath)
  60.     {
  61.         std::string s;
  62.         std::ifstream f;
  63.         f.open(filepath);
  64.         while (std::getline(f, s))
  65.             push(s);
  66.     }
  67.  
  68.     template <typename T_ = T,
  69.         typename std::enable_if<!std::is_arithmetic<T_>::value, T_>::type*        = nullptr,
  70.         typename std::enable_if<!std::is_same<T_, std::string>::value, T_>::type* = nullptr>
  71.     void load(std::string filepath, std::function<T(const std::string&)> callback)
  72.     {
  73.         std::string s;
  74.         std::ifstream f;
  75.         f.open(filepath);
  76.         while (std::getline(f, s))
  77.             push(callback(s));
  78.     }
  79.  
  80.     void save(std::string filepath) const
  81.     {
  82.         std::ifstream f;
  83.         f.open(filepath);
  84.         map([&f](const T& i) { f << i << '\n'; });
  85.         f.close();
  86.     }
  87.  
  88.     void save(std::string filepath, std::function<T(const std::string&)> callback) const
  89.     {
  90.         std::ifstream f;
  91.         f.open(filepath);
  92.         map([&f, &callback](const T& i) { f << callback(i) << '\n'; });
  93.         f.close();
  94.     }
  95.  
  96.     void map(std::function<void(T)> f) const
  97.     {
  98.         for(auto i = head; i; i = i->next)
  99.             f(i->value);
  100.     }
  101.  
  102.     void map(std::function<void(T&)> f)
  103.     {
  104.         for(auto i = head; i; i = i->next)
  105.             f(i->value);
  106.     }
  107.  
  108.     void map(std::function<void(const T&)> f) const
  109.     {
  110.         for(auto i = head; i; i = i->next)
  111.             f(i->value);
  112.     }
  113.  
  114. };
  115.  
  116. template <typename T>
  117. class Stack : public Container<T>
  118. {
  119.     using Container<T>::head;
  120.  
  121.     void deepcopy(Node<T> *n)
  122.     {
  123.         if(n) {
  124.             deepcopy(n->next);
  125.             push(n->value);
  126.         }
  127.     }
  128.  
  129. public:
  130.     Stack() : Container<T>{} {}
  131.  
  132.     template <typename ... Args>
  133.     Stack(Args ... args) : Container<T>{}
  134.     {
  135.         push(args...);
  136.     }
  137.  
  138.     Stack(const Stack &other) : Container<T>{}
  139.     {
  140.         deepcopy(other.head);
  141.     }
  142.  
  143.     Stack& operator=(const Stack &other) = default;
  144.  
  145.     template <typename ... Args>
  146.     void push(T i, Args ... args)
  147.     {
  148.         push(i);
  149.         push(args...);
  150.     }
  151.  
  152.     void push(T i)
  153.     {
  154.         head = new Node<T>{i, head};
  155.     }
  156.  
  157.     T pop()
  158.     {
  159.         if(this->empty()) return T{};
  160.         auto tmp = head;
  161.         auto v = tmp->value;
  162.         head = head->next;
  163.         delete tmp;
  164.         return v;
  165.     }
  166.  
  167. };
  168.  
  169. template <typename T>
  170. class Queue : public Container<T>
  171. {
  172.     using Container<T>::head;
  173.     using Container<T>::tail;
  174.  
  175.     void deepcopy(Node<T> *n)
  176.     {
  177.         if(n) {
  178.             push(n->value);
  179.             deepcopy(n->next);
  180.         }
  181.     }
  182.  
  183. public:
  184.     Queue() : Container<T>{} {}
  185.  
  186.     template <typename ... Args>
  187.     Queue(Args ... args) : Container<T>{}
  188.     {
  189.         push(args...);
  190.     }
  191.  
  192.     Queue(const Queue &other) : Container<T>{}
  193.     {
  194.         deepcopy(other.head);
  195.     }
  196.  
  197.     Queue& operator=(const Queue &other) = default;
  198.  
  199.     template <typename ... Args>
  200.     void push(T i, Args ... args)
  201.     {
  202.         push(i);
  203.         push(args...);
  204.     }
  205.  
  206.     void push(T i)
  207.     {
  208.         if (this->empty()) {
  209.             auto tmp = new Node<T>{i, head};
  210.             head = tail = tmp;
  211.         } else {
  212.             auto tmp = new Node<T>{i, nullptr};
  213.             tail->next = tmp;
  214.             tail = tmp;
  215.         }
  216.     }
  217.  
  218.     T pop()
  219.     {
  220.         if(this->empty()) return T{};
  221.         auto tmp = head;
  222.         auto v = tmp->value;
  223.         head = head->next;
  224.         if (this->empty())
  225.             tail = nullptr;
  226.         delete tmp;
  227.         return v;
  228.     }
  229.  
  230. };
  231.  
  232. template <typename T>
  233. class List : public Container<T>
  234. {
  235.     using Container<T>::head;
  236.  
  237.     static const std::function<bool(const T&, const T&)> create_compare()
  238.     {
  239.         static auto c = [](const T &lhs, const T &rhs) -> bool { return lhs > rhs; };
  240.         return c;
  241.     }
  242.  
  243.     const std::function<bool(const T&, const T&)> compare = create_compare();
  244.  
  245.     void deepcopy(Node<T> *n)
  246.     {
  247.         if(n) {
  248.             push(n->value);
  249.             deepcopy(n->next);
  250.         }
  251.     }
  252.  
  253. public:
  254.     List() : Container<T>{} {}
  255.  
  256.     List(std::function<bool(const T&, const T&)> compare_) : Container<T>{} , compare{compare_} {}
  257.  
  258.     template <typename ... Args>
  259.     List(T i, Args ... args) : Container<T>{}
  260.     {
  261.         push(i);
  262.         push(args...);
  263.     }
  264.  
  265.     List(const List &other) : Container<T>{}
  266.     {
  267.         deepcopy(other.head);
  268.     }
  269.  
  270.     List& operator=(const List &other) = default;
  271.  
  272.     template <typename ... Args>
  273.     void push(T i, Args ... args)
  274.     {
  275.         push(i);
  276.         push(args...);
  277.     }
  278.  
  279.     void push(T i)
  280.     {
  281.         if (this->empty() || !compare(i, head->value)) {
  282.             head = new Node<T>{i, head};
  283.         } else {
  284.             Node<T> *cur = head;
  285.             while (cur->next && compare(i, cur->next->value)) cur = cur->next;
  286.             cur->next = new Node<T>{i, cur->next};
  287.         }
  288.     }
  289.  
  290.     T pop()
  291.     {
  292.         return pop(1);
  293.     }
  294.  
  295.     T pop(int pos)
  296.     {
  297.         if (this->empty()) return T{};
  298.         if (pos == 1) {
  299.             auto tmp = head;
  300.             auto v = head->value;
  301.             head = head->next;
  302.             delete tmp;
  303.             return v;
  304.         } else {
  305.             auto cur = head;
  306.             for (int i = 2; i < pos && cur->next; ++i, cur = cur->next);
  307.             if (!cur->next) return T{};
  308.             auto tmp = cur->next;
  309.             auto v = cur->next->value;
  310.             cur->next = cur->next->next;
  311.             delete tmp;
  312.             return v;
  313.         }
  314.     }
  315.  
  316.     void erase(int v)
  317.     {
  318.         int index = 1;
  319.         for (auto i = head; i; i = i->next, ++index)
  320.             if (i->value == v)
  321.                 pop(index);
  322.     }
  323.  
  324. };
  325.  
  326. } // namespace containers
  327.  
  328. #endif /* CONTAINERS_HPP_ */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement