Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #pragma once
- #include <iterator>
- #include <assert.h>
- #include <memory>
- #include <new>
- #include <type_traits>
- template <class T>
- class VectorSafe;
- template <class T, int DIR>
- class VectorIter;
- template<class T> class Vector {
- std::allocator<T> _alloc = std::allocator<T>();
- T* data_ = nullptr;
- size_t size_;
- size_t capacity_;
- public:
- using iterator = VectorIter<T, 1>;
- using const_iterator = VectorIter<const T, 1>;
- using reverse_iterator = VectorIter<T, -1>;
- using const_reverse_iterator = VectorIter<const T, -1>;
- //basic
- Vector()
- {
- try {
- data_ = _alloc.allocate(1);
- size_ = 0;
- capacity_ = 1;
- Invariant();
- }
- catch (std::bad_alloc& e)
- {
- data_ = nullptr;
- size_ = 0;
- capacity_ = 0;
- throw;
- }
- }
- ~Vector()
- {
- for (int i = 0; i < size_; i++)
- {
- data_[i].~T();
- }
- _alloc.deallocate(data_, capacity_);
- }
- //copy construktor // basic
- Vector(const Vector& other) :Vector(other.size() + 1, other.begin(), other.end()) {}
- //move construktor
- Vector(Vector&& other)
- {
- this->size_ = 0;
- this->capacity_ = 0;
- this->data_ = nullptr;
- *this = std::move(other);
- Invariant();
- }
- template<class tIter>
- Vector(size_t newCapacity,
- const tIter& begin,
- const tIter& end)
- {
- data_ = _alloc.allocate(newCapacity);
- try
- {
- size_ = 0;
- capacity_ = newCapacity;
- tIter ptrBegin = begin;
- tIter ptrEnd = end;
- T* ptrData = data_;
- for (ptrBegin; ptrBegin != ptrEnd; ptrBegin++)
- {
- new (ptrData) T(*ptrBegin);
- size_++;
- ptrData++;
- }
- }
- catch (...)
- {
- this->~Vector();
- size_ = 0;
- capacity_ = 0;
- throw;
- }
- }
- //basic
- Vector(const char* other) : Vector(std::strlen(other), other, other + std::strlen(other)) {}
- //basic
- //kopiera värden
- Vector& operator=(const Vector& other)
- Vector<T> temp(other);
- swap(*this, temp);
- }
- }
- Vector& operator=(Vector&& other)
- {
- if (this->data_ == other.data())
- {
- return *this;
- }
- else
- {
- this->~Vector();
- this->size_ = other.size();
- this->capacity_ = other.capacity();
- this->data_ = other.data();
- other.data_ = nullptr;
- other.size_ = 0;
- other.capacity_ = 0;
- return *this;
- }
- }
- T& operator[](size_t i)
- {
- return data_[i];
- }
- //basic
- T& at(size_t i)
- {
- if (i <= size_ - 1)
- {
- return data_[i];
- }
- else
- {
- throw std::out_of_range("utanför range");
- }
- }
- //basic/
- const T& operator[](size_t i) const
- {
- return data_[i];
- }
- //basic
- const T& at(size_t i) const
- {
- if (i <= size_)
- {
- return data_[i];
- }
- else
- {
- throw std::out_of_range("hej");
- }
- }
- T* data() noexcept
- {
- return data_;
- }
- const T* data() const noexcept
- {
- return data_;
- }
- size_t size() const noexcept
- {
- return size_;
- }
- //basic
- void reserve(size_t n)
- {
- if (n > this->capacity_)
- {
- Vector new_vec(n, data_, data_ + size_);
- *this = (std::move(new_vec));
- }
- }
- size_t capacity() const noexcept
- {
- return capacity_;
- }
- //basic
- void shrink_to_fit()
- {
- if (this->size() != this->capacity()) {
- Vector new_vec(size_, data_, data_ + size_);
- *this = (std::move(new_vec));
- }
- }
- //basic
- void push_back(const T& value)
- {
- try {
- if (this->size() + 1 <= this->capacity())
- {
- new (data_ + size_) T(value);
- this->size_++;
- }
- else
- {
- this->reserve(capacity_ * 2);
- this->push_back(value);
- }
- }
- catch (...)
- {
- data_[size_].~T();
- throw;
- }
- }
- // value is moved into the new element.
- //basic
- void push_back(T&& value)
- {
- try {
- if (this->size() + 1 <= this->capacity())
- {
- new (data_ + size_) T(std::move(value));
- this->size_++;
- }
- else
- {
- this->reserve(capacity_ * 2);
- this->push_back(value);
- }
- }
- catch (...)
- {
- data_[size_].~T();
- throw;
- }
- }
- void resize(size_t n)
- {
- if (n > size_)
- {
- for (size_t i = size_; i != n; ++i)
- {
- this->push_back(T());
- }
- }
- if (n < size_)
- {
- for (size_t i = size_; i == n; --i)
- {
- data_[i].~T();
- }
- size_ = n;
- }
- }
- iterator begin()
- {
- return iterator(data_);
- }
- const_iterator begin() const
- {
- return const_iterator(data_);
- }
- iterator end()
- {
- return iterator(data_ + size_);
- }
- const_iterator end() const
- {
- return const_iterator(data_ + size_);
- }
- const_iterator cbegin() const
- {
- return const_iterator(data_);
- }
- const_iterator cend() const
- {
- return const_iterator(data_ + size_);
- }
- reverse_iterator rbegin()
- {
- return reverse_iterator(data_ + size_ - 1);
- }
- const_reverse_iterator rbegin() const
- {
- return const_reverse_iterator(data_ + size_ - 1);
- }
- reverse_iterator rend()
- {
- return reverse_iterator(data_ - 1);
- }
- const_reverse_iterator rend() const
- {
- return const_reverse_iterator(data_ - 1);
- }
- const_reverse_iterator crbegin() const
- {
- return const_reverse_iterator(data_ + size_ - 1);
- }
- const_reverse_iterator crend() const
- {
- return const_reverse_iterator(data_ - 1);
- }
- friend bool operator==(const Vector& lhs, const Vector& other)
- {
- if (lhs.size() != other.size()) {
- return false;
- }
- else {
- for (size_t i = 0; i < lhs.size(); i++) {
- if (lhs[i] != other[i]) {
- return false;
- }
- }
- return true;
- }
- }
- friend bool operator!=(const Vector& lhs, const Vector& other)
- {
- return !(lhs == other);
- }
- friend bool operator<(const Vector& lhs, const Vector& other)
- {
- size_t size = 0;
- if (lhs.size() > other.size())
- {
- size = lhs.size();
- }
- else
- {
- size = other.size();
- }
- for (size_t i = 0; i < size; i++)
- {
- if (lhs[i] != other[i])
- {
- if (lhs[i] < other[i])
- {
- return true;
- }
- else
- {
- return false;
- }
- }
- }
- return false;
- }
- friend bool operator>(const Vector& lhs, const Vector& other)
- {
- return!(lhs < other);
- }
- friend bool operator<=(const Vector& lhs, const Vector& other)
- {
- size_t size = 0;
- if (lhs.size() > other.size())
- {
- size = lhs.size();
- }
- else
- {
- size = other.size();
- }
- for (size_t i = 0; i < size; i++)
- {
- if (lhs[i] != other[i])
- {
- if (lhs[i] < other[i])
- {
- return true;
- }
- else
- {
- return false;
- }
- }
- }
- if (lhs.size() == other.size())
- {
- return true;
- }
- else
- {
- return false;
- }
- }
- friend bool operator>=(const Vector& lhs, const Vector& other)
- {
- return!(lhs <= other);
- }
- template <class T> void swap(Vector<T>& lhs, Vector<T>& rhs)
- {
- Vector<T> temp = (std::move(lhs));
- lhs = (std::move(rhs));
- rhs = (std::move(temp));
- }
- friend std::ostream& operator<<(std::ostream& cout, const Vector& other)
- {
- for (size_t i = 0; i < other.size(); ++i)
- cout << other[i];
- return cout;
- }
- void Check() const {
- assert(Invariant());
- }
- bool Invariant() const
- {
- assert(size_ >= 0);
- assert(capacity_ >= 0);
- assert(size_ <= capacity_);
- return true;
- }
- };
- template<class T, int DIR>
- class VectorIter {
- T* ptr;
- int dir;
- public:
- using iterator_category = std::random_access_iterator_tag;
- using value_type = T;
- using difference_type = int;
- using pointer = T * ;
- using reference = T & ;
- VectorIter() : ptr() {
- }
- VectorIter(T* p)
- {
- ptr = p;
- dir = DIR;
- }
- VectorIter(const VectorIter& other)
- {
- ptr = other.ptr;
- dir = other.dir;
- }
- VectorIter& operator=(const VectorIter& other) {
- if (this == &other)
- return *this;
- ptr = other.ptr;
- return *this;
- }
- T& operator*() { return *ptr; }
- T* operator->() { return ptr; }
- T& operator[](size_t i) {
- if (DIR == -1)
- {
- return *(ptr - i);
- }
- return *(ptr + i);
- }
- VectorIter& operator++() {
- if (DIR == -1)
- {
- --ptr;
- return *this;
- }
- ++ptr;
- return *this;
- }
- VectorIter& operator--()
- {
- if (DIR == -1)
- {
- ++ptr;
- return *this;
- }
- --ptr;
- return *this;
- }
- VectorIter operator++(int)
- {
- if (DIR == -1)
- {
- VectorIter temp = *this;
- --ptr;
- return temp;
- }
- VectorIter temp = *this;
- ++ptr;
- return temp;
- }
- VectorIter operator--(int)
- {
- if (DIR == -1)
- {
- VectorIter temp = *this;
- ++ptr;
- return temp;
- }
- VectorIter temp = *this;
- --ptr;
- return temp;
- }
- VectorIter operator+(difference_type i) const
- {
- //?? (reverse)
- return VectorIter(ptr + i);
- }
- VectorIter operator-(difference_type i) const
- {
- //?? (reverse)
- return VectorIter(ptr - i);
- }
- difference_type operator-(const VectorIter& other) const
- {
- int diff = (ptr - other.ptr);
- return diff;
- }
- friend bool operator==(const VectorIter& lhs, const VectorIter& rhs)
- {
- if (lhs.ptr == rhs.ptr)
- {
- return true;
- }
- else
- {
- return false;
- }
- }
- friend bool operator!=(const VectorIter& lhs, const VectorIter& rhs)
- {
- return !(lhs.ptr == rhs.ptr);
- }
- friend bool operator<(const VectorIter& lhs, const VectorIter& rhs)
- {
- if (lhs.dir == -1)
- {
- return lhs.ptr > rhs.ptr;
- }
- return lhs.ptr < rhs.ptr;
- }
- friend bool operator>(const VectorIter& lhs, const VectorIter& rhs)
- {
- if (lhs.dir == -1)
- {
- return lhs.ptr < rhs.ptr;
- }
- return !(lhs.ptr < rhs.ptr);
- }
- friend bool operator<=(const VectorIter& lhs, const VectorIter& rhs)
- {
- if (lhs.dir == -1)
- {
- return !(lhs.ptr <= rhs.ptr);
- }
- return lhs.ptr <= rhs.ptr;
- }
- friend bool operator>=(const VectorIter& lhs, const VectorIter& rhs)
- {
- if (lhs.dir == -1)
- {
- return lhs.ptr <= rhs.ptr;
- }
- return !(lhs.ptr <= rhs.ptr);
- }
- };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement