shizaero

Untitled

Aug 26th, 2023
1,198
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 14.62 KB | None | 0 0
  1. #pragma once
  2. #include <cassert>
  3. #include <initializer_list>
  4. #include <algorithm>
  5. #include <stdexcept>
  6. #include <string>
  7. #include "array_ptr.h"
  8. #include <utility>
  9. #include <iterator>
  10. struct ReserveProxyObj
  11. {
  12.    
  13.     ReserveProxyObj(size_t cap) : capacity(cap) {}
  14.    
  15.     size_t capacity;
  16. };
  17.  
  18.  
  19. template <typename Type>
  20. class SimpleVector {
  21. public:
  22.     using Iterator = Type*;
  23.     using ConstIterator = const Type*;
  24.  
  25.     SimpleVector() noexcept : size_(0), capacity_(0), arr_(nullptr) {}
  26.  
  27.    
  28.  
  29.     // Создаёт вектор из size элементов, инициализированных значением по умолчанию
  30.     explicit SimpleVector(size_t size) : size_(size), capacity_(size) {
  31.         //arr_ = new Type[size];
  32.         ArrayPtr<Type> new_arr_(size);
  33.         arr_.swap(new_arr_);
  34.         Iterator beginn = arr_.Get();
  35.         // Iterator endd = &arr_.Get()[static_cast<int>(size_)];
  36.         std::fill(beginn, beginn + size, Type{});
  37.     }
  38.  
  39.     // Создаёт вектор из size элементов, инициализированных значением value
  40.     SimpleVector(size_t size, const Type& value): size_(size), capacity_(size) {
  41.         ArrayPtr<Type> new_arr_(size);
  42.         arr_.swap(new_arr_);
  43.         Iterator beginn = arr_.Get();
  44.         // Iterator endd = &arr_.Get()[static_cast<int>(size_)];
  45.  
  46.         std::fill(beginn, beginn + size, value);
  47.  
  48.     }
  49.  
  50.     // Создаёт вектор из std::initializer_list
  51.     SimpleVector(std::initializer_list<Type> init) {
  52.         if (init.size() == 0) {
  53.             size_ = 0;
  54.             capacity_ = 0;
  55.  
  56.             ArrayPtr<Type> new_arr_(size_); // инициализация поля arr_ значением nullptr
  57.             arr_.swap(new_arr_);
  58.         }
  59.         else {
  60.         size_ = init.size();
  61.         ArrayPtr<Type> new_arr_(size_); // инициализация поля arr_ значением nullptr
  62.         arr_.swap(new_arr_);
  63.         size_t clock = 0;
  64.         for (auto memb: init) {
  65.             arr_[clock] = memb;
  66.             clock++;
  67.         }
  68.         capacity_  = size_;
  69.         }
  70.     }
  71.    
  72.     SimpleVector& operator=(const SimpleVector& rhs) {
  73.         if (this == &rhs) {
  74.             return *this;
  75.         }
  76.         SimpleVector temp(rhs);
  77.         swap(temp);
  78.         return *this;
  79.     }
  80.  
  81.     SimpleVector(ReserveProxyObj obj) {
  82.         capacity_ = obj.capacity;
  83.         size_ = 0;
  84.         ArrayPtr<Type> new_arr(static_cast<size_t>(0));
  85.         arr_.swap(new_arr);
  86.  
  87.     }
  88.     // Возвращает количество элементов в массиве
  89.     size_t GetSize() const noexcept {
  90.         return size_;
  91.        
  92.     }
  93.  
  94.     // Возвращает вместимость массива
  95.     size_t GetCapacity() const noexcept {
  96.         return capacity_;
  97.        
  98.     }
  99.  
  100.     // Сообщает, пустой ли массив
  101.     bool IsEmpty() const noexcept {
  102.         if (size_ == 0) {
  103.             return true;
  104.         }
  105.         else {
  106.             return false;
  107.         }
  108.        
  109.     }
  110.  
  111.     // Возвращает ссылку на элемент с индексом index
  112.     Type& operator[](size_t index) noexcept {
  113.        return arr_[index];
  114.     }
  115.  
  116.     // Возвращает константную ссылку на элемент с индексом index
  117.     const Type& operator[](size_t index) const noexcept {
  118.        return arr_[index];
  119.     }
  120.  
  121.     // Возвращает константную ссылку на элемент с индексом index
  122.     // Выбрасывает исключение std::out_of_range, если index >= size
  123.     Type& At(size_t index) {
  124.         if (index >= size_) {
  125.             throw std::out_of_range ("blah");;
  126.         }
  127.         else {
  128.             return arr_[index];
  129.         }
  130.     }
  131.  
  132.     // Возвращает константную ссылку на элемент с индексом index
  133.     // Выбрасывает исключение std::out_of_range, если index >= size
  134.     const Type& At(size_t index) const {
  135.         if (index >= size_) {
  136.             throw std::out_of_range ("blah");;
  137.         }
  138.         else {
  139.             return arr_[index];
  140.         }
  141.    
  142.     }
  143.  
  144.     // Обнуляет размер массива, не изменяя его вместимость
  145.     void Clear() noexcept {
  146.        size_ = 0;
  147.     }
  148.  
  149.     // Изменяет размер массива.
  150.     // При увеличении размера новые элементы получают значение по умолчанию для типа Type
  151.     void Resize(size_t new_capacity) {
  152.         if (new_capacity > capacity_) {
  153.             ArrayPtr<Type> new_arr_(new_capacity);
  154.             std::move(arr_.Get(), arr_.Get()+size_, new_arr_.Get());
  155.             /*
  156.             for (size_t i = 0; i < size_; ++i) {
  157.                 new_arr_[i] = arr_[i];
  158.             }
  159.             */
  160.             for (size_t i = size_; i < new_capacity; ++i) {
  161.                 new_arr_[i] = Type();  // Initialize new elements with default value
  162.             }
  163.             arr_.swap(new_arr_);
  164.             capacity_ = new_capacity;
  165.         }
  166.         if (new_capacity < size_) std::fill(arr_.Get() + new_capacity, arr_.Get() + size_, 0);
  167.         size_ = new_capacity;
  168.     }
  169.  
  170.     // Возвращает итератор на начало массива
  171.     // Для пустого массива может быть равен (или не равен) nullptr
  172.     Iterator begin() noexcept {
  173.         return arr_.Get();
  174.     }
  175.  
  176.     // Возвращает итератор на элемент, следующий за последним
  177.     // Для пустого массива может быть равен (или не равен) nullptr
  178.     Iterator end() noexcept {
  179.         auto result = arr_.Get() + size_;
  180.         return result;
  181.     }
  182.  
  183.     // Возвращает константный итератор на начало массива
  184.     // Для пустого массива может быть равен (или не равен) nullptr
  185.     ConstIterator begin() const noexcept {
  186.        return arr_.Get();
  187.     }
  188.  
  189.     // Возвращает итератор на элемент, следующий за последним
  190.     // Для пустого массива может быть равен (или не равен) nullptr
  191.     ConstIterator end() const noexcept {
  192.         auto result = arr_.Get() + size_;
  193.         return result;
  194.     }
  195.  
  196.     // Возвращает константный итератор на начало массива
  197.     // Для пустого массива может быть равен (или не равен) nullptr
  198.     ConstIterator cbegin() const noexcept {
  199.         return arr_.Get();
  200.     }
  201.  
  202.     // Возвращает итератор на элемент, следующий за последним
  203.     // Для пустого массива может быть равен (или не равен) nullptr
  204.     ConstIterator cend() const noexcept {
  205.         auto result = arr_.Get() + size_;
  206.         return result;
  207.     }
  208.  
  209.     SimpleVector(const SimpleVector& other) {
  210.        ArrayPtr<Type> new_arr_(other.size_);
  211.        arr_.swap(new_arr_);
  212.        size_ = other.size_;
  213.        capacity_ = other.capacity_;
  214.        std::copy(other.arr_.Get(), other.arr_.Get() + other.size_, arr_.Get());
  215.        
  216.     }
  217.  
  218.  
  219.     SimpleVector(SimpleVector&& other) {
  220.     //    ArrayPtr<Type> new_arr_(std::move(other.size_));
  221.     //    arr_.swap(new_arr_);
  222.     //    size_ = other.size_;
  223.     //    capacity_ = other.capacity_;
  224.     //    std::move(other.arr_.Get(), other.arr_.Get() + other.size_, arr_.Get());
  225.     //    other.Clear();
  226.  
  227.        std::swap(size_, other.size_);
  228.        std::swap(capacity_, other.capacity_);
  229.        arr_.swap(other.arr_);
  230.        other.Clear();      
  231.     }
  232.  
  233.     SimpleVector& operator=(SimpleVector&& rhs) {
  234.         if (*this == rhs) {
  235.             return *this;
  236.         }
  237.             if (*this == rhs) {
  238.             return *this;
  239.         }
  240.         SimpleVector temp(std::move(rhs));
  241.         swap(temp);
  242.         return *this;
  243.  
  244.     }
  245.  
  246.     // Добавляет элемент в конец вектора
  247.     // При нехватке места увеличивает вдвое вместимость вектора
  248.     void PushBack(const Type& item) {
  249.         if (size_ == capacity_) {
  250.             size_t new_capacity = capacity_ == 0 ? 1 : capacity_ * 2;
  251.             ArrayPtr<Type> new_arr_(new_capacity);
  252.             std::move(arr_.Get(), arr_.Get() + size_, new_arr_.Get());
  253.             for (size_t i = size_; i < new_capacity; ++i) {
  254.                 new_arr_[i] = Type();  // Initialize new elements with default value
  255.             }
  256.             arr_.swap(new_arr_);
  257.             capacity_ = new_capacity;
  258.         }
  259.         if (size_ < capacity_)
  260.         {
  261.             arr_[size_++] = move(item);
  262.         }
  263.         arr_[size_ - 1] = move(item);
  264.     }
  265.  
  266.  
  267.  
  268.     void PushBack(Type&& item) {
  269.        if (size_ == capacity_) {
  270.             size_t new_capacity = capacity_ == 0 ? 1 : capacity_ * 2;
  271.             ArrayPtr<Type> new_arr_(new_capacity);
  272.             std::move(arr_.Get(), arr_.Get() + size_, new_arr_.Get());
  273.             for (size_t i = size_; i < new_capacity; ++i) {
  274.                 new_arr_[i] = Type();  // Initialize new elements with default value
  275.             }
  276.             arr_.swap(new_arr_);
  277.             capacity_ = new_capacity;
  278.         }
  279.         if (size_ < capacity_)
  280.         {
  281.             arr_[size_++] = std::move(item);
  282.         }
  283.         arr_[size_ - 1] = std::move(item);
  284.     }  
  285.  
  286.     // Вставляет значение value в позицию pos.
  287.     // Возвращает итератор на вставленное значение
  288.     // Если перед вставкой значения вектор был заполнен полностью,
  289.     // вместимость вектора должна увеличиться вдвое, а для вектора вместимостью 0 стать равной 1
  290.      Iterator Insert(ConstIterator pos, const Type& value) {
  291.         size_t index = pos - arr_.Get();
  292.         if (size_ < capacity_) {
  293.             std::copy_backward(arr_.Get() + index, arr_.Get() + size_, arr_.Get() + size_ + 1);
  294.             arr_[index] = value;
  295.             size_++;
  296.             return arr_.Get() + index;
  297.         }
  298.         else {
  299.             Type* new_arr_ = new Type [size_ + 1];
  300.             std::copy(arr_.Get(), arr_.Get() + index, new_arr_);
  301.             new_arr_[index] = value;
  302.             std::copy(arr_.Get() + index, arr_.Get() + size_, new_arr_ + index + 1);
  303.             size_++;
  304.            
  305.             if (capacity_ > 0) {
  306.             capacity_ *= 2;
  307.             }
  308.             else {
  309.                 capacity_ = size_ * 2;
  310.             }
  311.             ArrayPtr<Type> new_arr2_(new_arr_);
  312.             arr_.swap(new_arr2_);
  313.             return arr_.Get() + index;
  314.         }
  315.     }
  316.  
  317.  
  318.  
  319.  
  320.     Iterator Insert(ConstIterator pos, Type&& value) {
  321.         size_t index = pos - arr_.Get();
  322.         if (size_ < capacity_) {
  323.             std::move_backward(arr_.Get() + index, arr_.Get() + size_, arr_.Get() + size_ + 1);
  324.             arr_[index] = std::move(value);
  325.             size_++;
  326.             return arr_.Get() + index;
  327.         }
  328.         else {
  329.             Type* new_arr_ = new Type [size_ + 1];
  330.             std::move(arr_.Get(), arr_.Get() + index, new_arr_);
  331.             new_arr_[index] = std::move(value);
  332.             std::move(arr_.Get() + index, arr_.Get() + size_, new_arr_ + index + 1);
  333.             size_++;
  334.            
  335.             if (capacity_ > 0) {
  336.             capacity_ *= 2;
  337.             }
  338.             else {
  339.                 capacity_ = size_ * 2;
  340.             }
  341.             ArrayPtr<Type> new_arr2_(std::move(new_arr_));
  342.             arr_.swap(new_arr2_);
  343.             return arr_.Get() + index;
  344.         }
  345.     }
  346.  
  347.     // "Удаляет" последний элемент вектора. Вектор не должен быть пустым
  348.     void PopBack() noexcept {
  349.         size_--;
  350.     }
  351.  
  352.     // Удаляет элемент вектора в указанной позиции
  353.     Iterator Erase(ConstIterator pos) {
  354.       auto index = pos - arr_.Get();
  355.       std::move(arr_.Get() + index + 1, arr_.Get() + size_, arr_.Get() + index);
  356.       size_--;
  357.       return arr_.Get() + index;
  358.     }
  359.  
  360.     // Обменивает значение с другим вектором
  361.     void swap(SimpleVector& other) noexcept {
  362.         arr_.swap(other.arr_);
  363.         std::swap(size_, other.size_);
  364.         std::swap(capacity_, other.capacity_);
  365.     }
  366.  
  367.     void Reserve(size_t new_capacity) {
  368.        if (capacity_ > new_capacity) {
  369.             return;
  370.        }
  371.        if (capacity_ == 0) {
  372.         capacity_ = new_capacity;
  373.        }
  374.        else {
  375.             ArrayPtr<Type> new_arr(new_capacity);
  376.             capacity_ = new_capacity;
  377.             std::copy(arr_.Get(), arr_.Get() + size_, new_arr.Get());
  378.             arr_.swap(new_arr);
  379.  
  380.         }
  381.        
  382.     }
  383.  
  384. private:
  385.  
  386.     size_t size_;
  387.     size_t capacity_;
  388.     ArrayPtr<Type> arr_;
  389. };
  390.  
  391.  
  392. template <typename Type>
  393. inline bool operator==(const SimpleVector<Type>& lhs, const SimpleVector<Type>& rhs) {
  394.    if (lhs.GetSize() != rhs.GetSize()) {
  395.     return false;
  396.    }
  397.    for (size_t i = 0; i < lhs.GetSize(); i++) {
  398.         if (lhs[i] != rhs[i]) {
  399.             return false;
  400.         }
  401.    }
  402.    return true;
  403. }
  404.  
  405. template <typename Type>
  406. inline bool operator!=(const SimpleVector<Type>& lhs, const SimpleVector<Type>& rhs) {
  407.     if (lhs == rhs) {
  408.          return false;
  409.    }
  410.    else {
  411.     return true;
  412.    }
  413. }
  414.  
  415. template <typename Type>
  416. inline bool operator<(const SimpleVector<Type>& lhs, const SimpleVector<Type>& rhs) {
  417.     return std::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
  418. }
  419.  
  420. template <typename Type>
  421. inline bool operator<=(const SimpleVector<Type>& lhs, const SimpleVector<Type>& rhs) {
  422.     if ((lhs < rhs) || (lhs == rhs)) {
  423.     return true;
  424.     }
  425.     else {
  426.         return false;
  427.     }
  428. }
  429.  
  430. template <typename Type>
  431. inline bool operator>(const SimpleVector<Type>& lhs, const SimpleVector<Type>& rhs) {
  432.     if ((lhs < rhs) || (lhs == rhs)) {
  433.     return false;
  434.     }
  435.     else {
  436.         return true;
  437.     }
  438. }
  439.  
  440. template <typename Type>
  441. inline bool operator>=(const SimpleVector<Type>& lhs, const SimpleVector<Type>& rhs) {
  442.     if (lhs < rhs) {
  443.         return false;
  444.     }
  445.     else {
  446.         return true;
  447.     }
  448. }
  449.  
  450. ReserveProxyObj Reserve(size_t capacity_to_reserve) {
  451.     return ReserveProxyObj(capacity_to_reserve);
  452. }
Advertisement
Add Comment
Please, Sign In to add comment