shizaero

Untitled

Aug 26th, 2023
1,126
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 14.73 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_size) {
  152.         if (new_size < size_) {
  153.             size_ = new_size;
  154.         }
  155.         else if (capacity_ > new_size) {
  156.             auto temp_old_size_ = size_;
  157.             size_ = new_size;
  158.             Iterator beginn = arr_.Get();
  159.             // Iterator endd = &arr_[static_cast<int>(size_)];
  160.             std::fill(beginn + temp_old_size_, beginn + size_, Type{});
  161.         }
  162.         else {
  163.             Type* new_arr_ = new Type[new_size];
  164.             Iterator beginn = arr_.Get();
  165.             //Iterator endd = &arr_[static_cast<int>(size_)];
  166.             std::copy(beginn, beginn + size_, new_arr_);
  167.             std::fill(new_arr_ + size_, new_arr_+new_size, Type{});
  168.             capacity_ = std::max(capacity_*2, new_size);
  169.             size_ = new_size;
  170.             ArrayPtr<Type> new_arr2_(new_arr_);
  171.             arr_.swap(new_arr2_);
  172.            
  173.         }
  174.        
  175.  
  176.        
  177.     }
  178.  
  179.     // Возвращает итератор на начало массива
  180.     // Для пустого массива может быть равен (или не равен) nullptr
  181.     Iterator begin() noexcept {
  182.         return arr_.Get();
  183.     }
  184.  
  185.     // Возвращает итератор на элемент, следующий за последним
  186.     // Для пустого массива может быть равен (или не равен) nullptr
  187.     Iterator end() noexcept {
  188.         auto result = arr_.Get() + size_;
  189.         return result;
  190.     }
  191.  
  192.     // Возвращает константный итератор на начало массива
  193.     // Для пустого массива может быть равен (или не равен) nullptr
  194.     ConstIterator begin() const noexcept {
  195.        return arr_.Get();
  196.     }
  197.  
  198.     // Возвращает итератор на элемент, следующий за последним
  199.     // Для пустого массива может быть равен (или не равен) nullptr
  200.     ConstIterator end() const noexcept {
  201.         auto result = arr_.Get() + size_;
  202.         return result;
  203.     }
  204.  
  205.     // Возвращает константный итератор на начало массива
  206.     // Для пустого массива может быть равен (или не равен) nullptr
  207.     ConstIterator cbegin() const noexcept {
  208.         return arr_.Get();
  209.     }
  210.  
  211.     // Возвращает итератор на элемент, следующий за последним
  212.     // Для пустого массива может быть равен (или не равен) nullptr
  213.     ConstIterator cend() const noexcept {
  214.         auto result = arr_.Get() + size_;
  215.         return result;
  216.     }
  217.  
  218.     SimpleVector(const SimpleVector& other) {
  219.        ArrayPtr<Type> new_arr_(other.size_);
  220.        arr_.swap(new_arr_);
  221.        size_ = other.size_;
  222.        capacity_ = other.capacity_;
  223.        std::copy(other.arr_.Get(), other.arr_.Get() + other.size_, arr_.Get());
  224.        
  225.     }
  226.  
  227.  
  228.     SimpleVector(SimpleVector&& other) {
  229.     //    ArrayPtr<Type> new_arr_(std::move(other.size_));
  230.     //    arr_.swap(new_arr_);
  231.     //    size_ = other.size_;
  232.     //    capacity_ = other.capacity_;
  233.     //    std::move(other.arr_.Get(), other.arr_.Get() + other.size_, arr_.Get());
  234.     //    other.Clear();
  235.  
  236.        std::swap(size_, other.size_);
  237.        std::swap(capacity_, other.capacity_);
  238.        arr_.swap(other.arr_);
  239.        other.Clear();      
  240.     }
  241.  
  242.     SimpleVector& operator=(SimpleVector&& rhs) {
  243.         if (*this == rhs) {
  244.             return *this;
  245.         }
  246.             if (*this == rhs) {
  247.             return *this;
  248.         }
  249.         SimpleVector temp(std::move(rhs));
  250.         swap(temp);
  251.         return *this;
  252.  
  253.     }
  254.  
  255.     // Добавляет элемент в конец вектора
  256.     // При нехватке места увеличивает вдвое вместимость вектора
  257.     void PushBack(const Type& item) {
  258.        if (size_ < capacity_) {
  259.         arr_[size_]  = item;
  260.         size_++;
  261.        }
  262.        else {
  263.             if (capacity_ > 0) {
  264.             capacity_ *= 2;
  265.             }
  266.             else {
  267.                 capacity_ = size_ * 2;
  268.             }
  269.             Type* new_arr_ = new Type[std::move(capacity_)];
  270.             std::move(arr_.Get(), arr_.Get() + size_, new_arr_);
  271.             new_arr_[size_] =item;
  272.             ArrayPtr<Type> new_arr2_(new_arr_);
  273.             arr_.swap(new_arr2_);
  274.             size_ += 1;
  275.        }
  276.     }
  277.  
  278.  
  279.  
  280.     void PushBack(Type&& item) {
  281.        if (size_ < capacity_) {
  282.         arr_[size_]  = std::move(item);
  283.         size_++;
  284.        }
  285.        else {
  286.              if (capacity_ > 0) {
  287.             capacity_ *= 2;
  288.             }
  289.             else {
  290.                 capacity_ = size_ * 2;
  291.             }
  292.             Type* new_arr_ = new Type[std::move(capacity_)];
  293.             std::move(arr_.Get(), arr_.Get() + size_, new_arr_);
  294.             new_arr_[size_] = std::move(item);
  295.             ArrayPtr<Type> new_arr2_(std::move(new_arr_));
  296.             arr_.swap(new_arr2_);
  297.             size_ += 1;
  298.        }
  299.     }  
  300.  
  301.     // Вставляет значение value в позицию pos.
  302.     // Возвращает итератор на вставленное значение
  303.     // Если перед вставкой значения вектор был заполнен полностью,
  304.     // вместимость вектора должна увеличиться вдвое, а для вектора вместимостью 0 стать равной 1
  305.      Iterator Insert(ConstIterator pos, const Type& value) {
  306.         size_t index = pos - arr_.Get();
  307.         if (size_ < capacity_) {
  308.             std::copy_backward(arr_.Get() + index, arr_.Get() + size_, arr_.Get() + size_ + 1);
  309.             arr_[index] = value;
  310.             size_++;
  311.             return arr_.Get() + index;
  312.         }
  313.         else {
  314.             Type* new_arr_ = new Type [size_ + 1];
  315.             std::copy(arr_.Get(), arr_.Get() + index, new_arr_);
  316.             new_arr_[index] = value;
  317.             std::copy(arr_.Get() + index, arr_.Get() + size_, new_arr_ + index + 1);
  318.             size_++;
  319.            
  320.             if (capacity_ > 0) {
  321.             capacity_ *= 2;
  322.             }
  323.             else {
  324.                 capacity_ = size_ * 2;
  325.             }
  326.             ArrayPtr<Type> new_arr2_(new_arr_);
  327.             arr_.swap(new_arr2_);
  328.             return arr_.Get() + index;
  329.         }
  330.     }
  331.  
  332.  
  333.  
  334.  
  335.     Iterator Insert(ConstIterator pos, Type&& value) {
  336.         size_t index = pos - arr_.Get();
  337.         if (size_ < capacity_) {
  338.             std::move_backward(arr_.Get() + index, arr_.Get() + size_, arr_.Get() + size_ + 1);
  339.             arr_[index] = std::move(value);
  340.             size_++;
  341.             return arr_.Get() + index;
  342.         }
  343.         else {
  344.             Type* new_arr_ = new Type [size_ + 1];
  345.             std::move(arr_.Get(), arr_.Get() + index, new_arr_);
  346.             new_arr_[index] = std::move(value);
  347.             std::move(arr_.Get() + index, arr_.Get() + size_, new_arr_ + index + 1);
  348.             size_++;
  349.            
  350.             if (capacity_ > 0) {
  351.             capacity_ *= 2;
  352.             }
  353.             else {
  354.                 capacity_ = size_ * 2;
  355.             }
  356.             ArrayPtr<Type> new_arr2_(std::move(new_arr_));
  357.             arr_.swap(new_arr2_);
  358.             return arr_.Get() + index;
  359.         }
  360.     }
  361.  
  362.     // "Удаляет" последний элемент вектора. Вектор не должен быть пустым
  363.     void PopBack() noexcept {
  364.         size_--;
  365.     }
  366.  
  367.     // Удаляет элемент вектора в указанной позиции
  368.     Iterator Erase(ConstIterator pos) {
  369.       auto index = pos - arr_.Get();
  370.       std::move(arr_.Get() + index + 1, arr_.Get() + size_, arr_.Get() + index);
  371.       size_--;
  372.       return arr_.Get() + index;
  373.     }
  374.  
  375.     // Обменивает значение с другим вектором
  376.     void swap(SimpleVector& other) noexcept {
  377.         arr_.swap(other.arr_);
  378.         std::swap(size_, other.size_);
  379.         std::swap(capacity_, other.capacity_);
  380.     }
  381.  
  382.     void Reserve(size_t new_capacity) {
  383.        if (capacity_ > new_capacity) {
  384.             return;
  385.        }
  386.        if (capacity_ == 0) {
  387.         capacity_ = new_capacity;
  388.        }
  389.        else {
  390.             ArrayPtr<Type> new_arr(new_capacity);
  391.             capacity_ = new_capacity;
  392.             std::copy(arr_.Get(), arr_.Get() + size_, new_arr.Get());
  393.             arr_.swap(new_arr);
  394.  
  395.         }
  396.        
  397.     }
  398.    
  399.  
  400.  
  401. private:
  402.  
  403. size_t size_;
  404. size_t capacity_;
  405. ArrayPtr<Type> arr_;
  406. };
  407.  
  408.  
  409. template <typename Type>
  410. inline bool operator==(const SimpleVector<Type>& lhs, const SimpleVector<Type>& rhs) {
  411.    if (lhs.GetSize() != rhs.GetSize()) {
  412.     return false;
  413.    }
  414.    for (size_t i = 0; i < lhs.GetSize(); i++) {
  415.         if (lhs[i] != rhs[i]) {
  416.             return false;
  417.         }
  418.    }
  419.    return true;
  420. }
  421.  
  422. template <typename Type>
  423. inline bool operator!=(const SimpleVector<Type>& lhs, const SimpleVector<Type>& rhs) {
  424.     if (lhs == rhs) {
  425.          return false;
  426.    }
  427.    else {
  428.     return true;
  429.    }
  430. }
  431.  
  432. template <typename Type>
  433. inline bool operator<(const SimpleVector<Type>& lhs, const SimpleVector<Type>& rhs) {
  434.     return std::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
  435. }
  436.  
  437. template <typename Type>
  438. inline bool operator<=(const SimpleVector<Type>& lhs, const SimpleVector<Type>& rhs) {
  439.     if ((lhs < rhs) || (lhs == rhs)) {
  440.     return true;
  441.     }
  442.     else {
  443.         return false;
  444.     }
  445. }
  446.  
  447. template <typename Type>
  448. inline bool operator>(const SimpleVector<Type>& lhs, const SimpleVector<Type>& rhs) {
  449.     if ((lhs < rhs) || (lhs == rhs)) {
  450.     return false;
  451.     }
  452.     else {
  453.         return true;
  454.     }
  455. }
  456.  
  457. template <typename Type>
  458. inline bool operator>=(const SimpleVector<Type>& lhs, const SimpleVector<Type>& rhs) {
  459.     if (lhs < rhs) {
  460.         return false;
  461.     }
  462.     else {
  463.         return true;
  464.     }
  465. }
  466.  
  467. ReserveProxyObj Reserve(size_t capacity_to_reserve) {
  468.     return ReserveProxyObj(capacity_to_reserve);
  469. }
Advertisement
Add Comment
Please, Sign In to add comment