Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #pragma once
- #include <algorithm>
- #include <cassert>
- #include <initializer_list>
- #include <stdexcept>
- #include <iterator>
- #include "array_ptr.h"
- const size_t XPANSION_MULTIPLIER = 2;
- template <typename Type>
- class SimpleVector {
- public:
- using Iterator = Type*;
- using ConstIterator = const Type*;
- SimpleVector(const SimpleVector& other) : items_(other.size_) {
- size_ = other.size_;
- capacity_ = other.capacity_;
- std::copy(other.begin(), other.end(), begin());
- }
- SimpleVector& operator=(const SimpleVector& rhs) {
- // Напишите тело конструктора самостоятельно
- if (this != &rhs) {
- SimpleVector dummy(rhs);
- swap(dummy);
- }
- return *this;
- }
- // Добавляет элемент в конец вектора
- // При нехватке места увеличивает вдвое вместимость вектора
- void PushBack(const Type& item) {
- if (size_ >= capacity_) {
- Resize(size_ + 1);
- items_[size_ - 1] = item;
- }
- else {
- items_[size_++] = item;
- }
- }
- // Вставляет значение value в позицию pos.
- // Возвращает итератор на вставленное значение
- // Если перед вставкой значения вектор был заполнен полностью,
- // вместимость вектора должна увеличиться вдвое, а для вектора вместимостью 0 стать равной 1
- Iterator Insert(ConstIterator pos, const Type& value) {
- if (size_ == 0u) {
- PushBack(value);
- return begin();
- }
- //auto it = Iterator(pos);
- //auto indx_int = std::distance(begin(), it);
- auto indx_int = std::distance(begin(), const_cast<Iterator>(pos));
- if (size_ >= capacity_) {
- Resize(size_ + 1);
- }
- std::copy_backward(begin() + indx_int, end() - 1, end());
- items_[indx_int] = value;
- return begin() + indx_int;
- }
- // "Удаляет" последний элемент вектора. Вектор не должен быть пустым
- void PopBack() noexcept {
- if (size_ > 0) --size_;
- }
- // Удаляет элемент вектора в указанной позиции
- Iterator Erase(ConstIterator pos) {
- auto it = Iterator(pos);
- std::move(it + 1, end(), it);
- --size_;
- return (it == end()) ? end() : it + 1;
- }
- // Обменивает значение с другим вектором
- void swap(SimpleVector& other) noexcept {
- items_.swap(other.items_);
- std::swap(size_, other.size_);
- std::swap(capacity_, other.capacity_);
- }
- SimpleVector() noexcept = default;
- // Создаёт вектор из size элементов, инициализированных значением по умолчанию
- explicit SimpleVector(size_t size) : size_(size), capacity_(size), items_(size) {
- std::fill(begin(), end(), Type());
- }
- // Создаёт вектор из size элементов, инициализированных значением value
- SimpleVector(size_t size, const Type& value) : size_(size), capacity_(size), items_(size) {
- std::fill(begin(), end(), value);
- }
- // Создаёт вектор из std::initializer_list
- SimpleVector(std::initializer_list<Type> init) : size_(init.size()), capacity_(init.size()), items_(init.size()) {
- std::copy(init.begin(), init.end(), begin());
- }
- // Возвращает количество элементов в массиве
- size_t GetSize() const noexcept {
- // Напишите тело самостоятельно
- return size_;
- }
- // Возвращает вместимость массива
- size_t GetCapacity() const noexcept {
- // Напишите тело самостоятельно
- return capacity_;
- }
- const ArrayPtr<Type>& GetItems() const noexcept {
- return items_;
- }
- // Сообщает, пустой ли массив
- bool IsEmpty() const noexcept {
- return size_ == 0u;
- }
- // Возвращает ссылку на элемент с индексом index
- Type& operator[](size_t index) noexcept {
- // Напишите тело самостоятельно
- return items_[index];
- }
- // Возвращает константную ссылку на элемент с индексом index
- const Type& operator[](size_t index) const noexcept {
- // Напишите тело самостоятельно
- return items_[index];
- }
- // Возвращает константную ссылку на элемент с индексом index
- // Выбрасывает исключение std::out_of_range, если index >= size
- Type& At(size_t index) {
- // Напишите тело самостоятельно
- if (index >= size_) {
- throw std::out_of_range("Out of range");
- }
- return items_[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 (const)");
- }
- return items_[index];
- }
- // Обнуляет размер массива, не изменяя его вместимость
- void Clear() noexcept {
- // Напишите тело самостоятельно
- size_ = 0u;
- }
- // Изменяет размер массива.
- // При увеличении размера новые элементы получают значение по умолчанию для типа Type
- void Resize(size_t new_size) {
- if (new_size <= capacity_) {
- if (new_size > size_) {
- std::fill(begin() + size_, begin() + new_size, Type());
- }
- }
- else {
- size_t newCapacity = std::max(new_size, capacity_ * XPANSION_MULTIPLIER);
- SimpleVector<Type> newItems(newCapacity);
- if (begin()) {
- std::copy(begin(), end(), newItems.begin());
- }
- swap(newItems);
- capacity_ = newCapacity;
- }
- size_ = new_size;
- }
- // Возвращает итератор на начало массива
- // Для пустого массива может быть равен (или не равен) nullptr
- Iterator begin() noexcept {
- // Напишите тело самостоятельно
- return items_.Get();
- }
- // Возвращает итератор на элемент, следующий за последним
- // Для пустого массива может быть равен (или не равен) nullptr
- Iterator end() noexcept {
- // Напишите тело самостоятельно
- return items_.Get() + size_;
- }
- // Возвращает константный итератор на начало массива
- // Для пустого массива может быть равен (или не равен) nullptr
- ConstIterator begin() const noexcept {
- // Напишите тело самостоятельно
- return items_.Get();
- }
- // Возвращает итератор на элемент, следующий за последним
- // Для пустого массива может быть равен (или не равен) nullptr
- ConstIterator end() const noexcept {
- // Напишите тело самостоятельно
- return items_.Get() + size_;
- }
- // Возвращает константный итератор на начало массива
- // Для пустого массива может быть равен (или не равен) nullptr
- ConstIterator cbegin() const noexcept {
- // Напишите тело самостоятельно
- return items_.Get();
- }
- // Возвращает итератор на элемент, следующий за последним
- // Для пустого массива может быть равен (или не равен) nullptr
- ConstIterator cend() const noexcept {
- // Напишите тело самостоятельно
- return items_.Get() + size_;
- }
- private:
- size_t size_ = 0;
- size_t capacity_ = 0;
- ArrayPtr<Type> items_;
- };
- template <typename Type>
- inline bool operator==(const SimpleVector<Type>& lhs, const SimpleVector<Type>& rhs) {
- return std::equal(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 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);
- }
- template <typename Type>
- std::ostream& operator<<(std::ostream& out, const SimpleVector<Type>& v) {
- // auto items = v.GetItems();
- auto size = v.GetSize();
- auto capacity = v.GetCapacity();
- out << "\nsize = " << size << ", " << "\n"
- << "capacity = " << capacity << "\n";
- out << "{ " << "\n";
- for (auto i = 0u; i < size; ++i) {
- out << "[" << i << "]" << "=" << v[i] << "\n";
- }
- /*
- for (auto item : v) {
- out << item << "\n";
- }
- */
- out << " }";
- return out;
- }
Advertisement
Add Comment
Please, Sign In to add comment