/* ************************************************************************** */ /* */ /* ::: :::::::: */ /* Vector.hpp :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: charles +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/04/24 16:19:04 by charles #+# #+# */ /* Updated: 2020/04/24 19:16:17 by charles ### ########.fr */ /* */ /* ************************************************************************** */ #ifndef VECTOR_HPP # define VECTOR_HPP # include # define FT_VECTOR_GROWTH_FACTOR 1.5 namespace ft { template < typename T, typename Alloc = allocator > class vector { public: typedef T value_type; typedef Alloc allocator_type; typedef typename allocator_type::reference reference; typedef typename allocator_type::const_reference const_reference; typedef typename allocator_type::pointer pointer; typedef typename allocator_type::const_pointer const_pointer; typedef ptrdiff_t difference_type; typedef size_t size_type; explicit Vector(const allocator_type& alloc = allocator_type()) : m_under(new value_type[0]), m_size(0), m_capacity(0) {} explicit Vector(size_type n, const value_type& val = value_type(), const allocator_type& alloc = allocator_type()) : m_under(new value_type[n]), m_size(n), m_capacity(n) { for (size_type i = 0; i < n; i++) m_under[i] = val; } template Vector (InputIterator first, InputIterator last, const allocator_type& alloc = allocator_type()) : m_under(new value_type[0]), m_size(0), m_capacity(0) { for (; first != last; first++) push_back(*first); } Vector (const Vector& x) { *this = x; } Vector& operator=(const Vector& x) { if (this == &x) return *this; delete [] m_under; m_capacity = x.m_capacity; m_size = x.m_size; m_under = new value_type[m_capacity]; for (size_type i = 0; i < m_size; i++) m_under[i] = x.m_under[i]; return *this; } ~Vector() { delete [] m_under; } iterator begin() { return iterator(*this, 0, 1); } const_iterator begin() const { return iterator(*this, 0, 1); } iterator end() { return const_iterator(*this, m_size, 1); } const_iterator end() const { return const_iterator(*this, m_size, 1); } iterator rbegin() { return iterator(*this, m_size - 1, -1); } const_iterator rbegin() const { return iterator(*this, m_size - 1, -1); } iterator rend() { return const_iterator(*this, -1, -1); } const_iterator rend() const { return const_iterator(*this, -1, -1); } size_type size() const { return m_size; } size_type max_size() const { return UINT_MAX; } size_type capacity() const { return m_capacity; } bool empty() const { return m_size == 0; } void resize(size_type n, value_type val = value_type()) { if (n == m_size) return ; if (n > m_size) { reserve(n); for (; m_size < n; m_size++) m_under[m_size] = val; } else { value_type* newUnder = new value_type[n]; m_capacity = n; m_size = n; for (size_type i = 0; i < m_size; i++) newUnder[i] = m_under[i]; delete [] m_under; m_under = newUnder; } } void reserve(size_type n) { if (m_capacity < 2) m_capacity = 2; while (m_capacity < n) m_capacity *= FT_VECTOR_GROWTH_FACTOR; value_type* newUnder = new value_type[m_capacity]; for (size_type i = 0; i < m_size; i++) newUnder[i] = m_under[i]; delete [] m_under; m_under = newUnder; } reference operator[](size_type n) { return m_under[n]; } const_reference operator[](size_type n) const { return m_under[n]; } reference at(size_type n) { if (n >= m_size) throw std::out_of_range("vector::_M_range_check"); return m_under[n]; } const_reference at(size_type n) const { if (n >= m_size) throw std::out_of_range("vector::_M_range_check"); return m_under[n]; } reference front() { return m_under[0]; } const_reference front() const { return m_under[0]; } reference back() { return m_under[m_size - 1]; } const_reference back() const { return m_under[m_size - 1]; } template void assign(InputIterator first, InputIterator last) { size_type count; InputIterator copy(first); for (count = 0; copy != last; copy++) count++; reserve(count); for (size_type i = 0; first != last; first++, i++) m_under[i] = *first; } void assign(size_type n, const value_type& val) { reserve(n); for (size_type i = 0; i < n; ++) m_under[i] = val; } void push_back(const value_type& val) { m_size++; reserve(m_size); m_under[m_size - 1] = val; } void pop_back() { m_size--; ~value_type(m_under[m_size]); } iterator insert(iterator position, const value_type& val) { m_size++; reserve(m_size); for (iterator it = rbegin(); it != position; ++it) *it = *(it - 1); *position = val; } void insert(iterator position, size_type n, const value_type& val) { reserve(m_size + n); while (n-- > 0) insert(position, val); } template void insert(iterator position, InputIterator first, InputIterator last) { for (; first != last; ++first) insert(position, *first); } iterator erase(iterator position) { for (; position != end(); ++position) *position = *(position + 1); m_size--; } iterator erase(iterator first, iterator last) { size_type i; for (i = 0; first != last && last + i != end(); ++first, i++) *first = *(last + i); m_size -= i; } void swap(Vector& x) { value_type* tmpUnder = m_under; size_type* tmpSize = m_size; size_type* tmpCapacity = m_capacity; m_under = x.m_under; m_size = x.m_size; m_capacity = x.m_capacity; x.m_under = tmpUnder; x.m_size = tmpSize; x.m_capacity = tmpCapacity; } void clear() { delete [] m_under; m_under = new value_type[0]; m_size = 0; m_capacity = 0; } class iterator { public: iterator() : m_pos(-1) {} iterator(const iterator& other) { *this = other; } iterator& operator=(const iterator& other) { if (this == &other) return *this; m_ref = other.m_ref; m_pos = other.m_pos; m_inc = other.m_inc; return *this; } ~iterator() {} value_type& operator*() { return m_ref[m_pos]; } value_type& operator->() { return m_ref[m_pos]; } bool operator==(const iterator& other) { return m_pos == other.m_pos; } bool operator!=(const iterator& other) { return !(operator==(other)); } bool operator<(const iterator& other) { return m_pos < other.m_pos; } bool operator>(const iterator& other) { return !(this <= other); } bool operator<=(const iterator& other) { return !(this > other); } bool operator>=(const iterator& other) { return !(this < other); } iterator& operator++() { m_pos += m_inc; return *this; } iterator& operator--() { m_pos -= m_inc; return *this; } iterator& operator++(int) { iterator copy(this); m_pos += m_inc; return copy; } iterator& operator--(int) { iterator copy(this); m_pos -= m_inc; return copy; } iterator operator+(int n) { iterator copy(this); return copy += n; } iterator operator-(int n) { iterator copy(this); return copy -= n; } iterator operator+(iterator& it) { iterator copy(this); return copy += it.m_pos; } iterator operator-(iterator& it) { iterator copy(this); return copy -= it.m_pos; } iterator& operator+=(int n) { m_pos += n; return *this; } iterator& operator-=(int n) { m_pos -= n; return *this; } value_type& operator[](size_type n) { return m_ref[m_pos + n]; } private: iterator(Vector* ref, size_type pos, int inc) : m_pos(pos), m_ref(ref), m_inc(int) {} Vector& m_ref; size_type m_pos; int inc; } class const_iterator : public iterator { const value_type& operator*() { return m_ref[m_pos]; } const value_type& operator->() { return m_ref[m_pos]; } } private: value_type* m_under; size_type m_size; size_type m_capacity; }; } template bool operator==(const Vector& lhs, const Vector& rhs) { if (lhs.size() != rhs.size()) return false; for (Vector::size_type i = 0; i < lhs.size(); i++) if (!(lhs[i] == rhs[i])) return false; return true; } template bool operator!=(const Vector& lhs, const Vector& rhs) { return !(lhs == rhs); } template bool operator& lhs, const Vector& rhs) { for (Vector::size_type i = 0; i < lhs.size() && i < rhs.size(); i++) if (lhs[i] < rhs[i] && !(rhs[i] < lhs[i])) return true; return false; } template bool operator<=const Vector& lhs, const Vector& rhs) { return !(rhs < lhs); } template bool operator>const Vector& lhs, const Vector& rhs) { return rhs < lhs; } template bool operator>=const Vector& lhs, const Vector& rhs) { return !(lhs < rhs); } template void swap(Vector& x, Vector& y) { x.swap(y); } #endif