Seredenko-V

Untitled

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