shizaero

Untitled

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