Seredenko-V

Untitled

Jul 25th, 2022 (edited)
248
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 16.11 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_ = std::move(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.     size_t GetSize() const noexcept {
  92.         return size_;
  93.     }
  94.  
  95.     // Возвращает вместимость массива
  96.     size_t GetCapacity() const noexcept {
  97.         return capacity_;
  98.     }
  99.  
  100.     // Сообщает, пустой ли массив
  101.     bool IsEmpty() const noexcept {
  102.         return size_ == 0;
  103.     }
  104.  
  105.     // Возвращает ссылку на элемент с индексом index
  106.     Type& operator[](size_t index) noexcept {
  107.         return simple_vector_[index];
  108.     }
  109.  
  110.     // Возвращает константную ссылку на элемент с индексом index
  111.     const Type& operator[](size_t index) const noexcept {
  112.         return simple_vector_[index];
  113.     }
  114.  
  115.     // Возвращает константную ссылку на элемент с индексом index
  116.     // Выбрасывает исключение std::out_of_range, если index >= size
  117.     Type& At(size_t index) {
  118.         if (index >= size_) {
  119.             throw std::out_of_range("Попытка обращения к элементу за пределами вектора.");
  120.         }
  121.         return simple_vector_[index];
  122.     }
  123.  
  124.     // Возвращает константную ссылку на элемент с индексом index
  125.     // Выбрасывает исключение std::out_of_range, если index >= size
  126.     const Type& At(size_t index) const {
  127.         if (index >= size_) {
  128.             throw std::out_of_range("Попытка обращения к элементу за пределами вектора.");
  129.         }
  130.         return simple_vector_[index];
  131.     }
  132.  
  133.     // Обнуляет размер массива, не изменяя его вместимость
  134.     void Clear() noexcept {
  135.         size_ = 0;
  136.     }
  137.  
  138.     // Изменяет размер массива.
  139.     // При увеличении размера новые элементы получают значение по умолчанию для типа Type
  140.     void Resize(size_t new_size) {
  141.         if (new_size > size_) {
  142.             if (new_size > capacity_) {
  143.                 SimpleVector new_vector(std::max(this->capacity_ * 2, new_size));
  144.                 new_vector.size_ = new_size;
  145.                 std::move(this->begin(), this->end(), new_vector.begin());
  146.                 for (size_t i = size_; i < new_size; ++i) {
  147.                     new_vector.simple_vector_[i] = std::move(Type());
  148.                 }
  149.                 *this = std::move(new_vector);
  150.                 this->capacity_ = std::max(this->capacity_ * 2, new_size);
  151.             } else {
  152.                 for (size_t i = size_; i < new_size; ++i) {
  153.                     simple_vector_[i] = std::move(Type()); // дефолтные значения после уже записанных
  154.                 }
  155.             }
  156.            
  157.  
  158.  
  159.             //SimpleVector new_vector(new_size);
  160.             //std::move(this->begin(), this->end(), new_vector.begin());
  161.             //this->simple_vector_ = std::move(new_vector.simple_vector_);
  162.  
  163.             //ArrayPtr<Type> new_arr(new_size);
  164.             //std::move(this->begin(), this->end(), new_arr.Get());
  165.             //this->simple_vector_ = std::move(new_arr);
  166.            
  167.         }
  168.         this->size_ = new_size;
  169.     }
  170.  
  171.     // Возвращает итератор на начало массива
  172.     // Для пустого массива может быть равен (или не равен) nullptr
  173.     Iterator begin() noexcept {
  174.         //return &simple_vector_[0];
  175.         return simple_vector_.Get();
  176.     }
  177.  
  178.     // Возвращает итератор на элемент, следующий за последним
  179.     // Для пустого массива может быть равен (или не равен) nullptr
  180.     Iterator end() noexcept {
  181.         return &simple_vector_[size_];
  182.     }
  183.  
  184.     // Возвращает константный итератор на начало массива
  185.     // Для пустого массива может быть равен (или не равен) nullptr
  186.     ConstIterator begin() const noexcept {
  187.         return cbegin();
  188.     }
  189.  
  190.     // Возвращает итератор на элемент, следующий за последним
  191.     // Для пустого массива может быть равен (или не равен) nullptr
  192.     ConstIterator end() const noexcept {
  193.         return cend();
  194.     }
  195.  
  196.     // Возвращает константный итератор на начало массива
  197.     // Для пустого массива может быть равен (или не равен) nullptr
  198.     ConstIterator cbegin() const noexcept {
  199.         return simple_vector_.Get();
  200.     }
  201.  
  202.     // Возвращает итератор на элемент, следующий за последним
  203.     // Для пустого массива может быть равен (или не равен) nullptr
  204.     ConstIterator cend() const noexcept {
  205.         return &simple_vector_[size_];
  206.     }
  207.  
  208.     SimpleVector& operator=(const SimpleVector& rhs) {
  209.         if (*this == rhs) {
  210.             return *this;
  211.         }
  212.         SimpleVector tmp_vector(rhs);
  213.         this->swap(tmp_vector);
  214.         return *this;
  215.     }
  216.  
  217.     // Перемещающий оператор присваивания
  218.     SimpleVector& operator=(SimpleVector&& rvalue) {
  219.         if (*this == rvalue) {
  220.             return *this;
  221.         }
  222.         this->simple_vector_ = std::move(rvalue.simple_vector_);
  223.         this->size_ = std::move(rvalue.size_);
  224.         rvalue.capacity_ = 0;
  225.         rvalue.size_ = 0;
  226.         return *this;
  227.     }
  228.  
  229.     // Добавляет элемент в конец вектора
  230.     // При нехватке места увеличивает вдвое вместимость вектора
  231.     void PushBack(const Type& item) {
  232.         this->Resize(size_ + 1);
  233.         simple_vector_[size_ - 1] = item;
  234.     }
  235.  
  236.     void PushBack(Type&& item) {
  237.         this->Resize(size_ + 1);
  238.         simple_vector_[size_ - 1] = std::move(item);
  239.     }
  240.  
  241.     // Вставляет значение value в позицию pos.
  242.     // Возвращает итератор на вставленное значение
  243.     // Если перед вставкой значения вектор был заполнен полностью,
  244.     // вместимость вектора должна увеличиться вдвое, а для вектора вместимостью 0 стать равной 1
  245.     Iterator Insert(ConstIterator pos, const Type& value) {
  246.         if (capacity_ == 0) {
  247.             this->PushBack(value);
  248.             return this->begin();
  249.         }
  250.         size_t position_new_element = std::distance(this->cbegin(), pos);
  251.         Iterator new_pos = this->begin() + position_new_element; // текущего вектора
  252.         if (size_ == capacity_) {
  253.             assert(size_ <= capacity_);
  254.  
  255.             //SimpleVector tmp_vector(this->size_ + 1);
  256.             //tmp_vector.capacity_ = this->capacity_ * 2;
  257.             //Iterator position_new_element = this->begin() + (std::distance(this->cbegin(), pos));
  258.             //std::copy(this->begin(), position_new_element, tmp_vector.begin());
  259.             //std::advance(position_new_element, -1);
  260.             //*position_new_element = std::move(value);
  261.             //std::copy_backward(position_new_element, end(), tmp_vector.end());
  262.             //this->swap(tmp_vector);
  263.             //return position_new_element;
  264.  
  265.             ArrayPtr<Type> tmp_arr(capacity_ * 2);
  266.             std::copy(begin(), new_pos, tmp_arr.Get());
  267.             tmp_arr[position_new_element] = value;
  268.             std::copy_backward(new_pos, end(), tmp_arr.Get() + size_ + 1);
  269.             ++size_;
  270.             capacity_ *= 2;
  271.             simple_vector_.swap(tmp_arr);
  272.             return &simple_vector_[position_new_element];
  273.  
  274.             //ArrayPtr<Type> tmp_arr(capacity_ * 2);
  275.             //size_t position_new_element = std::distance(this->cbegin(), pos);
  276.             //Iterator new_pos = this->begin() + position_new_element;
  277.             //std::copy(begin(), new_pos, tmp_arr.Get());
  278.             //tmp_arr[position_new_element] = value;
  279.             //std::copy_backward(new_pos, end(), tmp_arr.Get() + size_ + 1);
  280.             //++size_;
  281.             //capacity_ *= 2;
  282.             //simple_vector_.swap(tmp_arr);
  283.             //return &tmp_arr[position_new_element];
  284.         } else {
  285.             std::copy_backward(new_pos, this->end(), std::next(this->end()));
  286.             simple_vector_[position_new_element] = value;
  287.             ++size_;
  288.             return &simple_vector_[position_new_element];
  289.         }
  290.     }
  291.  
  292.     Iterator Insert(ConstIterator pos, Type&& value) {
  293.         if (capacity_ == 0) {
  294.             this->PushBack(std::move(value));
  295.             return this->begin();
  296.         }
  297.         size_t position_new_element = std::distance(this->cbegin(), pos);
  298.         Iterator new_pos = this->begin() + position_new_element; // текущего вектора
  299.         if (size_ == capacity_) {
  300.             assert(size_ <= capacity_);
  301.  
  302.     ////        //SimpleVector tmp_vector(this->size_ + 1);
  303.     ////        //tmp_vector.capacity_ = this->capacity_ * 2;
  304.     ////        //Iterator position_new_element = this->begin() + (std::distance(this->cbegin(), pos));
  305.     ////        //std::move(this->begin(), position_new_element, tmp_vector.begin());
  306.     ////        //std::advance(position_new_element, -1);
  307.     ////        //*position_new_element = std::move(value);
  308.     ////        //std::move_backward(position_new_element, end(), tmp_vector.end());
  309.     ////        //*this = std::move(tmp_vector);
  310.     ////        //return position_new_element;
  311.  
  312.             ArrayPtr<Type> tmp_arr(capacity_ * 2);
  313.             std::move(begin(), new_pos, tmp_arr.Get());
  314.             tmp_arr[position_new_element] = std::move(value);
  315.             std::move_backward(new_pos, end(), tmp_arr.Get() + size_ + 1);
  316.             ++size_;
  317.             capacity_ *= 2;
  318.             simple_vector_ = std::move(tmp_arr);
  319.             return &simple_vector_[position_new_element];
  320.         } else {
  321.             std::move_backward(new_pos, this->end(), std::next(this->end()));
  322.             simple_vector_[position_new_element] = std::move(value);
  323.             ++size_;
  324.             return &simple_vector_[position_new_element];
  325.             //Iterator new_pos = this->begin() + (std::distance(this->cbegin(), pos));
  326.             //std::move_backward(new_pos, this->end(), std::next(this->end()));
  327.             //*new_pos = std::move(value);
  328.             //++size_;
  329.             //return new_pos;
  330.         }
  331.     }
  332.  
  333.     // "Удаляет" последний элемент вектора. Вектор не должен быть пустым
  334.     void PopBack() noexcept {
  335.         if (this->IsEmpty()) {
  336.             return;
  337.         }
  338.         --size_;
  339.     }
  340.  
  341.     // Удаляет элемент вектора в указанной позиции
  342.     Iterator Erase(ConstIterator pos) {
  343.         std::copy(std::next(pos), this->cend(), const_cast<Iterator>(pos));
  344.         --size_;
  345.         return const_cast<Iterator>(pos);
  346.     }
  347.  
  348.     Iterator Erase(Iterator pos) {
  349.         std::move(std::next(pos), this->end(), const_cast<Iterator>(pos));
  350.         --size_;
  351.         return const_cast<Iterator>(pos);
  352.     }
  353.  
  354.     // Обменивает значение с другим вектором
  355.     void swap(SimpleVector& other) noexcept {
  356.         std::swap(this->capacity_, other.capacity_);
  357.         std::swap(this->size_, other.size_);
  358.         this->simple_vector_.swap(other.simple_vector_);
  359.     }
  360.  
  361.     void Reserve(size_t new_capacity) {
  362.         if (new_capacity <= capacity_) {
  363.             return;
  364.         }
  365.         SimpleVector tmp_vector(new_capacity);
  366.         std::move(begin(), end(), tmp_vector.begin());
  367.         simple_vector_ = std::move(tmp_vector.simple_vector_);
  368.         this->capacity_ = new_capacity;
  369.     }
  370.  
  371. private:
  372.     size_t size_ = 0;
  373.     size_t capacity_ = 0;
  374.     ArrayPtr<Type> simple_vector_;
  375. };
  376.  
  377. template <typename Type>
  378. inline bool operator==(const SimpleVector<Type>& lhs, const SimpleVector<Type>& rhs) {
  379.     return (lhs.GetSize() == rhs.GetSize() && std::equal(lhs.begin(), lhs.end(), rhs.begin(), rhs.end()));
  380. }
  381.  
  382. template <typename Type>
  383. inline bool operator!=(const SimpleVector<Type>& lhs, const SimpleVector<Type>& rhs) {
  384.     return !(lhs == rhs);
  385. }
  386.  
  387. template <typename Type>
  388. inline bool operator<(const SimpleVector<Type>& lhs, const SimpleVector<Type>& rhs) {
  389.     return std::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
  390. }
  391.  
  392. template <typename Type>
  393. inline bool operator<=(const SimpleVector<Type>& lhs, const SimpleVector<Type>& rhs) {
  394.     return !(rhs < lhs);
  395. }
  396.  
  397. template <typename Type>
  398. inline bool operator>(const SimpleVector<Type>& lhs, const SimpleVector<Type>& rhs) {
  399.     return rhs < lhs;
  400. }
  401.  
  402. template <typename Type>
  403. inline bool operator>=(const SimpleVector<Type>& lhs, const SimpleVector<Type>& rhs) {
  404.     return !(lhs < rhs);
  405. }
  406.  
  407. ReserveProxyObj Reserve(size_t capacity_to_reserve) {
  408.     return ReserveProxyObj(capacity_to_reserve);
  409. }
Advertisement
Add Comment
Please, Sign In to add comment