shizaero

Untitled

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