Advertisement
KShah

Untitled

Mar 19th, 2022
819
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 8.70 KB | None | 0 0
  1. #include <iostream>
  2. #include <iterator>
  3. #include <vector>
  4.  
  5. template<typename T>
  6. class Deque {
  7.  private:
  8.   std::vector<T*> array_;
  9.   size_t size_ = 0;
  10.   size_t array_size_ = 0;
  11.   size_t head_block_ind_ = 0;
  12.   size_t head_buf_ind_ = 0;
  13.  
  14.   const static size_t block_size = 8;
  15.  
  16.   void resize(size_t new_array_size) {
  17.     if (new_array_size < array_size_) {
  18.       return;
  19.     }
  20.     std::vector<T*> temp_array;
  21.  
  22.     size_t new_head_buf_ind = (new_array_size - array_size_) / 2;
  23.     for (size_t i = 0; i < new_head_buf_ind; ++i) {
  24.       temp_array.push_back(reinterpret_cast<T*>(new char[block_size * sizeof(T)]));
  25.     }
  26.     for (size_t i = 0; i < array_size_; ++i) {
  27.       temp_array.push_back(array_[i]);
  28.     }
  29.     for (size_t i = new_head_buf_ind + array_size_; i < new_array_size; ++i) {
  30.       temp_array.push_back(reinterpret_cast<T*>(new char[block_size * sizeof(T)]));
  31.     }
  32.  
  33.     array_ = temp_array;
  34.     array_size_ = new_array_size;
  35.     head_block_ind_ = (head_block_ind_ + new_head_buf_ind * block_size) % block_size;
  36.     head_buf_ind_ = new_head_buf_ind;
  37.   }
  38.  public:
  39.   Deque() {
  40.     resize(1);
  41.   }
  42.  
  43.   explicit Deque(size_t size) {
  44.     resize(size / block_size + 1);
  45.     for (size_t i = 0; i < size; ++i) {
  46.       push_back(T());
  47.     }
  48.   }
  49.  
  50.   Deque(size_t size, const T& value) {
  51.     resize(1);
  52.     for (size_t i = 0; i < size; ++i) {
  53.       push_back(value);
  54.     }
  55.   }
  56.   Deque(const Deque& other) {
  57.     try {
  58.       resize(1);
  59.       for (size_t i = 0; i < other.size_; ++i) {
  60.         push_back(other[i]);
  61.       }
  62.     } catch (...) {
  63.       throw;
  64.     }
  65.   }
  66.  
  67.   Deque& operator=(const Deque& other) {
  68.     array_ = other.array_;
  69.     size_ = other.size_;
  70.     array_size_ = other.array_size_;
  71.     head_block_ind_ = other.head_block_ind_;
  72.     head_buf_ind_ = other.head_buf_ind_;
  73.  
  74.     return *this;
  75.   }
  76.  
  77.   size_t size()  const {
  78.     return size_;
  79.   }
  80.  
  81.   T& operator[](size_t index) {
  82.     return array_[head_buf_ind_ + (head_block_ind_ + index) / block_size][(head_block_ind_ + index) % block_size];
  83.   }
  84.   const T& operator[](size_t index) const {
  85.     return array_[head_buf_ind_ + (head_block_ind_ + index) / block_size][(head_block_ind_ + index) % block_size];
  86.   }
  87.   T& at(size_t index) {
  88.     if (index >= size_) {
  89.       throw std::out_of_range("AtError: Index is out of range!");
  90.     }
  91.     return array_[head_buf_ind_ + (head_block_ind_ + index) / block_size][(head_block_ind_ + index) % block_size];
  92.   }
  93.   const T& at(size_t index) const {
  94.     if (index >= size_) {
  95.       throw std::out_of_range("AtError: Index is out of range!");
  96.     }
  97.     return array_[head_buf_ind_ + (head_block_ind_ + index) / block_size][(head_block_ind_ + index) % block_size];
  98.   }
  99.  
  100.   void push_back(T value) {
  101.     if (head_buf_ind_ + (head_block_ind_ + size_) / block_size == array_size_) {
  102.       resize(3 * array_size_);
  103.     }
  104.     try {
  105.       new(array_[head_buf_ind_ + (head_block_ind_ + size_) / block_size] + (head_block_ind_ + size_) % block_size) T(value);
  106.       ++size_;
  107.     } catch (...) {
  108.       throw;
  109.     }
  110.   }
  111.  
  112.   void push_front(T value) {
  113.     if (head_block_ind_ == 0 && head_buf_ind_ == 0) {
  114.       resize(3 * array_size_);
  115.     }
  116.     try {
  117.       new(array_[head_block_ind_ == 0 ? head_buf_ind_ - 1 : head_buf_ind_] + (head_block_ind_ - 1 + block_size) % block_size) T(value);
  118.       ++size_;
  119.       if (!head_block_ind_) {
  120.         --head_buf_ind_;
  121.       }
  122.       head_block_ind_ = (head_block_ind_ - 1 + block_size) % block_size;
  123.     } catch (...) {
  124.       throw;
  125.     }
  126.   }
  127.  
  128.   void pop_back() {
  129.     size_t tail_buf_ind = head_buf_ind_ + (head_block_ind_ + size_) / block_size;
  130.     size_t tail_block_ind = (head_block_ind_ + size_) % block_size;
  131.     (array_[tail_buf_ind] + tail_block_ind)->~T();
  132.     --size_;
  133.   }
  134.  
  135.   void pop_front() {
  136.     (array_[head_buf_ind_] + head_block_ind_)->~T();
  137.     head_buf_ind_ += (head_block_ind_ + 1) / block_size;
  138.     head_block_ind_ = (head_block_ind_ + 1) % block_size;
  139.     --size_;
  140.   }
  141.  
  142.   template<bool is_const>
  143.   class Iterator {
  144.    private:
  145.     friend class Deque;
  146.  
  147.     size_t cur_buff_index;
  148.     size_t cur_block_index;
  149.     std::conditional_t<is_const, const T*, T*> ptr;
  150.  
  151.     const std::vector<T *> *vector_ptr;
  152.    public:
  153.     Iterator(std::conditional_t<is_const, const Deque&, Deque&> deque_, size_t index) {
  154.       cur_block_index = (deque_.head_block_ind_ + index) % block_size;
  155.       cur_buff_index = deque_.head_buf_ind_ + (deque_.head_block_ind_ + index) / block_size;
  156.       ptr = deque_.array_[cur_buff_index] + cur_block_index;
  157.       vector_ptr = &deque_.array_;
  158.     }
  159.  
  160.     Iterator& operator++() {
  161.       ++cur_block_index;
  162.       if (cur_block_index == block_size) {
  163.         ++cur_buff_index;
  164.         ptr = (*vector_ptr)[cur_buff_index];
  165.         cur_block_index = 0;
  166.       } else {
  167.         ++ptr;
  168.       }
  169.  
  170.       return *this;
  171.     }
  172.  
  173.     Iterator operator++(int) {
  174.       Iterator copy = *this;
  175.       ++*this;
  176.       return copy;
  177.     }
  178.  
  179.     Iterator& operator--() {
  180.       if (cur_block_index == 0u) {
  181.         --cur_buff_index;
  182.         ptr = (*vector_ptr)[cur_buff_index] + block_size - 1;
  183.         cur_block_index = block_size - 1;
  184.       } else {
  185.         --cur_block_index;
  186.         --ptr;
  187.       }
  188.  
  189.       return *this;
  190.     }
  191.  
  192.     Iterator operator--(int) {
  193.       Iterator copy = *this;
  194.       --*this;
  195.       return copy;
  196.     }
  197.  
  198.     Iterator& operator+=(int n) {
  199.       size_t all_index = block_size * cur_buff_index + cur_block_index + n;
  200.  
  201.       cur_buff_index = all_index / block_size;
  202.       cur_block_index = all_index % block_size;
  203.       ptr = (*vector_ptr)[cur_buff_index] + cur_block_index;
  204.       return *this;
  205.     }
  206.  
  207.     Iterator operator+(int x) {
  208.       Iterator result = *this;
  209.       result += x;
  210.       return result;
  211.     }
  212.  
  213.     Iterator& operator-=(int n) {
  214.       size_t all_index = block_size * cur_buff_index + cur_block_index - n;
  215.  
  216.       cur_buff_index = all_index / block_size;
  217.       cur_block_index = all_index % block_size;
  218.       ptr = (*vector_ptr)[cur_buff_index] + cur_block_index;
  219.       return *this;
  220.     }
  221.  
  222.     Iterator operator-(int x) {
  223.       Iterator result = *this;
  224.       result -= x;
  225.       return result;
  226.     }
  227.  
  228.     int operator-(const Iterator &other) const {
  229.       size_t all_index = cur_buff_index * block_size + cur_block_index;
  230.       size_t other_all_index = other.cur_buff_index * block_size + other.cur_block_index;
  231.       return all_index - other_all_index;
  232.     }
  233.  
  234.     bool operator==(const Iterator& other) const {
  235.       return ptr == other.ptr;
  236.     }
  237.     bool operator!=(const Iterator& other) const {
  238.       return ptr != other.ptr;
  239.     }
  240.     bool operator<(const Iterator& other) const {
  241.       return cur_buff_index < other.cur_buff_index || (cur_buff_index == other.cur_buff_index && cur_block_index < other.cur_block_index);
  242.     }
  243.     bool operator>(const Iterator& other) const {
  244.       return other < *this;
  245.     }
  246.     bool operator<=(const Iterator& other) const {
  247.       return *this == other || *this < other;
  248.     }
  249.     bool operator>=(const Iterator& other) const {
  250.       return *this == other || *this > other;
  251.     }
  252.  
  253.     std::conditional_t<is_const, const T &, T &> operator*() const {
  254.       return *ptr;
  255.     }
  256.  
  257.     std::conditional_t<is_const, const T *, T *> operator->() const {
  258.       return ptr;
  259.     }
  260.   };
  261.  
  262.   using const_iterator = Iterator<true>;
  263.   using iterator = Iterator<false>;
  264.   using reverse_iterator = std::reverse_iterator<iterator>;
  265.   using const_reverse_iterator = std::reverse_iterator<const_iterator>;
  266.  
  267.   iterator begin() {
  268.     return iterator(*this, 0);
  269.   }
  270.   const_iterator begin() const {
  271.     return const_iterator(*this, 0);
  272.   }
  273.   const_iterator cbegin() const {
  274.     return const_iterator(*this, 0);
  275.   }
  276.  
  277.   iterator end() {
  278.     return iterator(*this, size_);
  279.   }
  280.   const_iterator end() const {
  281.     return const_iterator(*this, size_);
  282.   }
  283.   const_iterator cend() const {
  284.     return const_iterator(*this, size_);
  285.   }
  286.  
  287.   reverse_iterator rbegin() {
  288.     return std::make_reverse_iterator(end());
  289.   }
  290.   const_reverse_iterator crbegin() const {
  291.     return std::make_reverse_iterator(cend());
  292.   }
  293.  
  294.   reverse_iterator rend() {
  295.     return std::make_reverse_iterator(begin());
  296.   }
  297.   const_reverse_iterator crend() const {
  298.     return std::make_reverse_iterator(cbegin());
  299.   }
  300.  
  301.   void insert(iterator it, const T &value) {
  302.     push_back(value);
  303.     iterator it_ = end();
  304.     --it_;
  305.     iterator prev_it = it_;
  306.     --prev_it;
  307.     for (; it_ > it; --it_, --prev_it) {
  308.       std::swap(*it_, *(prev_it));
  309.     }
  310.   }
  311.  
  312.   void erase(iterator it) {
  313.     iterator it_ = it;
  314.     iterator next_it = it_;
  315.     ++next_it;
  316.     for (; it_ < end(); ++it_, ++next_it) {
  317.       std::swap(*it_, *(next_it));
  318.     }
  319.     pop_back();
  320.   }
  321. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement