Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #pragma once
- #include <initializer_list>
- #include "array_ptr.h"
- #include <stdexcept>
- template <typename Type>
- class SimpleVector {
- private:
- ArrayPtr<Type> data;
- size_t size_;
- size_t capacity_;
- public:
- using Iterator = Type*;
- using ConstIterator = const Type*;
- SimpleVector() noexcept : data(nullptr), size_(0), capacity_(0) {}
- // Создаёт вектор из size элементов, инициализированных значением по умолчанию
- explicit SimpleVector(size_t size) {
- this->size_ = size;
- this->capacity_ = size;
- ArrayPtr<Type> new_data(size);
- for (size_t i = 0; i < size; ++i) {
- new_data[i] = Type{}; // Initialize new elements with default value
- }
- data.swap(new_data);
- }
- // Создаёт вектор из size элементов, инициализированных значением value
- SimpleVector(size_t size, const Type& value) {
- this->size_ = size;
- this->capacity_ = size;
- ArrayPtr<Type> new_data(size);
- data.swap(new_data);
- for(size_t i = 0; i < size; ++i){
- data[i] = value;
- }
- }
- // Создаёт вектор из std::initializer_list
- SimpleVector(std::initializer_list<Type> init) {
- this->size_ = init.size();
- this->capacity_ = init.size();
- ArrayPtr<Type> new_data(size_);
- data.swap(new_data);
- size_t i = 0;
- for (const auto& item : init) {
- data[i++] = item;
- }
- }
- SimpleVector(const SimpleVector& other)
- : size_(other.size_), capacity_(other.capacity_)
- {
- ArrayPtr<Type> new_data(size_);
- for(size_t i = 0; i < size_; ++i){
- new_data[i] = other.data[i];
- }
- data.swap(new_data);
- }
- SimpleVector& operator=(const SimpleVector& rhs) {
- if (this == &rhs) {
- return *this;
- }
- SimpleVector temp(rhs);
- swap(temp);
- return *this;
- }
- // Добавляет элемент в конец вектора
- // При нехватке места увеличивает вдвое вместимость вектора
- void PushBack(const Type& item) {
- if (size_ == capacity_) {
- // Увеличиваем вместимость вдвое
- size_t new_capacity = capacity_ == 0 ? 1 : capacity_ * 2;
- Resize(new_capacity);
- size_ += 1;
- }
- if (size_ < capacity_)
- {
- data[size_++] = item;
- }
- data[size_ - 1] = item;
- }
- // Вставляет значение value в позицию pos.
- // Возвращает итератор на вставленное значение
- // Если перед вставкой значения вектор был заполнен полностью,
- // вместимость вектора должна увеличиться вдвое, а для вектора вместимостью 0 стать равной 1
- Iterator Insert(ConstIterator pos, const Type& value) {
- size_t index = pos - data.Get();
- if (size_ == capacity_) {
- size_t new_capacity = capacity_ == 0 ? 1 : capacity_ * 2;
- Resize(new_capacity);
- size_ += 1;
- }
- for (size_t i = size_; i > index; --i) {
- data[i] = data[i - 1];
- }
- data[index] = value;
- return data.Get() + index;
- }
- // "Удаляет" последний элемент вектора. Вектор не должен быть пустым
- void PopBack() noexcept {
- if (size_ > 0) {
- --size_;
- }
- }
- // Удаляет элемент вектора в указанной позиции
- Iterator Erase(ConstIterator pos) {
- size_t index = pos - data.Get();
- if (index >= size_) {
- return end();
- }
- for (size_t i = index; i < size_ - 1; ++i) {
- data[i] = data[i + 1];
- }
- --size_;
- return data.Get() + index;
- }
- // Обменивает значение с другим вектором
- void swap(SimpleVector& other) noexcept {
- data.swap(other.data);
- std::swap(size_, other.size_);
- std::swap(capacity_, other.capacity_);
- }
- // Возвращает количество элементов в массиве
- size_t GetSize() const noexcept {
- return size_;
- }
- // Возвращает вместимость массива
- size_t GetCapacity() const noexcept {
- return capacity_;
- }
- // Сообщает, пустой ли массив
- bool IsEmpty() const noexcept {
- return size_ == 0;
- }
- // Возвращает ссылку на элемент с индексом index
- Type& operator[](size_t index) noexcept{
- return data[index];
- }
- // Возвращает константную ссылку на элемент с индексом index
- const Type& operator[](size_t index) const noexcept{
- return data[index];
- }
- // Возвращает константную ссылку на элемент с индексом index
- // Выбрасывает исключение std::out_of_range, если index >= size
- Type& At(size_t index) {
- if (index >= size_) {
- throw std::out_of_range("Index out of range");
- }
- return data[index];
- }
- // Возвращает константную ссылку на элемент с индексом index
- // Выбрасывает исключение std::out_of_range, если index >= size
- const Type& At(size_t index) const {
- if (index >= size_) {
- throw std::out_of_range("Index out of range");
- }
- return data[index];
- }
- // Обнуляет размер массива, не изменяя его вместимость
- void Clear() noexcept {
- size_ = 0;
- }
- // Изменяет размер массива.
- // При увеличении размера новые элементы получают значение по умолчанию для типа Type
- void Resize(size_t new_size) {
- if (new_size > capacity_) {
- ArrayPtr<Type> new_data(new_size);
- for (size_t i = 0; i < size_; ++i) {
- new_data[i] = data[i];
- }
- for (size_t i = size_; i < new_size; ++i) {
- new_data[i] = Type(); // Initialize new elements with default value
- }
- data.swap(new_data);
- capacity_ = new_size;
- }
- if(new_size < size_) std::fill(data.Get() + new_size, data.Get() + size_, 0);
- size_ = new_size;
- }
- // Возвращает итератор на начало массива
- // Для пустого массива может быть равен (или не равен) nullptr
- Iterator begin() noexcept {
- return data.Get();
- }
- // Возвращает итератор на элемент, следующий за последним
- // Для пустого массива может быть равен (или не равен) nullptr
- Iterator end() noexcept {
- return data.Get() + size_;
- }
- // Возвращает константный итератор на начало массива
- // Для пустого массива может быть равен (или не равен) nullptr
- ConstIterator begin() const noexcept {
- return data.Get();
- }
- // Возвращает итератор на элемент, следующий за последним
- // Для пустого массива может быть равен (или не равен) nullptr
- ConstIterator end() const noexcept {
- return data.Get() + size_;
- }
- // Возвращает константный итератор на начало массива
- // Для пустого массива может быть равен (или не равен) nullptr
- ConstIterator cbegin() const noexcept {
- return begin();
- }
- // Возвращает итератор на элемент, следующий за последним
- // Для пустого массива может быть равен (или не равен) nullptr
- ConstIterator cend() const noexcept {
- return end();
- }
- };
- template <typename Type>
- inline bool operator==(const SimpleVector<Type>& lhs, const SimpleVector<Type>& rhs) {
- if (lhs.GetSize() != rhs.GetSize())
- {
- return false;
- }
- return std::equal(lhs.begin(), lhs.end(), rhs.begin());
- }
- template <typename Type>
- inline bool operator!=(const SimpleVector<Type>& lhs, const SimpleVector<Type>& rhs) {
- return !(lhs == rhs);
- }
- template <typename Type>
- inline bool operator<(const SimpleVector<Type>& lhs, const SimpleVector<Type>& rhs) {
- return std::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
- }
- template <typename Type>
- inline bool operator<=(const SimpleVector<Type>& lhs, const SimpleVector<Type>& rhs) {
- return !(lhs > rhs);
- }
- template <typename Type>
- inline bool operator>(const SimpleVector<Type>& lhs, const SimpleVector<Type>& rhs) {
- return rhs < lhs;
- }
- template <typename Type>
- inline bool operator>=(const SimpleVector<Type>& lhs, const SimpleVector<Type>& rhs) {
- return !(lhs < rhs);
- }
Advertisement
Add Comment
Please, Sign In to add comment