shizaero

Untitled

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