Punchcard

SimpleVector2

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