Punchcard

SimpleVector2-02

Jan 14th, 2024
147
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 10.18 KB | Source Code | 0 0
  1. #pragma once
  2. #include <algorithm>
  3. #include <cassert>
  4. #include <initializer_list>
  5. #include <stdexcept>
  6. #include <iterator>
  7. #include "array_ptr.h"
  8.  
  9. const size_t XPANSION_MULTIPLIER = 2;  
  10.  
  11. template <typename Type>
  12. class SimpleVector {
  13. public:
  14.     using Iterator = Type*;
  15.     using ConstIterator = const Type*;
  16.    
  17.     SimpleVector(const SimpleVector& other) : items_(other.size_) {
  18.        
  19.         size_ = other.size_;
  20.         capacity_ = other.capacity_;
  21.         std::copy(other.begin(), other.end(), begin());    
  22.     }  
  23.  
  24.     SimpleVector& operator=(const SimpleVector& rhs) {
  25.         // Напишите тело конструктора самостоятельно
  26.         if (this != &rhs) {
  27.             SimpleVector dummy(rhs);
  28.             swap(dummy);
  29.         }
  30.         return *this;
  31.     }
  32.  
  33.     // Добавляет элемент в конец вектора
  34.     // При нехватке места увеличивает вдвое вместимость вектора
  35.     void PushBack(const Type& item) {
  36.         if (size_ >= capacity_) {
  37.             Resize(size_ + 1);
  38.             items_[size_ - 1] = item;
  39.         }
  40.         else {
  41.             items_[size_++] = item;
  42.         }
  43.     }
  44.  
  45.     // Вставляет значение value в позицию pos.
  46.     // Возвращает итератор на вставленное значение
  47.     // Если перед вставкой значения вектор был заполнен полностью,
  48.     // вместимость вектора должна увеличиться вдвое, а для вектора вместимостью 0 стать равной 1
  49.     Iterator Insert(ConstIterator pos, const Type& value) {    
  50.  
  51.         if (pos > cend() || pos < cbegin()) return nullptr;
  52.        
  53.         auto indx_int = std::distance(cbegin(), pos);      
  54.         //*
  55.         if (size_ == 0u || pos == cend()) {
  56.             PushBack(value);
  57.             return end() - 1;
  58.         }
  59.         //*/
  60.         if (size_ == capacity_) {
  61.             Resize(size_ + 1);         
  62.         }      
  63.        
  64.         std::copy_backward(begin() + indx_int, end() - 1, end());
  65.         items_[indx_int] = value;
  66.         return begin() + indx_int;
  67.     }
  68.  
  69.     // "Удаляет" последний элемент вектора. Вектор не должен быть пустым
  70.     void PopBack() noexcept {
  71.         if (size_ > 0) --size_;
  72.     }
  73.  
  74.     // Удаляет элемент вектора в указанной позиции
  75.     Iterator Erase(ConstIterator pos) {        
  76.  
  77.         auto it = Iterator(pos);
  78.         std::move(it + 1, end(), it);      
  79.         --size_;
  80.         return (it == end()) ? end() : it + 1;
  81.     }
  82.     // Обменивает значение с другим вектором
  83.     void swap(SimpleVector& other) noexcept {
  84.         items_.swap(other.items_);
  85.         std::swap(size_, other.size_);
  86.         std::swap(capacity_, other.capacity_);
  87.     }  
  88.  
  89.     SimpleVector() noexcept = default;
  90.  
  91.     // Создаёт вектор из size элементов, инициализированных значением по умолчанию
  92.     explicit SimpleVector(size_t size) : size_(size), capacity_(size), items_(size) {
  93.        
  94.         std::fill(begin(), end(), Type());
  95.     }
  96.  
  97.     // Создаёт вектор из size элементов, инициализированных значением value
  98.     SimpleVector(size_t size, const Type& value)  : size_(size), capacity_(size), items_(size) {
  99.        
  100.         std::fill(begin(), end(), value);      
  101.     }
  102.  
  103.     // Создаёт вектор из std::initializer_list
  104.     SimpleVector(std::initializer_list<Type> init) : size_(init.size()), capacity_(init.size()), items_(init.size()) {
  105.        
  106.         std::copy(init.begin(), init.end(), begin());
  107.     }
  108.  
  109.     // Возвращает количество элементов в массиве
  110.     size_t GetSize() const noexcept {
  111.         // Напишите тело самостоятельно
  112.         return size_;
  113.     }
  114.  
  115.     // Возвращает вместимость массива
  116.     size_t GetCapacity() const noexcept {
  117.         // Напишите тело самостоятельно
  118.         return capacity_;
  119.     }
  120.    
  121.     const ArrayPtr<Type>& GetItems() const noexcept {
  122.        
  123.         return items_;
  124.     }  
  125.  
  126.     // Сообщает, пустой ли массив
  127.     bool IsEmpty() const noexcept {
  128.         return size_ == 0u;
  129.     }
  130.  
  131.     // Возвращает ссылку на элемент с индексом index
  132.     Type& operator[](size_t index) noexcept {
  133.         // Напишите тело самостоятельно
  134.         return items_[index];
  135.     }
  136.  
  137.     // Возвращает константную ссылку на элемент с индексом index
  138.     const Type& operator[](size_t index) const noexcept {
  139.         // Напишите тело самостоятельно
  140.         return items_[index];
  141.     }
  142.  
  143.     // Возвращает константную ссылку на элемент с индексом index
  144.     // Выбрасывает исключение std::out_of_range, если index >= size
  145.     Type& At(size_t index) {
  146.         // Напишите тело самостоятельно
  147.         if (index >= size_) {
  148.             throw std::out_of_range("Out of range");
  149.         }
  150.         return items_[index];
  151.     }
  152.  
  153.     // Возвращает константную ссылку на элемент с индексом index
  154.     // Выбрасывает исключение std::out_of_range, если index >= size
  155.     const Type& At(size_t index) const {
  156.         // Напишите тело самостоятельно
  157.         if (index >= size_) {
  158.             throw std::out_of_range("Out of range (const)");
  159.         }
  160.         return items_[index];      
  161.     }
  162.  
  163.     // Обнуляет размер массива, не изменяя его вместимость
  164.     void Clear() noexcept {
  165.         // Напишите тело самостоятельно
  166.         size_ = 0u;
  167.     }
  168.  
  169.     // Изменяет размер массива.
  170.     // При увеличении размера новые элементы получают значение по умолчанию для типа Type
  171.     void Resize(size_t new_size) {
  172.         if (new_size <= capacity_) {
  173.             if (new_size > size_) {            
  174.                 std::fill(begin() + size_, begin() + new_size, Type());
  175.             }          
  176.         }
  177.         else {
  178.             size_t newCapacity = std::max(new_size, capacity_ * XPANSION_MULTIPLIER);
  179.             SimpleVector<Type> newItems(newCapacity);
  180.             if (begin()) {
  181.                 std::copy(begin(), end(), newItems.begin());               
  182.             }
  183.             swap(newItems);
  184.             capacity_ = newCapacity;
  185.         }
  186.         size_ = new_size;
  187.     }
  188.  
  189.     // Возвращает итератор на начало массива
  190.     // Для пустого массива может быть равен (или не равен) nullptr
  191.     Iterator begin() noexcept {
  192.         // Напишите тело самостоятельно
  193.         return items_.Get();
  194.     }
  195.  
  196.     // Возвращает итератор на элемент, следующий за последним
  197.     // Для пустого массива может быть равен (или не равен) nullptr
  198.     Iterator end() noexcept {
  199.         // Напишите тело самостоятельно
  200.         return begin() ? items_.Get() + size_ : begin();
  201.     }
  202.  
  203.     // Возвращает константный итератор на начало массива
  204.     // Для пустого массива может быть равен (или не равен) nullptr
  205.     ConstIterator begin() const noexcept {
  206.         // Напишите тело самостоятельно
  207.         return items_.Get();
  208.     }
  209.  
  210.     // Возвращает итератор на элемент, следующий за последним
  211.     // Для пустого массива может быть равен (или не равен) nullptr
  212.     ConstIterator end() const noexcept {
  213.         // Напишите тело самостоятельно
  214.         return begin() ? items_.Get() + size_ : begin();
  215.     }
  216.  
  217.     // Возвращает константный итератор на начало массива
  218.     // Для пустого массива может быть равен (или не равен) nullptr
  219.     ConstIterator cbegin() const noexcept {
  220.         // Напишите тело самостоятельно
  221.         return items_.Get();
  222.     }
  223.  
  224.     // Возвращает итератор на элемент, следующий за последним
  225.     // Для пустого массива может быть равен (или не равен) nullptr
  226.     ConstIterator cend() const noexcept {
  227.         // Напишите тело самостоятельно
  228.         return cbegin() ? items_.Get() + size_ : cbegin();
  229.     }
  230. private:   
  231.     size_t size_ = 0;
  232.     size_t capacity_ = 0;  
  233.     ArrayPtr<Type> items_; 
  234. };
  235.  
  236. template <typename Type>
  237. inline bool operator==(const SimpleVector<Type>& lhs, const SimpleVector<Type>& rhs) {
  238.    
  239.     return std::equal(lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
  240. }
  241.  
  242. template <typename Type>
  243. inline bool operator!=(const SimpleVector<Type>& lhs, const SimpleVector<Type>& rhs) {
  244.    
  245.     return !(lhs == rhs);
  246. }
  247.  
  248. template <typename Type>
  249. inline bool operator<(const SimpleVector<Type>& lhs, const SimpleVector<Type>& rhs) {
  250.    
  251.     return std::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
  252. }
  253.  
  254. template <typename Type>
  255. inline bool operator<=(const SimpleVector<Type>& lhs, const SimpleVector<Type>& rhs) { 
  256.    
  257.     return !(rhs < lhs);   
  258. }
  259.  
  260. template <typename Type>
  261. inline bool operator>(const SimpleVector<Type>& lhs, const SimpleVector<Type>& rhs) {
  262.    
  263.     return rhs < lhs;
  264. }
  265.  
  266. template <typename Type>
  267. inline bool operator>=(const SimpleVector<Type>& lhs, const SimpleVector<Type>& rhs) {
  268.    
  269.     return !(lhs < rhs);
  270. }  
  271.  
  272. template <typename Type>
  273. std::ostream& operator<<(std::ostream& out, const SimpleVector<Type>& v) {
  274.     // auto items = v.GetItems();
  275.     auto size = v.GetSize();
  276.     auto capacity = v.GetCapacity();    
  277.     out << "\nsize = " << size << ", " << "\n"
  278.         << "capacity = " << capacity << "\n";
  279.  
  280.     out << "{ " << "\n";
  281.     for (auto i = 0u; i < capacity; ++i) {
  282.         out << "[" << i << "]" << "=" << v[i] << "\n";
  283.     }  
  284.     /*
  285.     for (auto item : v) {
  286.         out << item << "\n";
  287.     }
  288.     */
  289.     out << " }";
  290.     return out;
  291. }
Advertisement
Add Comment
Please, Sign In to add comment