shizaero

Untitled

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