Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #pragma once
- // #include <cassert>
- #include <initializer_list>
- #include <stdexcept>
- // using namespace std;
- 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) {
- items_ = new Type[size];
- std::fill(begin(), end(), value);
- }
- // Создаёт вектор из std::initializer_list
- SimpleVector(std::initializer_list<Type> init)
- : size_(init.size()), capacity_(init.size()) {
- items_ = new Type[init.size()];
- std::copy(init.begin(), init.end(), begin());
- }
- SimpleVector(const SimpleVector& other) noexcept
- {
- // SimpleVector<Type> temp(other.size_);
- // std::copy(other.begin(), other.end(), temp.begin());
- SimpleVector temp;
- temp.capacity_ = other.capacity_;
- temp.items_ = new Type[other.size_];
- for (size_t i=0; i<other.size_; ++i)
- {
- temp[i] = other[i];
- ++temp.size_;
- }
- swap(temp);
- }
- SimpleVector& operator=(const SimpleVector& rhs) {
- if (this != &rhs) {
- SimpleVector temp(rhs);
- swap(temp);
- }
- return *this;
- }
- ~SimpleVector() {delete[] items_;}
- // Возвращает количество элементов в массиве
- size_t GetSize() const noexcept {return size_;}
- // Возвращает вместимость массива
- size_t GetCapacity() const noexcept {return capacity_;}
- // Сообщает, пустой ли массив
- bool IsEmpty() const noexcept {return !GetSize();}
- // Возвращает ссылку на элемент с индексом 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");};
- return items_[index];
- }
- // Обнуляет размер массива, не изменяя его вместимость
- void Clear() noexcept {size_ = 0;}
- // Изменяет размер массива.
- // При увеличении размера новые элементы получают значение по умолчанию для типа Type
- void Resize(size_t new_size) {
- if (new_size > capacity_) {
- size_t new_capacity = new_size > (2 * capacity_)? new_size: 2 * capacity_;
- Type* new_items = new Type[new_size]();
- std::copy(begin(), end(), new_items);
- delete[] items_;
- items_ = new_items;
- capacity_ = new_capacity;
- } else if (new_size > size_) {
- std::fill(begin() + size_, begin() + new_size, Type{});
- }
- size_ = new_size;
- }
- // Возвращает итератор на начало массива
- // Для пустого массива может быть равен (или не равен) nullptr
- Iterator begin() noexcept {return items_;}
- // Возвращает итератор на элемент, следующий за последним
- // Для пустого массива может быть равен (или не равен) nullptr
- Iterator end() noexcept {return items_ + size_;}
- // Возвращает константный итератор на начало массива
- // Для пустого массива может быть равен (или не равен) nullptr
- ConstIterator begin() const noexcept {return items_;}
- // Возвращает итератор на элемент, следующий за последним
- // Для пустого массива может быть равен (или не равен) nullptr
- ConstIterator end() const noexcept {return items_ + size_;}
- // Возвращает константный итератор на начало массива
- // Для пустого массива может быть равен (или не равен) nullptr
- ConstIterator cbegin() const noexcept {return items_;}
- // Возвращает итератор на элемент, следующий за последним
- // Для пустого массива может быть равен (или не равен) nullptr
- ConstIterator cend() const noexcept {return items_ + size_;}
- // Добавляет элемент в конец вектора
- // При нехватке места увеличивает вдвое вместимость вектора
- void PushBack(const Type& item) {
- if (size_ == capacity_) {Resize(size_ * 2);}
- items_[size_] = item;
- }
- // Вставляет значение value в позицию pos.
- // Возвращает итератор на вставленное значение
- // Если перед вставкой значения вектор был заполнен полностью,
- // вместимость вектора должна увеличиться вдвое, а для вектора вместимостью 0 стать равной 1
- Iterator Insert(ConstIterator pos, const Type& value) {
- // if (!capacity_) {Resize(1);}
- // else if (size_ == capacity_) {Resize(size_ * 2);}
- if (size_ == capacity_ || !capacity_) {Resize(capacity_ + 1);}
- std::copy_backward(Iterator(pos), end(), Iterator(pos) + 1);
- *Iterator(pos) = value;
- return Iterator(pos);
- }
- // "Удаляет" последний элемент вектора. Вектор не должен быть пустым
- void PopBack() noexcept {
- if (size_) {--size_;}
- }
- // Удаляет элемент вектора в указанной позиции
- Iterator Erase(ConstIterator pos) {
- std::copy(Iterator(pos), end(), Iterator(pos) - 1);
- --size_;
- return Iterator(pos);
- }
- // Обменивает значение с другим вектором
- void swap(SimpleVector& other) noexcept {
- std::swap(items_, other.items_);
- std::swap(size_, other.size_);
- std::swap(capacity_, other.capacity_);
- }
- private:
- Type* items_ = nullptr;
- 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 lhs<rhs || lhs==rhs;
- }
- // TODO
- // Реализуйте оператор> как return rhs < lhs;. Потому что !(std::lexicographical_compare(...) включает не все варианты.
- 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 !(lhs<rhs);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement