#pragma once #include "iterator.hpp" #include "reverse_iterator.hpp" #include "utils.hpp" #include #include #include namespace ft { template < class T, class Alloc = std::allocator< T > > class vector { public: typedef T value_type; typedef Alloc allocator_type; typedef typename Alloc::pointer pointer; typedef typename Alloc::const_pointer const_pointer; typedef value_type &reference; typedef const value_type &const_reference; typedef ft::random_access_iterator< T > iterator; typedef ft::random_access_iterator< const T > const_iterator; typedef ft::reverse_iterator< iterator > reverse_iterator; typedef ft::reverse_iterator< const_iterator > const_reverse_iterator; typedef std::ptrdiff_t difference_type; typedef std::size_t size_type; private: Alloc _alloc; pointer _begin; size_type _size; size_type _capacity; public: explicit vector(const Alloc &alloc = allocator_type()) : _alloc(alloc), _begin(NULL), _size(0), _capacity(0){}; explicit vector(size_type count, const_reference value = T(), const Alloc &alloc = allocator_type()) : _alloc(alloc), _size(count), _capacity(count) { _begin = _alloc.allocate(count); for (size_type i = 0; i < count; i++) _alloc.construct(_begin + i, value); } template < class It > vector(It first, It last, const Alloc &alloc = allocator_type(), typename ft::enable_if< !is_integral< It >::value, bool >::type = 0) : _alloc(alloc) { _size = ft::distance(first, last) - 1; _capacity = _size; _begin = _alloc.allocate(_size); for (size_type i = 0; i < _size; i++) _alloc.construct(_begin + i, *(first++)); } vector(const vector &other) : _alloc(other._alloc), _size(other._size), _capacity(other._capacity) { _begin = _alloc.allocate(_capacity); for (size_type i = 0; i < _size; i++) _alloc.construct(_begin + i, other._begin[i]); } ~vector(void) { clear(); if (_capacity) _alloc.deallocate(_begin, _capacity); } vector &operator=(const vector &other) { clear(); _alloc.deallocate(_begin, _capacity); _alloc = other._alloc; _capacity = other._capacity; _size = other._size; _begin = _alloc.allocate(_capacity); for (size_type i = 0; i < _size; i++) _alloc.construct(_begin + i, other._begin[i]); return (*this); } void assign(size_type count, const_reference value) { resize(count); while (count--) { _alloc.destroy(_begin + count); _alloc.construct(_begin + count, value); }; } template < class It > void assign(It first, It last, typename ft::enable_if< !is_integral< It >::value, bool >::type = 0) { size_type count = ft::distance(first, last) - 1; resize(count); while (count-- > 0) { _alloc.destroy(_begin + count); _alloc.construct(_begin + count, *(--last)); } } allocator_type get_allocator(void) const { return _alloc; } // ACCESS: reference at(size_type pos) { if (pos >= _size) throw(std::out_of_range("vector: Out of range access")); return *(_begin + pos); } const_reference at(size_type pos) const { if (pos >= _size) throw(std::out_of_range("vector: Out of range access")); return *(_begin + pos); } reference operator[](size_type pos) { return _begin[pos]; } const_reference operator[](size_type pos) const { return _begin[pos]; } reference front(void) { return _begin[0]; } const_reference front(void) const { return _begin[0]; } reference back(void) { return _begin[_size - 1]; } const_reference back(void) const { return _begin[_size - 1]; } pointer data(void) { return _begin; } const_pointer data(void) const { return _begin; } // ITERATORS: iterator begin(void) { return iterator(_begin); } const_iterator begin(void) const { return const_iterator(_begin); } iterator end(void) { return iterator(_begin + _size); } const_iterator end(void) const { return const_iterator(_begin + _size); } reverse_iterator rbegin(void) { return reverse_iterator(end()); } const_reverse_iterator rbegin(void) const { return const_reverse_iterator(end()); } reverse_iterator rend(void) { return reverse_iterator(begin()); } const_reverse_iterator rend(void) const { return const_reverse_iterator(begin()); } // CAPACITY: bool empty(void) const { return _size == 0; } size_type size(void) const { return _size; } size_type max_size(void) const { return _alloc.max_size(); } void reserve(size_type new_cap) { if (new_cap > max_size()) throw(std::length_error("vector::reserve: new_cap > max_size")); Alloc new_alloc; pointer new_begin; new_begin = new_alloc.allocate(new_cap); for (size_type i = 0; i < _size; i++) new_alloc.construct(new_begin + i, *(_begin + i)); clear(); _alloc.deallocate(_begin, _capacity); _alloc = new_alloc; _begin = new_begin; _capacity = new_cap; } size_type capacity(void) const { return _capacity; } // MODIFIERS: void clear(void) { for (size_type i = 0; i < _size; i++) _alloc.destroy(_begin + i); _size = 0; } iterator insert(iterator pos, const_reference value) { if (_size == _capacity) resize(_size + 1); iterator it = end() + 1; ; while (--it >= pos) *it = *(it - 1); *it = value; return _begin; } iterator insert(iterator pos, size_type count, const_reference value) { if ((_size + count) > _capacity) resize(_size + count); iterator it = end() + count; while (--it >= (pos + count)) *it = *(it - count); while (it >= pos) { *it = value; it--; } return _begin; } template < class It > iterator insert(iterator pos, It first, It last) { size_type count = ft::distance(first, last) - 1; if ((_size + count) > _capacity) resize(_size + count); iterator it = end(); while (--it >= (pos + count)) *it = *(it - count); while (it >= pos) { *(--it) = *(--last); } return _begin; } iterator erase(iterator pos) { while (pos < end()) { _alloc.destroy(pos.base()); *pos = *(pos + 1); pos++; } _size--; return _begin; } iterator erase(iterator first, iterator last) { while (last++ < end()) { _alloc.destroy(first.base()); *(first++) = *last; } while (first < end() && _size--) { _alloc.destroy(first.base()); *(first++) = value_type(); } return _begin; } void push_back(const_reference value) { if (_size == _capacity) resize(_size + 1); _alloc.construct(_begin + _size - 1, value); } void pop_back(void) { _alloc.destroy(_begin + _size - 1); _size--; } void resize(size_type count, T value = T()) { if (count < _size) { while (count < --_size) _alloc.destroy(_begin + _size); } else { if (count > _capacity) reserve(count); while (_size < count) _alloc.construct(_begin + _size++, value); } } void swap(vector &other) { vector< T > tmp = other; other = this; this = tmp; } void print(void) { ft::random_access_iterator< T > i = begin(); while (i < end()) { std::cout << *i << " "; i++; } std::cout << "\n"; } }; } // namespace ft