Punchcard

SimpleVector2-01

Jan 14th, 2024
112
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 9.58 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 (size_ == 0u) {
  52.             PushBack(value);
  53.             return begin();
  54.         }
  55.         auto indx_int = std::distance(begin(), const_cast<Iterator>(pos));
  56.         if (size_ >= capacity_) {
  57.             Resize(size_ + 1);         
  58.         }      
  59.        
  60.         std::copy_backward(begin() + indx_int, end() - 1, end());
  61.         items_[indx_int] = value;
  62.         return begin() + indx_int;
  63.     }
  64.  
  65.     // "Удаляет" последний элемент вектора. Вектор не должен быть пустым
  66.     void PopBack() noexcept {
  67.         if (size_ > 0) --size_;
  68.     }
  69.  
  70.     // Удаляет элемент вектора в указанной позиции
  71.     Iterator Erase(ConstIterator pos) {        
  72.  
  73.         auto it = Iterator(pos);
  74.         //std::move(it + 1, end(), it);
  75.         std::copy(it + 1, end(), it);
  76.         --size_;
  77.         return (it == end()) ? end() : it + 1;
  78.     }
  79.     // Обменивает значение с другим вектором
  80.     void swap(SimpleVector& other) noexcept {
  81.         items_.swap(other.items_);
  82.         std::swap(size_, other.size_);
  83.         std::swap(capacity_, other.capacity_);
  84.     }  
  85.  
  86.     SimpleVector() noexcept = default;
  87.  
  88.     // Создаёт вектор из size элементов, инициализированных значением по умолчанию
  89.     explicit SimpleVector(size_t size) : size_(size), capacity_(size), items_(size) {
  90.        
  91.         std::fill(begin(), end(), Type());
  92.     }
  93.  
  94.     // Создаёт вектор из size элементов, инициализированных значением value
  95.     SimpleVector(size_t size, const Type& value)  : size_(size), capacity_(size), items_(size) {
  96.        
  97.         std::fill(begin(), end(), value);      
  98.     }
  99.  
  100.     // Создаёт вектор из std::initializer_list
  101.     SimpleVector(std::initializer_list<Type> init) : size_(init.size()), capacity_(init.size()), items_(init.size()) {
  102.        
  103.         std::copy(init.begin(), init.end(), begin());
  104.     }
  105.  
  106.     // Возвращает количество элементов в массиве
  107.     size_t GetSize() const noexcept {
  108.         // Напишите тело самостоятельно
  109.         return size_;
  110.     }
  111.  
  112.     // Возвращает вместимость массива
  113.     size_t GetCapacity() const noexcept {
  114.         // Напишите тело самостоятельно
  115.         return capacity_;
  116.     }
  117.    
  118.     const ArrayPtr<Type>& GetItems() const noexcept {
  119.        
  120.         return items_;
  121.     }  
  122.  
  123.     // Сообщает, пустой ли массив
  124.     bool IsEmpty() const noexcept {
  125.         return size_ == 0u;
  126.     }
  127.  
  128.     // Возвращает ссылку на элемент с индексом index
  129.     Type& operator[](size_t index) noexcept {
  130.         // Напишите тело самостоятельно
  131.         return items_[index];
  132.     }
  133.  
  134.     // Возвращает константную ссылку на элемент с индексом index
  135.     const Type& operator[](size_t index) const noexcept {
  136.         // Напишите тело самостоятельно
  137.         return items_[index];
  138.     }
  139.  
  140.     // Возвращает константную ссылку на элемент с индексом index
  141.     // Выбрасывает исключение std::out_of_range, если index >= size
  142.     Type& At(size_t index) {
  143.         // Напишите тело самостоятельно
  144.         if (index >= size_) {
  145.             throw std::out_of_range("Out of range");
  146.         }
  147.         return items_[index];
  148.     }
  149.  
  150.     // Возвращает константную ссылку на элемент с индексом index
  151.     // Выбрасывает исключение std::out_of_range, если index >= size
  152.     const Type& At(size_t index) const {
  153.         // Напишите тело самостоятельно
  154.         if (index >= size_) {
  155.             throw std::out_of_range("Out of range (const)");
  156.         }
  157.         return items_[index];      
  158.     }
  159.  
  160.     // Обнуляет размер массива, не изменяя его вместимость
  161.     void Clear() noexcept {
  162.         // Напишите тело самостоятельно
  163.         size_ = 0u;
  164.     }
  165.  
  166.     // Изменяет размер массива.
  167.     // При увеличении размера новые элементы получают значение по умолчанию для типа Type
  168.     void Resize(size_t new_size) {
  169.         if (new_size <= capacity_) {
  170.             if (new_size > size_) {            
  171.                 std::fill(begin() + size_, begin() + new_size, Type());
  172.             }          
  173.         }
  174.         else {
  175.             size_t newCapacity = std::max(new_size, capacity_ * XPANSION_MULTIPLIER);
  176.             SimpleVector<Type> newItems(newCapacity);
  177.             if (begin()) {
  178.                 std::copy(begin(), end(), newItems.begin());               
  179.             }
  180.             swap(newItems);
  181.             capacity_ = newCapacity;
  182.         }
  183.         size_ = new_size;
  184.     }
  185.  
  186.     // Возвращает итератор на начало массива
  187.     // Для пустого массива может быть равен (или не равен) nullptr
  188.     Iterator begin() noexcept {
  189.         // Напишите тело самостоятельно
  190.         return items_.Get();
  191.     }
  192.  
  193.     // Возвращает итератор на элемент, следующий за последним
  194.     // Для пустого массива может быть равен (или не равен) nullptr
  195.     Iterator end() noexcept {
  196.         // Напишите тело самостоятельно
  197.         return items_.Get() + size_;
  198.     }
  199.  
  200.     // Возвращает константный итератор на начало массива
  201.     // Для пустого массива может быть равен (или не равен) nullptr
  202.     ConstIterator begin() const noexcept {
  203.         // Напишите тело самостоятельно
  204.         return items_.Get();
  205.     }
  206.  
  207.     // Возвращает итератор на элемент, следующий за последним
  208.     // Для пустого массива может быть равен (или не равен) nullptr
  209.     ConstIterator end() const noexcept {
  210.         // Напишите тело самостоятельно
  211.         return items_.Get() + size_;
  212.     }
  213.  
  214.     // Возвращает константный итератор на начало массива
  215.     // Для пустого массива может быть равен (или не равен) nullptr
  216.     ConstIterator cbegin() const noexcept {
  217.         // Напишите тело самостоятельно
  218.         return items_.Get();
  219.     }
  220.  
  221.     // Возвращает итератор на элемент, следующий за последним
  222.     // Для пустого массива может быть равен (или не равен) nullptr
  223.     ConstIterator cend() const noexcept {
  224.         // Напишите тело самостоятельно
  225.         return items_.Get() + size_;
  226.     }
  227. private:   
  228.     size_t size_ = 0;
  229.     size_t capacity_ = 0;  
  230.     ArrayPtr<Type> items_; 
  231. };
  232.  
  233. template <typename Type>
  234. inline bool operator==(const SimpleVector<Type>& lhs, const SimpleVector<Type>& rhs) {
  235.    
  236.     return std::equal(lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
  237. }
  238.  
  239. template <typename Type>
  240. inline bool operator!=(const SimpleVector<Type>& lhs, const SimpleVector<Type>& rhs) {
  241.    
  242.     return !(lhs == rhs);
  243. }
  244.  
  245. template <typename Type>
  246. inline bool operator<(const SimpleVector<Type>& lhs, const SimpleVector<Type>& rhs) {
  247.    
  248.     return std::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
  249. }
  250.  
  251. template <typename Type>
  252. inline bool operator<=(const SimpleVector<Type>& lhs, const SimpleVector<Type>& rhs) { 
  253.    
  254.     return !(rhs < lhs);   
  255. }
  256.  
  257. template <typename Type>
  258. inline bool operator>(const SimpleVector<Type>& lhs, const SimpleVector<Type>& rhs) {
  259.    
  260.     return rhs < lhs;
  261. }
  262.  
  263. template <typename Type>
  264. inline bool operator>=(const SimpleVector<Type>& lhs, const SimpleVector<Type>& rhs) {
  265.    
  266.     return !(lhs < rhs);
  267. }
Advertisement
Add Comment
Please, Sign In to add comment