Advertisement
pavel_777

simple_vector.h

Oct 22nd, 2023 (edited)
1,036
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 8.63 KB | None | 0 0
  1. #pragma once
  2.  
  3. // #include <cassert>
  4. #include <initializer_list>
  5. #include <stdexcept>
  6.  
  7. // using namespace std;
  8.  
  9. template <typename Type>
  10. class SimpleVector {
  11. public:
  12.     using Iterator = Type*;
  13.     using ConstIterator = const Type*;
  14.  
  15.     SimpleVector() noexcept = default;
  16.  
  17.     // Создаёт вектор из size элементов, инициализированных значением по умолчанию
  18.     explicit SimpleVector(size_t size) : SimpleVector(size, Type{}) {}
  19.  
  20.     // Создаёт вектор из size элементов, инициализированных значением value
  21.     SimpleVector(size_t size, const Type& value)
  22.     : size_(size), capacity_(size) {
  23.         items_ = new Type[size];
  24.         std::fill(begin(), end(), value);
  25.     }
  26.  
  27.     // Создаёт вектор из std::initializer_list
  28.     SimpleVector(std::initializer_list<Type> init)
  29.     : size_(init.size()), capacity_(init.size()) {
  30.         items_ = new Type[init.size()];
  31.         std::copy(init.begin(), init.end(), begin());
  32.     }
  33.  
  34.     SimpleVector(const SimpleVector& other) noexcept
  35.     {
  36.         // SimpleVector<Type> temp(other.size_);
  37.         // std::copy(other.begin(), other.end(), temp.begin());
  38.         SimpleVector temp;
  39.         temp.capacity_ = other.capacity_;
  40.         temp.items_ = new Type[other.size_];
  41.         for (size_t i=0; i<other.size_; ++i)
  42.         {
  43.             temp[i] = other[i];
  44.             ++temp.size_;
  45.         }
  46.         swap(temp);
  47.     }
  48.  
  49.     SimpleVector& operator=(const SimpleVector& rhs) {
  50.         if (this != &rhs) {
  51.             SimpleVector temp(rhs);
  52.             swap(temp);
  53.         }
  54.         return *this;
  55.     }
  56.  
  57.     ~SimpleVector() {delete[] items_;}
  58.  
  59.     // Возвращает количество элементов в массиве
  60.     size_t GetSize() const noexcept {return size_;}
  61.  
  62.     // Возвращает вместимость массива
  63.     size_t GetCapacity() const noexcept {return capacity_;}
  64.  
  65.     // Сообщает, пустой ли массив
  66.     bool IsEmpty() const noexcept {return !GetSize();}
  67.  
  68.     // Возвращает ссылку на элемент с индексом index
  69.     Type& operator[](size_t index) noexcept {return items_[index];}
  70.  
  71.     // Возвращает константную ссылку на элемент с индексом index
  72.     const Type& operator[](size_t index) const noexcept {return items_[index];}
  73.  
  74.     // Возвращает константную ссылку на элемент с индексом index
  75.     // Выбрасывает исключение std::out_of_range, если index >= size
  76.     Type& At(size_t index) {
  77.         if (index >= size_) {throw std::out_of_range("out of range");};
  78.         return items_[index];
  79.     }
  80.  
  81.     // Возвращает константную ссылку на элемент с индексом index
  82.     // Выбрасывает исключение std::out_of_range, если index >= size
  83.     const Type& At(size_t index) const {
  84.         if (index >= size_) {throw std::out_of_range("out of range");};
  85.         return items_[index];
  86.     }
  87.  
  88.     // Обнуляет размер массива, не изменяя его вместимость
  89.     void Clear() noexcept {size_ = 0;}
  90.  
  91.     // Изменяет размер массива.
  92.     // При увеличении размера новые элементы получают значение по умолчанию для типа Type
  93.     void Resize(size_t new_size) {
  94.         if (new_size > capacity_) {
  95.             size_t new_capacity = new_size > (2 * capacity_)? new_size: 2 * capacity_;
  96.             Type* new_items = new Type[new_size]();
  97.             std::copy(begin(), end(), new_items);
  98.             delete[] items_;
  99.             items_ = new_items;
  100.             capacity_ = new_capacity;
  101.         } else if (new_size > size_) {
  102.             std::fill(begin() + size_, begin() + new_size, Type{});
  103.         }
  104.         size_ = new_size;
  105.     }
  106.  
  107.     // Возвращает итератор на начало массива
  108.     // Для пустого массива может быть равен (или не равен) nullptr
  109.     Iterator begin() noexcept {return items_;}
  110.  
  111.     // Возвращает итератор на элемент, следующий за последним
  112.     // Для пустого массива может быть равен (или не равен) nullptr
  113.     Iterator end() noexcept {return items_ + size_;}
  114.  
  115.     // Возвращает константный итератор на начало массива
  116.     // Для пустого массива может быть равен (или не равен) nullptr
  117.     ConstIterator begin() const noexcept {return items_;}
  118.  
  119.     // Возвращает итератор на элемент, следующий за последним
  120.     // Для пустого массива может быть равен (или не равен) nullptr
  121.     ConstIterator end() const noexcept {return items_ + size_;}
  122.  
  123.     // Возвращает константный итератор на начало массива
  124.     // Для пустого массива может быть равен (или не равен) nullptr
  125.     ConstIterator cbegin() const noexcept {return items_;}
  126.  
  127.     // Возвращает итератор на элемент, следующий за последним
  128.     // Для пустого массива может быть равен (или не равен) nullptr
  129.     ConstIterator cend() const noexcept {return items_ + size_;}
  130.  
  131.     // Добавляет элемент в конец вектора
  132.     // При нехватке места увеличивает вдвое вместимость вектора
  133.     void PushBack(const Type& item) {
  134.         if (size_ == capacity_) {Resize(size_ * 2);}
  135.         items_[size_] = item;
  136.     }
  137.  
  138.     // Вставляет значение value в позицию pos.
  139.     // Возвращает итератор на вставленное значение
  140.     // Если перед вставкой значения вектор был заполнен полностью,
  141.     // вместимость вектора должна увеличиться вдвое, а для вектора вместимостью 0 стать равной 1
  142.     Iterator Insert(ConstIterator pos, const Type& value) {
  143.         // if (!capacity_) {Resize(1);}
  144.         // else if (size_ == capacity_) {Resize(size_ * 2);}
  145.         if (size_ == capacity_ || !capacity_) {Resize(capacity_ + 1);}
  146.         std::copy_backward(Iterator(pos), end(), Iterator(pos) + 1);
  147.         *Iterator(pos) = value;
  148.         return Iterator(pos);
  149.     }
  150.  
  151.     // "Удаляет" последний элемент вектора. Вектор не должен быть пустым
  152.     void PopBack() noexcept {
  153.         if (size_) {--size_;}
  154.     }
  155.  
  156.     // Удаляет элемент вектора в указанной позиции
  157.     Iterator Erase(ConstIterator pos) {
  158.         std::copy(Iterator(pos), end(), Iterator(pos) - 1);
  159.         --size_;
  160.         return Iterator(pos);
  161.     }
  162.  
  163.     // Обменивает значение с другим вектором
  164.     void swap(SimpleVector& other) noexcept {
  165.         std::swap(items_, other.items_);
  166.         std::swap(size_, other.size_);
  167.         std::swap(capacity_, other.capacity_);
  168.     }
  169.  
  170. private:
  171.     Type* items_ = nullptr;
  172.     size_t size_ = 0;
  173.     size_t capacity_ = 0;
  174. };
  175.  
  176. template <typename Type>
  177. inline bool operator==(const SimpleVector<Type>& lhs, const SimpleVector<Type>& rhs) {
  178.     return std::equal(lhs.begin(), lhs.end(), rhs.begin());
  179.  
  180. }
  181.  
  182. template <typename Type>
  183. inline bool operator!=(const SimpleVector<Type>& lhs, const SimpleVector<Type>& rhs) {
  184.     return !(lhs==rhs);
  185. }
  186.  
  187. template <typename Type>
  188. inline bool operator<(const SimpleVector<Type>& lhs, const SimpleVector<Type>& rhs) {
  189.     return std::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
  190. }
  191.  
  192. template <typename Type>
  193. inline bool operator<=(const SimpleVector<Type>& lhs, const SimpleVector<Type>& rhs) {
  194.     return lhs<rhs || lhs==rhs;
  195. }
  196.  
  197. // TODO
  198. // Реализуйте оператор> как return rhs < lhs;. Потому что !(std::lexicographical_compare(...) включает не все варианты.
  199. template <typename Type>
  200. inline bool operator>(const SimpleVector<Type>& lhs, const SimpleVector<Type>& rhs) {
  201.     return !(lhs<=rhs);
  202. }
  203.  
  204. template <typename Type>
  205. inline bool operator>=(const SimpleVector<Type>& lhs, const SimpleVector<Type>& rhs) {
  206.     return !(lhs<rhs);
  207. }
  208.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement