shizaero

Untitled

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