#pragma once #include "ft_conatainer.hpp" #include "iterator.hpp" #include #include namespace ft { template < class T, class Allocator = std::allocator< T > > class vector { public: typedef T value_type; typedef Allocator allocator_type; typedef typename Allocator::pointer pointer; typedef typename Allocator::const_pointer cst_pointer; typedef value_type &reference; typedef const value_type &cst_reference; typedef ft::ra_iterator< reference > iterator; typedef ft::ra_iterator< cst_reference > cst_iterator; typedef ft::rev_iterator< iterator > reverse_iterator; typedef ft::rev_iterator< cst_iterator > cst_reverse_iterator; typedef std::ptrdiff_t difference_type; typedef std::size_t size_type; private: Allocator _alloc; pointer _begin; size_type _size; size_type _capacity; public: explicit vector(const Allocator &alloc = allocator_type()) : _alloc(alloc), _begin(NULL), _size(0), _capacity(0){}; explicit vector(size_type count, cst_reference value = T(), const Allocator &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 Allocator &alloc = allocator_type(), typename enable_if, 1>::type is_it = 0 ) : _alloc(alloc) { _size = distance(first, last); _capacity = _size; _begin = _alloc.allocate(_size); for (size_type i = 0; i < _size; i++) _alloc.construct(_begin + i, first[i]); } 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, cst_reference value) { resize(count); while (count > 0){ _alloc.destroy(this[count]); _alloc.contruct(this[count], value); count--; } } template < class It > void assign(It first, It last) { size_type i = ft::distance(first, last); resize(i); while (i > 0) { _alloc.destroy(this[i]); _alloc.contruct(this[i], first[i - 1]); i--; } } 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); } cst_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);} cst_reference operator[](size_type pos) const {return *(_begin + pos);} reference front(void) {return this[0];} cst_reference front(void) const {return this[0];} reference back(void) {return this[_size - 1];} cst_reference back(void) const {return this[_size - 1];} pointer data(void) {return _begin;} cst_pointer data(void) const {return _begin;} // ITERATORS: ra_iterator< T > begin(void) {return ra_iterator(front());} ra_iterator< const T > begin(void) const {return ra_iterator(front());} ra_iterator< T > end(void) {return ra_iterator(this[_size]);} ra_iterator< const T > end(void) const {return ra_iterator(this[_size]);} rev_iterator< iterator > rbegin(void) {return rev_iterator(end());} rev_iterator< cst_iterator > rbegin(void) const {return rev_iterator(end());} rev_iterator< iterator > rend(void) {return rev_iterator(begin());} rev_iterator< cst_iterator > rend(void) const {return rev_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")); Allocator 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, cst_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, cst_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); if ((_size + count) > _capacity) resize(_size + count); iterator it = end() + count; while (--it >= (pos + count)) *it = *(it - count); while (it >= pos) { *it = *last; it--; last--; } return _begin; } iterator erase(iterator pos) { while (pos < end()) { _alloc.destroy(pos); *pos = *(pos + 1); pos++; } _size--; return _begin; } iterator erase(iterator first, iterator last) { while (last++ < end()){ _alloc.destroy(first); *(first++) = *last; } while (first < end() && _size--) { _alloc.destroy(first); *(first++) = value_type(); } return _begin; } void push_back(cst_reference value) { if (_size == _capacity) resize(_size + 1); _alloc.construct(back(), value); } void pop_back(void) { _alloc.destroy(back()); _size--; } void resize(size_type count, T value = T()) { size_type i = count; if (count < _size) { while (i < _size && --_size) _alloc.destroy(this[i]); } else { if (count > _capacity) reserve(count); while (i >= _size) _alloc.construct(_begin[--i], value); } } void swap(vector &other) { vector tmp = other; other = this; this = tmp; } }; } // namespace ft