Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- main
- #include "simple_vector.h"
- // Tests
- #include "tests.h"
- int main() {
- Test1();
- return 0;
- }
- #########################################################################################
- simple_vector.h
- #pragma once
- #include <cassert>
- #include <initializer_list>
- #include "array_ptr.h"
- template <typename Type>
- class SimpleVector
- {
- public:
- using Iterator = Type*;
- using ConstIterator = const Type*;
- //По умолчанию.Создаёт пустой вектор с нулевой вместимостью.Не выделяет динамическую память и не выбрасывает исключений.
- SimpleVector() noexcept = default;
- // Создаёт вектор из size элементов, инициализированных значением по умолчанию
- // Параметризованный конструктор, создающий вектор заданного размера.
- // Элементы вектора инициализированы значением по умолчанию для типа Type.
- // Вектор должен иметь одинаковые размер и вместимость.Если размер нулевой, динамическая память для его
- // элементов выделяться не должна.
- explicit SimpleVector(size_t size_) :SimpleVector(size_, Type()) {
- // Напишите тело конструктора самостоятельно
- }
- // Создаёт вектор из size элементов, инициализированных значением value
- SimpleVector(size_t size, const Type& value) :ptr_(size) {
- // Напишите тело конструктора самостоятельно
- std::fill(ptr_.Get(), ptr_.Get() + size, value);
- size_ = size,
- capacity_ = size;
- }
- ~SimpleVector()
- {
- }
- //Создаёт вектор из std::initializer_list
- SimpleVector(std::initializer_list<Type> init) :ptr_(init.size())
- {
- // Напишите тело конструктора самостоятельно
- std::copy(init.begin(), init.end(), begin());
- size_ = init.size();
- capacity_ = size_;
- }
- // Возвращает количество элементов в массиве
- size_t GetSize() const noexcept {
- // Напишите тело самостоятельно
- return size_;
- }
- // Возвращает вместимость массива
- size_t GetCapacity() const noexcept {
- // Напишите тело самостоятельно
- return capacity_;
- }
- // Сообщает, пустой ли массив
- bool IsEmpty() const noexcept {
- if (size_ == 0)
- {
- return true;
- }
- return false;
- }
- // Возвращает ссылку на элемент с индексом index
- Type& operator[](size_t index) noexcept {
- // Напишите тело самостоятельно
- return ptr_.Get()[index];
- }
- // Возвращает константную ссылку на элемент с индексом index
- const Type& operator[](size_t index) const noexcept {
- // Напишите тело самостоятельно
- return ptr_.Get()[index];
- }
- // Возвращает константную ссылку на элемент с индексом index
- // Выбрасывает исключение std::out_of_range, если index >= size
- Type& At(size_t index) {
- // Напишите тело самостоятельно
- if (index >= size_)
- {
- throw std::out_of_range("out");
- }
- return ptr_.Get()[index];
- }
- // Возвращает константную ссылку на элемент с индексом index
- // Выбрасывает исключение std::out_of_range, если index >= size
- const Type& At(size_t index) const {
- // Напишите тело самостоятельно
- if (index >= size_)
- {
- throw std::out_of_range("out");
- }
- return ptr_.Get()[index];
- }
- // Обнуляет размер массива, не изменяя его вместимость
- void Clear() noexcept {
- // Напишите тело самостоятельно
- size_ = 0;
- }
- // Изменяет размер массива.
- // При увеличении размера новые элементы получают значение по умолчанию для типа Type
- /* В методе Resize отдельно обработайте три ситуации : новый размер меньше или равен текущему,
- новый размер не превышает его вместимости,
- новый размер превышает текущую вместимость вектора.
- Если при изменении размера массива новый размер вектора превышает его текущую вместимость,
- создайте новый массив с нужной вместимостью,
- скопируйте в него прежнее содержимое и
- заполните остальные элементы значением по умолчанию.
- Затем старый массив можно удалить и
- использовать копию.После этого не забудьте обновить размер и вместимость вектора.
- Если при увеличении размера массива новый размер вектора не превышает его вместимость,
- заполните добавленные элементы значением по умолчанию для типа Type.
- При уменьшении размера вектора просто уменьшите его размер.*/
- void Resize(size_t new_size) {
- // Напишите тело самостоятельно
- if (new_size <= size_ && new_size < capacity_)
- {
- size_ = new_size;
- }
- else if (new_size > size_ && new_size < capacity_)
- {
- //std::fill(begin() + size_ - 1, begin() + size_ + new_size, Type());
- std::fill(begin() + size_, begin() + new_size, Type());
- size_ = new_size;
- }
- else
- {
- ArrayPtr<Type> temp_(2 * new_size);//???? 2* new_size???
- auto it = std::copy(begin(), end(), temp_.Get());
- std::fill(it, temp_.Get() + new_size, Type());
- // void swap(ArrayPtr & other) noexcept
- temp_.swap(ptr_);
- size_ = new_size;
- capacity_ = std::max(2 * capacity_, new_size);
- }
- }
- // Возвращает итератор на начало массива
- // Для пустого массива может быть равен (или не равен) nullptr
- Iterator begin() noexcept {
- // Напишите тело самостоятельно
- return ptr_.Get();
- }
- // Возвращает итератор на элемент, следующий за последним
- // Для пустого массива может быть равен (или не равен) nullptr
- Iterator end() noexcept {
- // Напишите тело самостоятельно
- return ptr_.Get() + size_;
- }
- // Возвращает константный итератор на начало массива
- // Для пустого массива может быть равен (или не равен) nullptr
- ConstIterator begin() const noexcept {
- // Напишите тело самостоятельно
- return ptr_.Get();
- }
- // Возвращает итератор на элемент, следующий за последним
- // Для пустого массива может быть равен (или не равен) nullptr
- ConstIterator end() const noexcept {
- // Напишите тело самостоятельно
- return ptr_.Get() + size_;
- }
- /* Возвращает константный итератор на начало массива
- Для пустого массива может быть равен (или не равен) nullptr*/
- ConstIterator cbegin() const noexcept {
- /* Напишите тело самостоятельно*/
- return ptr_.Get();
- }
- /*Возвращает итератор на элемент, следующий за последним
- Для пустого массива может быть равен (или не равен) nullptr*/
- ConstIterator cend() const noexcept {
- /* Напишите тело самостоятельно*/
- return ptr_.Get() + size_;
- }
- private:
- ArrayPtr<Type> ptr_;
- size_t size_ = 0;
- size_t capacity_ = 0;
- };
- #########################################################################################
- array_ptr.h
- #pragma once
- #include <iostream>
- #include <algorithm>
- #include <cassert>
- #include <cstdlib>
- template <typename Type>
- class ArrayPtr {
- public:
- // Инициализирует ArrayPtr нулевым указателем
- ArrayPtr() = default;
- // Создаёт в куче массив из size элементов типа Type.
- // Если size == 0, поле raw_ptr_ должно быть равно nullptr
- explicit ArrayPtr(size_t size) {
- // Реализуйте конструктор самостоятельно
- if (size == 0)
- {
- // raw_ptr_ == nullptr;
- }
- else
- {
- raw_ptr_ = new Type[size];
- }
- }
- // Конструктор из сырого указателя, хранящего адрес массива в куче либо nullptr
- explicit ArrayPtr(Type* raw_ptr) noexcept {
- // Реализуйте конструктор самостоятельно
- raw_ptr_ = raw_ptr;
- }
- // Запрещаем копирование
- ArrayPtr(const ArrayPtr&) = delete;
- ~ArrayPtr() {
- // Напишите деструктор самостоятельно
- delete[] raw_ptr_;
- }
- // Запрещаем присваивание
- ArrayPtr& operator=(const ArrayPtr&) = delete;
- // Прекращает владением массивом в памяти, возвращает значение адреса массива
- // После вызова метода указатель на массив должен обнулиться
- [[nodiscard]] Type* Release() noexcept {
- // Заглушка. Реализуйте метод самостоятельно
- auto temp = raw_ptr_;
- //delete[] raw_ptr_;
- raw_ptr_ = nullptr;
- return temp;
- }
- // Возвращает ссылку на элемент массива с индексом index
- Type& operator[](size_t index) noexcept {
- // Реализуйте операцию самостоятельно
- return raw_ptr_[index];
- }
- // Возвращает константную ссылку на элемент массива с индексом index
- const Type& operator[](size_t index) const noexcept {
- // Реализуйте операцию самостоятельно
- return raw_ptr_[index];
- }
- // Возвращает true, если указатель ненулевой, и false в противном случае
- explicit operator bool() const {
- // Заглушка. Реализуйте операцию самостоятельно
- if (raw_ptr_ == nullptr)
- {
- return false;
- }
- return true;
- }
- // Возвращает значение сырого указателя, хранящего адрес начала массива
- Type* Get() const noexcept {
- // Заглушка. Реализуйте метод самостоятельно
- return raw_ptr_;
- }
- // Обменивается значениям указателя на массив с объектом other
- void swap(ArrayPtr& other) noexcept
- {
- // Реализуйте метод самостоятельно
- std::swap(raw_ptr_, other.raw_ptr_);
- }
- private:
- Type* raw_ptr_ = nullptr;
- };
- #########################################################################################
- tests.h
- #pragma once
- #include <cassert>
- #include <stdexcept>
- // У функции, объявленной со спецификатором inline, может быть несколько
- // идентичных определений в разных единицах трансляции.
- // Обычно inline помечают функции, чьё тело находится в заголовочном файле,
- // чтобы при подключении этого файла из разных единиц трансляции не возникало ошибок компоновки
- inline void Test1() {
- // Инициализация конструктором по умолчанию
- {
- SimpleVector<int> v;
- assert(v.GetSize() == 0u);
- assert(v.IsEmpty());
- assert(v.GetCapacity() == 0u);
- }
- // Инициализация вектора указанного размера
- {
- SimpleVector<int> v(5);
- assert(v.GetSize() == 5u);
- assert(v.GetCapacity() == 5u);
- assert(!v.IsEmpty());
- for (size_t i = 0; i < v.GetSize(); ++i) {
- assert(v[i] == 0);
- }
- }
- // Инициализация вектора, заполненного заданным значением
- {
- SimpleVector<int> v(3, 42);
- assert(v.GetSize() == 3);
- assert(v.GetCapacity() == 3);
- for (size_t i = 0; i < v.GetSize(); ++i) {
- assert(v[i] == 42);
- }
- }
- // Инициализация вектора при помощи initializer_list
- {
- SimpleVector<int> v{1, 2, 3};
- assert(v.GetSize() == 3);
- assert(v.GetCapacity() == 3);
- assert(v[2] == 3);
- }
- // Доступ к элементам при помощи At
- {
- SimpleVector<int> v(3);
- assert(&v.At(2) == &v[2]);
- try {
- v.At(3);
- assert(false); // Ожидается выбрасывание исключения
- } catch (const std::out_of_range&) {
- } catch (...) {
- assert(false); // Не ожидается исключение, отличное от out_of_range
- }
- }
- // Очистка вектора
- {
- SimpleVector<int> v(10);
- const size_t old_capacity = v.GetCapacity();
- v.Clear();
- assert(v.GetSize() == 0);
- assert(v.GetCapacity() == old_capacity);
- }
- // Изменение размера
- {
- SimpleVector<int> v(3);
- v[2] = 17;
- v.Resize(7);
- assert(v.GetSize() == 7);
- assert(v.GetCapacity() >= v.GetSize());
- assert(v[2] == 17);
- assert(v[3] == 0);
- }
- {
- SimpleVector<int> v(3);
- v[0] = 42;
- v[1] = 55;
- const size_t old_capacity = v.GetCapacity();
- v.Resize(2);
- assert(v.GetSize() == 2);
- assert(v.GetCapacity() == old_capacity);
- assert(v[0] == 42);
- assert(v[1] == 55);
- }
- {
- const size_t old_size = 3;
- SimpleVector<int> v(3);
- v.Resize(old_size + 5);
- v[3] = 42;
- v.Resize(old_size);
- v.Resize(old_size + 2);
- assert(v[3] == 0);
- }
- // Итерирование по SimpleVector
- {
- // Пустой вектор
- {
- SimpleVector<int> v;
- assert(v.begin() == nullptr);
- assert(v.end() == nullptr);
- }
- // Непустой вектор
- {
- SimpleVector<int> v(10, 42);
- assert(v.begin());
- assert(*v.begin() == 42);
- assert(v.end() == v.begin() + v.GetSize());
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement