Advertisement
KShah

Untitled

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