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