Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #pragma once
- #include <iostream>
- #include <cassert>
- #include <initializer_list>
- #include <algorithm>
- #include "array_ptr.h"
- #include <numeric>
- #include <iterator>
- #include <stdexcept>
- #include <cmath>
- #include <utility>
- struct ReserveProxyObj {
- size_t capacity_to_reserve_;
- ReserveProxyObj(size_t capacity_to_reserve)
- : capacity_to_reserve_(capacity_to_reserve) {}
- };
- ReserveProxyObj Reserve(size_t capacity_to_reserve) {
- return ReserveProxyObj(capacity_to_reserve);
- }
- template <typename Type>
- class SimpleVector {
- public:
- using Iterator = Type*;
- using ConstIterator = const Type*;
- SimpleVector() noexcept = default;
- SimpleVector(ReserveProxyObj obj) {
- Reserve(obj.capacity_to_reserve_);
- }
- // Создаёт вектор из size элементов, инициализированных значением по умолчанию
- explicit SimpleVector(size_t size) {
- ArrayPtr<Type> simple_vector_copy(size);
- simple_vector_copy.swap(simple_vector_);
- size_ = size;
- capacity_ = size;
- //std::fill(begin(), end(), Type{});
- }
- // Создаёт вектор из size элементов, инициализированных значением value
- SimpleVector(size_t size, const Type& value) {
- ArrayPtr<Type> simple_vector_copy(size);
- std::fill(simple_vector_copy.Get(), simple_vector_copy.Get() + size, value);
- simple_vector_.swap(simple_vector_copy);
- size_ = size;
- capacity_ = size;
- }
- // Создаёт вектор из std::initializer_list
- SimpleVector(std::initializer_list<Type> init) {
- ArrayPtr<Type> simple_vector_copy(init.size());
- std::copy(std::make_move_iterator(init.begin()), std::make_move_iterator(init.end()),
- simple_vector_copy.Get());
- simple_vector_.swap(simple_vector_copy);
- size_ = init.size();
- capacity_ = init.size();
- }
- // Конструктор копирования
- SimpleVector(const SimpleVector& other) {
- SimpleVector<Type> simple_vector_copy(other.size_);
- std::copy(other.begin(), other.end(),
- simple_vector_copy.begin());
- simple_vector_copy.size_ = other.size_;
- simple_vector_copy.capacity_ = other.capacity_;
- swap(simple_vector_copy);
- }
- // конструктор перемещения
- SimpleVector(SimpleVector&& other) {
- simple_vector_ = std::move(other.simple_vector_);
- size_ = std::move(other.size_);
- capacity_ = std::move(other.capacity_);
- other.size_ = 0;
- other.capacity_ = 0;
- }
- // Оператор присваивания
- SimpleVector& operator=(const SimpleVector& rhs) {
- if (simple_vector_.Get() != rhs.simple_vector_.Get()) {
- ArrayPtr<Type> simple_vector_copy(rhs.size_);
- std::copy(std::make_move_iterator(rhs.simple_vector_.Get()), std::make_move_iterator(rhs.simple_vector_.Get() + rhs.size_),
- simple_vector_copy.Get());
- simple_vector_.swap(simple_vector_copy);
- size_ = std::move(rhs.size_);
- capacity_ = std::move(rhs.capacity_);
- }
- return *this;
- }
- // Добавляет элемент в конец вектора
- // При нехватке места увеличивает вдвое вместимость вектора
- void PushBack(Type item) {
- if (size_ < capacity_) {
- simple_vector_[size_] = std::move(item);
- ++size_;
- }
- else {
- SimpleVector<Type> simple_vector_copy(std::max(size_ * 2, size_t(1)));
- std::copy(std::make_move_iterator(begin()), std::make_move_iterator(end()),
- simple_vector_copy.begin());
- simple_vector_copy[size_] = std::move(item);
- simple_vector_copy.size_ = size_ + 1;
- swap(simple_vector_copy);
- }
- }
- // Вставляет значение value в позицию pos.
- // Возвращает итератор на вставленное значение
- // Если перед вставкой значения вектор был заполнен полностью,
- // вместимость вектора должна увеличиться вдвое, а для вектора вместимостью 0 стать равной 1
- Iterator Insert(ConstIterator pos, Type value) {
- size_t index = size_t(pos - begin());
- if (size_ < capacity_) {
- std::copy_backward(std::make_move_iterator(begin() + index), std::make_move_iterator(end()), end() + 1);
- simple_vector_[index] = std::move(value);
- ++size_;
- }
- else {
- SimpleVector<Type> simple_vector_copy(std::max(size_ * 2, size_t(1)));
- std::copy(std::make_move_iterator(begin()), std::make_move_iterator(begin() + index), simple_vector_copy.begin());
- simple_vector_copy[index] = std::move(value);
- std::copy(std::make_move_iterator(begin() + index), std::make_move_iterator(end()), simple_vector_copy.begin() + index + 1);
- simple_vector_copy.size_ = size_ + 1;
- swap(simple_vector_copy);
- }
- return begin() + index;
- }
- // "Удаляет" последний элемент вектора. Вектор не должен быть пустым
- void PopBack() noexcept {
- if (size_ > 0) {
- --size_;
- }
- }
- // Удаляет элемент вектора в указанной позиции
- Iterator Erase(ConstIterator pos) {
- size_t index = size_t(pos - begin());
- std::copy(std::make_move_iterator(begin() + index + 1), std::make_move_iterator(end()), begin() + index);
- --size_;
- return begin() + index;
- }
- // Обменивает значение с другим вектором
- void swap(SimpleVector& other) noexcept {
- simple_vector_.swap(other.simple_vector_);
- 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 {
- assert(index < size_);
- return simple_vector_[index];
- }
- // Возвращает константную ссылку на элемент с индексом index
- const Type& operator[](size_t index) const noexcept {
- assert(index < size_);
- return simple_vector_[index];
- }
- // Возвращает константную ссылку на элемент с индексом index
- // Выбрасывает исключение std::out_of_range, если index >= size
- Type& At(size_t index) {
- if (index >= size_) {
- throw std::out_of_range("out_of_range");
- }
- else {
- return simple_vector_[index];
- }
- }
- // Возвращает константную ссылку на элемент с индексом index
- // Выбрасывает исключение std::out_of_range, если index >= size
- const Type& At(size_t index) const {
- if (index >= size_) {
- throw std::out_of_range("out_of_range");
- }
- else {
- return simple_vector_[index];
- }
- }
- // Обнуляет размер массива, не изменяя его вместимость
- void Clear() noexcept {
- size_ = 0;
- }
- void Reserve(size_t new_capacity) {
- if (new_capacity > capacity_) {
- SimpleVector<Type> simple_vector_copy(new_capacity);
- std::copy(begin(), end(), simple_vector_copy.begin());
- simple_vector_copy.size_ = size_;
- swap(simple_vector_copy);
- }
- }
- // Изменяет размер массива.
- // При увеличении размера новые элементы получают значение по умолчанию для типа Type
- void Resize(size_t new_size) {
- if (new_size <= size_) {
- size_ = new_size;
- }
- else if (new_size <= capacity_) {
- std::fill(simple_vector_.Get(), simple_vector_.Get() + new_size, Type{});
- /*auto first = simple_vector_.Get();
- auto last = simple_vector_.Get() + new_size;
- for (; first != last; ++first)
- *first = Type{};*/
- size_ = new_size;
- }
- else {
- SimpleVector<Type> simple_vector_copy_(std::max(capacity_ * 2, new_size));
- std::copy(begin(), end(), simple_vector_copy_.begin());
- swap(simple_vector_copy_);
- }
- }
- // Возвращает итератор на начало массива
- // Для пустого массива может быть равен (или не равен) nullptr
- Iterator begin() noexcept {
- return simple_vector_.Get();
- }
- // Возвращает итератор на элемент, следующий за последним
- // Для пустого массива может быть равен (или не равен) nullptr
- Iterator end() noexcept {
- return simple_vector_.Get() + size_;
- }
- // Возвращает константный итератор на начало массива
- // Для пустого массива может быть равен (или не равен) nullptr
- ConstIterator begin() const noexcept {
- return simple_vector_.Get();
- }
- // Возвращает итератор на элемент, следующий за последним
- // Для пустого массива может быть равен (или не равен) nullptr
- ConstIterator end() const noexcept {
- return simple_vector_.Get() + size_;
- }
- // Возвращает константный итератор на начало массива
- // Для пустого массива может быть равен (или не равен) nullptr
- ConstIterator cbegin() const noexcept {
- return simple_vector_.Get();
- }
- // Возвращает итератор на элемент, следующий за последним
- // Для пустого массива может быть равен (или не равен) nullptr
- ConstIterator cend() const noexcept {
- return simple_vector_.Get() + size_;
- }
- private:
- ArrayPtr<Type> simple_vector_;
- size_t size_ = 0;
- size_t capacity_ = 0;
- };
- template <typename Type>
- inline bool operator==(const SimpleVector<Type>& lhs, const SimpleVector<Type>& rhs) {
- 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 !(rhs < lhs);
- }
- 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
Advertisement