shizaero

Untitled

Aug 26th, 2023
1,098
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 14.51 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.         arr_[size_]  = item;
  251.         size_++;
  252.        }
  253.        else {
  254.             if (capacity_ > 0) {
  255.             capacity_ *= 2;
  256.             }
  257.             else {
  258.                 capacity_ = size_ * 2;
  259.             }
  260.             Type* new_arr_ = new Type[std::move(capacity_)];
  261.             std::move(arr_.Get(), arr_.Get() + size_, new_arr_);
  262.             new_arr_[size_] =item;
  263.             ArrayPtr<Type> new_arr2_(new_arr_);
  264.             arr_.swap(new_arr2_);
  265.             size_ += 1;
  266.        }
  267.     }
  268.  
  269.  
  270.  
  271.     void PushBack(Type&& item) {
  272.        if (size_ < capacity_) {
  273.         arr_[size_]  = std::move(item);
  274.         size_++;
  275.        }
  276.        else {
  277.              if (capacity_ > 0) {
  278.             capacity_ *= 2;
  279.             }
  280.             else {
  281.                 capacity_ = size_ * 2;
  282.             }
  283.             Type* new_arr_ = new Type[std::move(capacity_)];
  284.             std::move(arr_.Get(), arr_.Get() + size_, new_arr_);
  285.             new_arr_[size_] = std::move(item);
  286.             ArrayPtr<Type> new_arr2_(std::move(new_arr_));
  287.             arr_.swap(new_arr2_);
  288.             size_ += 1;
  289.        }
  290.     }  
  291.  
  292.     // Вставляет значение value в позицию pos.
  293.     // Возвращает итератор на вставленное значение
  294.     // Если перед вставкой значения вектор был заполнен полностью,
  295.     // вместимость вектора должна увеличиться вдвое, а для вектора вместимостью 0 стать равной 1
  296.      Iterator Insert(ConstIterator pos, const Type& value) {
  297.         size_t index = pos - arr_.Get();
  298.         if (size_ < capacity_) {
  299.             std::copy_backward(arr_.Get() + index, arr_.Get() + size_, arr_.Get() + size_ + 1);
  300.             arr_[index] = value;
  301.             size_++;
  302.             return arr_.Get() + index;
  303.         }
  304.         else {
  305.             Type* new_arr_ = new Type [size_ + 1];
  306.             std::copy(arr_.Get(), arr_.Get() + index, new_arr_);
  307.             new_arr_[index] = value;
  308.             std::copy(arr_.Get() + index, arr_.Get() + size_, new_arr_ + index + 1);
  309.             size_++;
  310.            
  311.             if (capacity_ > 0) {
  312.             capacity_ *= 2;
  313.             }
  314.             else {
  315.                 capacity_ = size_ * 2;
  316.             }
  317.             ArrayPtr<Type> new_arr2_(new_arr_);
  318.             arr_.swap(new_arr2_);
  319.             return arr_.Get() + index;
  320.         }
  321.     }
  322.  
  323.  
  324.  
  325.  
  326.     Iterator Insert(ConstIterator pos, Type&& value) {
  327.         size_t index = pos - arr_.Get();
  328.         if (size_ < capacity_) {
  329.             std::move_backward(arr_.Get() + index, arr_.Get() + size_, arr_.Get() + size_ + 1);
  330.             arr_[index] = std::move(value);
  331.             size_++;
  332.             return arr_.Get() + index;
  333.         }
  334.         else {
  335.             Type* new_arr_ = new Type [size_ + 1];
  336.             std::move(arr_.Get(), arr_.Get() + index, new_arr_);
  337.             new_arr_[index] = std::move(value);
  338.             std::move(arr_.Get() + index, arr_.Get() + size_, new_arr_ + index + 1);
  339.             size_++;
  340.            
  341.             if (capacity_ > 0) {
  342.             capacity_ *= 2;
  343.             }
  344.             else {
  345.                 capacity_ = size_ * 2;
  346.             }
  347.             ArrayPtr<Type> new_arr2_(std::move(new_arr_));
  348.             arr_.swap(new_arr2_);
  349.             return arr_.Get() + index;
  350.         }
  351.     }
  352.  
  353.     // "Удаляет" последний элемент вектора. Вектор не должен быть пустым
  354.     void PopBack() noexcept {
  355.         size_--;
  356.     }
  357.  
  358.     // Удаляет элемент вектора в указанной позиции
  359.     Iterator Erase(ConstIterator pos) {
  360.       auto index = pos - arr_.Get();
  361.       std::move(arr_.Get() + index + 1, arr_.Get() + size_, arr_.Get() + index);
  362.       size_--;
  363.       return arr_.Get() + index;
  364.     }
  365.  
  366.     // Обменивает значение с другим вектором
  367.     void swap(SimpleVector& other) noexcept {
  368.         arr_.swap(other.arr_);
  369.         std::swap(size_, other.size_);
  370.         std::swap(capacity_, other.capacity_);
  371.     }
  372.  
  373.     void Reserve(size_t new_capacity) {
  374.        if (capacity_ > new_capacity) {
  375.             return;
  376.        }
  377.        if (capacity_ == 0) {
  378.         capacity_ = new_capacity;
  379.        }
  380.        else {
  381.             ArrayPtr<Type> new_arr(new_capacity);
  382.             capacity_ = new_capacity;
  383.             std::copy(arr_.Get(), arr_.Get() + size_, new_arr.Get());
  384.             arr_.swap(new_arr);
  385.  
  386.         }
  387.        
  388.     }
  389.  
  390. private:
  391.  
  392.     size_t size_;
  393.     size_t capacity_;
  394.     ArrayPtr<Type> arr_;
  395. };
  396.  
  397.  
  398. template <typename Type>
  399. inline bool operator==(const SimpleVector<Type>& lhs, const SimpleVector<Type>& rhs) {
  400.    if (lhs.GetSize() != rhs.GetSize()) {
  401.     return false;
  402.    }
  403.    for (size_t i = 0; i < lhs.GetSize(); i++) {
  404.         if (lhs[i] != rhs[i]) {
  405.             return false;
  406.         }
  407.    }
  408.    return true;
  409. }
  410.  
  411. template <typename Type>
  412. inline bool operator!=(const SimpleVector<Type>& lhs, const SimpleVector<Type>& rhs) {
  413.     if (lhs == rhs) {
  414.          return false;
  415.    }
  416.    else {
  417.     return true;
  418.    }
  419. }
  420.  
  421. template <typename Type>
  422. inline bool operator<(const SimpleVector<Type>& lhs, const SimpleVector<Type>& rhs) {
  423.     return std::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
  424. }
  425.  
  426. template <typename Type>
  427. inline bool operator<=(const SimpleVector<Type>& lhs, const SimpleVector<Type>& rhs) {
  428.     if ((lhs < rhs) || (lhs == rhs)) {
  429.     return true;
  430.     }
  431.     else {
  432.         return false;
  433.     }
  434. }
  435.  
  436. template <typename Type>
  437. inline bool operator>(const SimpleVector<Type>& lhs, const SimpleVector<Type>& rhs) {
  438.     if ((lhs < rhs) || (lhs == rhs)) {
  439.     return false;
  440.     }
  441.     else {
  442.         return true;
  443.     }
  444. }
  445.  
  446. template <typename Type>
  447. inline bool operator>=(const SimpleVector<Type>& lhs, const SimpleVector<Type>& rhs) {
  448.     if (lhs < rhs) {
  449.         return false;
  450.     }
  451.     else {
  452.         return true;
  453.     }
  454. }
  455.  
  456. ReserveProxyObj Reserve(size_t capacity_to_reserve) {
  457.     return ReserveProxyObj(capacity_to_reserve);
  458. }
Advertisement
Add Comment
Please, Sign In to add comment