Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #pragma once
- #include <cassert>
- #include <initializer_list>
- #include <stdexcept>
- #include <algorithm>
- #include <iostream>
- template <typename Type>
- class SimpleVector
- {
- public:
- using Iterator = Type*;
- using ConstIterator = const Type*;
- SimpleVector() noexcept = default;
- // Создаёт вектор из size элементов, инициализированных значением по умолчанию
- explicit SimpleVector(size_t size):SimpleVector(size, Type())
- {}
- // Создаёт вектор из size элементов, инициализированных значением value
- SimpleVector(size_t size, const Type& value)
- :size_(size)
- ,capacity_(size)
- {
- // Напишите тело конструктора самостоятельно
- if (size)
- {
- simple_vector_ = new Type[size];
- std::fill(begin(), end(), value);
- }
- }
- SimpleVector(const SimpleVector& other)
- :size_(other.size_)
- ,capacity_(other.capacity_)
- {
- Assign(other.begin(), other.end());
- }
- // Создаёт вектор из std::initializer_list
- SimpleVector(std::initializer_list<Type> init)
- :size_(init.size())
- ,capacity_(init.size())
- {
- // Напишите тело конструктора самостоятельно
- Assign(init.begin(), init.end());
- }
- ~SimpleVector()
- {
- delete[] simple_vector_;
- }
- // Возвращает количество элементов в массиве
- 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_ - 1);
- return simple_vector_[index];
- }
- // Возвращает константную ссылку на элемент с индексом index
- const Type& operator[](size_t index) const noexcept
- {
- // Напишите тело самостоятельно
- //assert(index < size_ - 1);
- return simple_vector_[index];
- }
- // Возвращает константную ссылку на элемент с индексом index
- // Выбрасывает исключение std::out_of_range, если index >= size
- Type& At(size_t index)
- {
- // Напишите тело самостоятельно
- if (index >= size_)
- {
- throw std::out_of_range("simple_vector subscript 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("simple_vector subscript out of range!");
- }
- else
- {
- return simple_vector_[index];
- }
- }
- // Обнуляет размер массива, не изменяя его вместимость
- void Clear() noexcept
- {
- // Напишите тело самостоятельно
- size_ = 0;
- }
- // Изменяет размер массива.
- // При увеличении размера новые элементы получают значение по умолчанию для типа Type
- void Resize(size_t new_size)
- {
- if(new_size > size_)
- {
- if(new_size > capacity_)
- {
- capacity_ = new_size;
- Type* new_simple_vector = new Type[capacity_];
- std::copy(begin(), end(), new_simple_vector);
- delete[] simple_vector_;
- simple_vector_ = new_simple_vector;
- }
- std::fill(simple_vector_ + size_, simple_vector_ + capacity_, Type());
- }
- size_ = new_size;
- }
- SimpleVector& operator=(const SimpleVector& rhs)
- {
- if(&rhs != this)
- {
- auto rhs_copy = rhs;
- swap(rhs_copy);
- }
- return *this;
- }
- void PushBack(const Type& value)
- {
- Insert(end(), value);
- }
- Iterator Insert(ConstIterator pos, const Type& value)
- {
- if(capacity_ == size_)
- {
- capacity_ = capacity_ ? capacity_ * 2 : 1;
- Type* new_simple_vector = new Type[capacity_];
- Iterator new_element = std::copy(begin(), Iterator(pos), new_simple_vector);
- *new_element = value;
- std::copy(Iterator(pos), end(), std::next(new_element));
- delete[] simple_vector_;
- simple_vector_ = new_simple_vector;
- }
- else
- {
- std::copy_backward(Iterator(pos), end(), std::next(Iterator(pos)));
- *(Iterator(pos)) = value;
- }
- ++size_;
- return Iterator(pos);
- }
- void PopBack() noexcept
- {
- assert(size_ != 0);
- --size_;
- }
- Iterator Erase(ConstIterator pos)
- {
- assert(size_ != 0);
- std::copy(std::next(Iterator(pos)), end(), Iterator(pos));
- --size_;
- return Iterator(pos);
- }
- void swap(SimpleVector& other) noexcept
- {
- std::swap(simple_vector_, other.simple_vector_);
- std::swap(size_, other.size_);
- std::swap(capacity_, other.capacity_);
- }
- // Возвращает итератор на начало массива
- // Для пустого массива может быть равен (или не равен) nullptr
- Iterator begin() noexcept
- {
- // Напишите тело самостоятельно
- return simple_vector_;
- }
- // Возвращает итератор на элемент, следующий за последним
- // Для пустого массива может быть равен (или не равен) nullptr
- Iterator end() noexcept
- {
- // Напишите тело самостоятельно
- return simple_vector_ + size_;
- }
- // Возвращает константный итератор на начало массива
- // Для пустого массива может быть равен (или не равен) nullptr
- ConstIterator begin() const noexcept
- {
- // Напишите тело самостоятельно
- return simple_vector_;
- }
- // Возвращает итератор на элемент, следующий за последним
- // Для пустого массива может быть равен (или не равен) nullptr
- ConstIterator end() const noexcept
- {
- // Напишите тело самостоятельно
- return simple_vector_ + size_;
- }
- // Возвращает константный итератор на начало массива
- // Для пустого массива может быть равен (или не равен) nullptr
- ConstIterator cbegin() const noexcept
- {
- // Напишите тело самостоятельно
- return begin();
- }
- // Возвращает итератор на элемент, следующий за последним
- // Для пустого массива может быть равен (или не равен) nullptr
- ConstIterator cend() const noexcept
- {
- // Напишите тело самостоятельно
- return end();
- }
- private:
- template <typename InputIterator>
- void Assign(InputIterator range_begin, InputIterator range_end)
- {
- simple_vector_ = new Type[size_];
- std::copy(range_begin, range_end, begin());
- }
- Type* simple_vector_ = nullptr;
- size_t size_ = 0u;
- size_t capacity_ = 0u;
- };
- 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);
- }
- 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());
- }
- }
- }
- inline void Test2() {
- // PushBack
- {
- SimpleVector<int> v(1);
- v.PushBack(42);
- assert(v.GetSize() == 2);
- assert(v.GetCapacity() >= v.GetSize());
- assert(v[0] == 0);
- assert(v[1] == 42);
- }
- // Если хватает места, PushBack не увеличивает Capacity
- {
- SimpleVector<int> v(2);
- v.Resize(1);
- const size_t old_capacity = v.GetCapacity();
- v.PushBack(123);
- assert(v.GetSize() == 2);
- assert(v.GetCapacity() == old_capacity);
- }
- // PopBack
- {
- SimpleVector<int> v{ 0, 1, 2, 3 };
- const size_t old_capacity = v.GetCapacity();
- const auto old_begin = v.begin();
- v.PopBack();
- assert(v.GetCapacity() == old_capacity);
- assert(v.begin() == old_begin);
- assert((v == SimpleVector<int>{0, 1, 2}));
- }
- // Конструктор копирования
- {
- SimpleVector<int> numbers{ 1, 2 };
- auto numbers_copy(numbers);
- assert(&numbers_copy[0] != &numbers[0]);
- assert(numbers_copy.GetSize() == numbers.GetSize());
- for (size_t i = 0; i < numbers.GetSize(); ++i) {
- assert(numbers_copy[i] == numbers[i]);
- assert(&numbers_copy[i] != &numbers[i]);
- }
- }
- // Сравнение
- {
- assert((SimpleVector{ 1, 2, 3 } == SimpleVector{ 1, 2, 3 }));
- assert((SimpleVector{ 1, 2, 3 } != SimpleVector{ 1, 2, 2 }));
- assert((SimpleVector{ 1, 2, 3 } < SimpleVector{ 1, 2, 3, 1 }));
- assert((SimpleVector{ 1, 2, 3 } > SimpleVector{ 1, 2, 2, 1 }));
- assert((SimpleVector{ 1, 2, 3 } >= SimpleVector{ 1, 2, 3 }));
- assert((SimpleVector{ 1, 2, 4 } >= SimpleVector{ 1, 2, 3 }));
- assert((SimpleVector{ 1, 2, 3 } <= SimpleVector{ 1, 2, 3 }));
- assert((SimpleVector{ 1, 2, 3 } <= SimpleVector{ 1, 2, 4 }));
- }
- // Обмен значений векторов
- {
- SimpleVector<int> v1{ 42, 666 };
- SimpleVector<int> v2;
- v2.PushBack(0);
- v2.PushBack(1);
- v2.PushBack(2);
- const int* const begin1 = &v1[0];
- const int* const begin2 = &v2[0];
- const size_t capacity1 = v1.GetCapacity();
- const size_t capacity2 = v2.GetCapacity();
- const size_t size1 = v1.GetSize();
- const size_t size2 = v2.GetSize();
- static_assert(noexcept(v1.swap(v2)));
- v1.swap(v2);
- assert(&v2[0] == begin1);
- assert(&v1[0] == begin2);
- assert(v1.GetSize() == size2);
- assert(v2.GetSize() == size1);
- assert(v1.GetCapacity() == capacity2);
- assert(v2.GetCapacity() == capacity1);
- }
- // Присваивание
- {
- SimpleVector<int> src_vector{ 1, 2, 3, 4 };
- SimpleVector<int> dst_vector{ 1, 2, 3, 4, 5, 6 };
- dst_vector = src_vector;
- assert(dst_vector == src_vector);
- }
- // Вставка элементов
- {
- SimpleVector<int> v{ 1, 2, 3, 4 };
- v.Insert(v.begin() + 2, 42);
- assert((v == SimpleVector<int>{1, 2, 42, 3, 4}));
- }
- // Удаление элементов
- {
- SimpleVector<int> v{ 1, 2, 3, 4 };
- v.Erase(v.cbegin() + 2);
- assert((v == SimpleVector<int>{1, 2, 4}));
- }
- }
- int main()
- {
- Test1();
- Test2();
- SimpleVector<int> sv;
- for(int i = 0; i < 10; ++i)
- {
- sv.PushBack(i);
- }
- //Тут выводит 1 (True), а в 18 тесте не проходит это решение :-/
- std::cout << (sv.Insert(sv.end(), 10) == sv.end() - 1) << '\n';
- std::cout << *(sv.end() - 1);
- }
Advertisement
Add Comment
Please, Sign In to add comment