AlexSSH

Untitled

Jan 27th, 2023
91
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 9.45 KB | None | 0 0
  1. #pragma once
  2.  
  3. #include <bits/stdc++.h>
  4. #include "array_ptr.h"
  5.  
  6. template<typename Type>
  7. class SimpleVector {
  8. public:
  9.     using Iterator = ArrayPtr<Type>;
  10.     using ConstIterator = const ArrayPtr<Type>;
  11.  
  12.     SimpleVector(const SimpleVector &other) {
  13.         SimpleVector tmp;
  14.         if (!other.IsEmpty()) {
  15.             tmp.size_ = other.size_;
  16.             tmp.capacity_ = other.capacity_;
  17.             tmp.data = other.data;
  18.         }
  19.         swap(tmp);
  20.     }
  21.  
  22.     SimpleVector &operator=(const SimpleVector &rhs) {
  23.         if (this != &rhs) {
  24.             auto rhs_copy(rhs);
  25.             swap(rhs_copy);
  26.         }
  27.         return *this;
  28.     }
  29.  
  30.     SimpleVector() noexcept = default;
  31.  
  32.     // Создаёт вектор из size элементов, инициализированных значением по умолчанию
  33.     explicit SimpleVector(size_t size) {
  34.         if (size > 0) {
  35.             size_ = size;
  36.             capacity_ = CountCapacity(size);
  37.             data = Iterator(capacity_);
  38.             std::fill(data, data + size_, Type());
  39.         }
  40.     }
  41.  
  42.     // Создаёт вектор из size элементов, инициализированных значением value
  43.     SimpleVector(size_t size, const Type &value) {
  44.         if (size > 0) {
  45.             size_ = size;
  46.             capacity_ = CountCapacity(size);
  47.             data = Iterator(capacity_);
  48.             std::fill(data, data + size_, value);
  49.         }
  50.     }
  51.  
  52.     // Создаёт вектор из std::initializer_list
  53.     SimpleVector(std::initializer_list<Type> init) {
  54.         size_ = init.size();
  55.         capacity_ = CountCapacity(size_);
  56.         data = Iterator(capacity_);
  57.         std::copy(init.begin(), init.end(), data);
  58.     }
  59.  
  60.     // Возвращает количество элементов в массиве
  61.     size_t GetSize() const noexcept {
  62.         return size_;
  63.     }
  64.  
  65.     // Возвращает вместимость массива
  66.     size_t GetCapacity() const noexcept {
  67.         return capacity_;
  68.     }
  69.  
  70.     // Сообщает, пустой ли массив
  71.     bool IsEmpty() const noexcept {
  72.         return size_ == 0;
  73.     }
  74.  
  75.     // Возвращает ссылку на элемент с индексом index
  76.     Type &operator[](size_t index) noexcept {
  77.         return data[index];
  78.     }
  79.  
  80.     // Возвращает константную ссылку на элемент с индексом index
  81.     const Type &operator[](size_t index) const noexcept {
  82.         return data[index];
  83.     }
  84.  
  85.     // Возвращает константную ссылку на элемент с индексом index
  86.     // Выбрасывает исключение std::out_of_range, если index >= size
  87.     Type &At(size_t index) {
  88.         if (index >= size_) throw std::out_of_range("");
  89.         return data[index];
  90.     }
  91.  
  92.     // Возвращает константную ссылку на элемент с индексом index
  93.     // Выбрасывает исключение std::out_of_range, если index >= size
  94.     const Type &At(size_t index) const {
  95.         if (index >= size_) throw std::out_of_range("");
  96.         return data[index];
  97.     }
  98.  
  99.     // Обнуляет размер массива, не изменяя его вместимость
  100.     void Clear() noexcept {
  101.         size_ = 0;
  102.     }
  103.  
  104.     // Изменяет размер массива.
  105.     // При увеличении размера новые элементы получают значение по умолчанию для типа Type
  106.     void Resize(size_t new_size) {
  107.         if (new_size <= size_) {
  108.             size_ = new_size;
  109.         } else if (new_size <= capacity_) {
  110.             std::fill(data + size_, data + capacity_, Type());
  111.         } else {
  112.             //while (new_size > capacity_) capacity_ *= 2;
  113.             capacity_ = new_size;
  114.             auto tmp = Iterator(capacity_);
  115.             std::fill(tmp, tmp + capacity_, Type());
  116.             std::copy(data, data + size_, tmp);
  117.             size_ = new_size;
  118.             delete[] data;
  119.             data = tmp;
  120.         }
  121.     }
  122.  
  123.     // Добавляет элемент в конец вектора
  124.     // При нехватке места увеличивает вдвое вместимость вектора
  125.     void PushBack(const Type &item) {
  126.         if (size_ < capacity_) {
  127.             *(data + size_++) = item;
  128.         } else {
  129.             capacity_ *= 2;
  130.             ArrayPtr<Type> tmp(capacity_);
  131.             std::copy(data, data + size_, tmp.Get());
  132.             tmp[size_++] = item;
  133.             delete[] data;
  134.             data = tmp.Release();
  135.         }
  136.     }
  137.  
  138.     // Вставляет значение value в позицию pos.
  139.     // Возвращает итератор на вставленное значение
  140.     // Если перед вставкой значения вектор был заполнен полностью,
  141.     // вместимость вектора должна увеличиться вдвое, а для вектора вместимостью 0 стать равной 1
  142.     Iterator Insert(Iterator pos, const Type &value) {
  143.         if (size_ < capacity_) {
  144.             std::copy_backward(Iterator(pos), data + size_++, pos+1); //TODO check res
  145.             *pos = value;
  146.         } else {
  147.             capacity_ *= 2;
  148.             ArrayPtr<Type> tmp(capacity_);
  149.             std::copy(data, pos, tmp.Get());
  150.             *pos = value; //todo
  151.             std::copy(pos, data + size_++, tmp.Get());
  152.             delete[] data;
  153.             data = tmp.Release();
  154.         }
  155.         return Iterator(&value);
  156.     }
  157.  
  158.     // "Удаляет" последний элемент вектора. Вектор не должен быть пустым
  159.     void PopBack() noexcept {
  160.         if (!IsEmpty()) --size_;
  161.     }
  162.  
  163.     // Удаляет элемент вектора в указанной позиции
  164.     Iterator Erase(ConstIterator pos) {
  165.         std::copy_backward(Iterator(pos + 1), data + size_, Iterator(pos)); //TODO check res
  166.         --size_;
  167.         return Iterator(pos - 1);
  168.     }
  169.  
  170.     // Обменивает значение с другим вектором
  171.     void swap(SimpleVector &other) noexcept {
  172.         std::swap(size_, other.size_);
  173.         std::swap(capacity_, other.capacity_);
  174.         std::swap(data, other.data);
  175.     }
  176.  
  177.     // Возвращает итератор на начало массива
  178.     // Для пустого массива может быть равен (или не равен) nullptr
  179.     Iterator begin() noexcept {
  180.         return data;
  181.     }
  182.  
  183.     // Возвращает итератор на элемент, следующий за последним
  184.     // Для пустого массива может быть равен (или не равен) nullptr
  185.     Iterator end() noexcept {
  186.         return data + size_;
  187.     }
  188.  
  189.     // Возвращает константный итератор на начало массива
  190.     // Для пустого массива может быть равен (или не равен) nullptr
  191.     ConstIterator begin() const noexcept {
  192.         return data;
  193.     }
  194.  
  195.     // Возвращает итератор на элемент, следующий за последним
  196.     // Для пустого массива может быть равен (или не равен) nullptr
  197.     ConstIterator end() const noexcept {
  198.         return data + size_;
  199.     }
  200.  
  201.     // Возвращает константный итератор на начало массива
  202.     // Для пустого массива может быть равен (или не равен) nullptr
  203.     ConstIterator cbegin() const noexcept {
  204.         return data;
  205.     }
  206.  
  207.     // Возвращает итератор на элемент, следующий за последним
  208.     // Для пустого массива может быть равен (или не равен) nullptr
  209.     ConstIterator cend() const noexcept {
  210.         return data + size_;
  211.     }
  212.  
  213.     size_t CountCapacity(size_t size) {
  214.         //capacity_ = 1;
  215.         //while (capacity_ < size) {
  216.         //    capacity_ *= 2;
  217.         //}
  218.         //return capacity_;
  219.         return size;
  220.     }
  221.  
  222. private:
  223.     Iterator data;
  224.     size_t size_ = 0;
  225.     size_t capacity_ = 0;
  226. };
  227.  
  228. template<typename Type>
  229. inline bool operator==(const SimpleVector<Type> &lhs, const SimpleVector<Type> &rhs) {
  230.     return lhs.GetSize() == rhs.GetSize() && std::equal(lhs.begin(), lhs.end(), rhs.begin());
  231. }
  232.  
  233. template<typename Type>
  234. inline bool operator!=(const SimpleVector<Type> &lhs, const SimpleVector<Type> &rhs) {
  235.     return !(operator==(lhs, rhs));
  236. }
  237.  
  238. template<typename Type>
  239. inline bool operator<(const SimpleVector<Type> &lhs, const SimpleVector<Type> &rhs) {
  240.     return std::lexicographical_compare(lhs.begin(), lhs.end(),
  241.                                         rhs.begin(), rhs.end());
  242. }
  243.  
  244. template<typename Type>
  245. inline bool operator<=(const SimpleVector<Type> &lhs, const SimpleVector<Type> &rhs) {
  246.     return (operator==(lhs, rhs)) || (operator<(lhs, rhs));
  247. }
  248.  
  249. template<typename Type>
  250. inline bool operator>(const SimpleVector<Type> &lhs, const SimpleVector<Type> &rhs) {
  251.     return !(operator<=(lhs, rhs));
  252. }
  253.  
  254. template<typename Type>
  255. inline bool operator>=(const SimpleVector<Type> &lhs, const SimpleVector<Type> &rhs) {
  256.     return (operator==(lhs, rhs)) || (operator>(lhs, rhs));
  257. }
Advertisement
Add Comment
Please, Sign In to add comment