You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

269 lines
7.5 KiB

#pragma once
#include "iterator.hpp"
#include "utils.hpp"
#include <iostream>
#include <memory>
#include <stdexcept>
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 ft::enable_if< !is_integral< It >::value, bool >::type = 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);
do {
_alloc.destroy(_begin + count);
_alloc.construct(_begin + count, value);
} while (count-- > 0);
}
template < class It >
void
assign(It first, It last,
typename ft::enable_if< !is_integral< It >::value, bool >::type = 0) {
size_type i = ft::distance(first, last);
resize(i);
do {
_alloc.destroy(_begin + i);
_alloc.construct(_begin + i, first[i]);
} while (i-- > 0);
}
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 _begin[0]; }
cst_reference front(void) const { return _begin[0]; }
reference back(void) { return _begin[_size - 1]; }
cst_reference back(void) const { return _begin[_size - 1]; }
pointer data(void) { return _begin; }
cst_pointer data(void) const { return _begin; }
// ITERATORS:
ra_iterator< T > begin(void) { return ra_iterator< T >(_begin); }
ra_iterator< const T > begin(void) const {
return ra_iterator< const T >(_begin);
}
ra_iterator< T > end(void) { return ra_iterator< T >(_begin + _size); }
ra_iterator< const T > end(void) const {
return ra_iterator< const T >(_begin + _size);
}
rev_iterator< iterator > rbegin(void) {
return rev_iterator< pointer >(end());
}
rev_iterator< cst_iterator > rbegin(void) const {
return rev_iterator< cst_pointer >(end());
}
rev_iterator< iterator > rend(void) {
return rev_iterator< pointer >(begin());
}
rev_iterator< cst_iterator > rend(void) const {
return rev_iterator< cst_pointer >(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(_begin + i);
} else {
if (count > _capacity)
reserve(count);
while (i >= _size)
_alloc.construct(_begin + --i, value);
_size = count;
}
}
void swap(vector &other) {
vector< T > tmp = other;
other = this;
this = tmp;
}
void print(void) {
ft::ra_iterator< T > i = begin();
while (i < end()) {
std::cout << *i << " ";
i++;
}
std::cout << "\n";
}
};
} // namespace ft