Browse Source

save 22-12-15

master
nicolas-arnaud 2 years ago
parent
commit
91f7e4abde
  1. 222
      includes/iterator.hpp
  2. 121
      includes/reverse_iterator.hpp
  3. 145
      includes/vector.hpp
  4. 3
      tester.cpp

222
includes/iterator.hpp

@ -9,19 +9,18 @@ struct forward_iterator_tag : public input_iterator_tag {};
struct bidirectional_iterator_tag : public forward_iterator_tag {}; struct bidirectional_iterator_tag : public forward_iterator_tag {};
struct random_access_iterator_tag : public bidirectional_iterator_tag {}; struct random_access_iterator_tag : public bidirectional_iterator_tag {};
template < class Iter > struct iterator_traits { template < class Iterator > struct iterator_traits {
typedef typename Iter::iterator_category iterator_category; typedef typename Iterator::iterator_category iterator_category;
typedef typename Iter::value_type value_type; typedef typename Iterator::value_type value_type;
typedef typename Iter::difference_type difference_type; typedef typename Iterator::difference_type difference_type;
typedef typename Iter::pointer pointer; typedef typename Iterator::pointer pointer;
typedef typename Iter::reference reference; typedef typename Iterator::reference reference;
}; };
template < class T > struct iterator_traits< T * > { template < class T > struct iterator_traits< T * > {
public:
typedef random_access_iterator_tag iterator_category; typedef random_access_iterator_tag iterator_category;
typedef T value_type; typedef T value_type;
typedef std::ptrdiff_t difference_type; typedef ptrdiff_t difference_type;
typedef T *pointer; typedef T *pointer;
typedef T &reference; typedef T &reference;
}; };
@ -29,162 +28,129 @@ public:
template < class T > struct iterator_traits< const T * > { template < class T > struct iterator_traits< const T * > {
typedef random_access_iterator_tag iterator_category; typedef random_access_iterator_tag iterator_category;
typedef T value_type; typedef T value_type;
typedef std::ptrdiff_t difference_type; typedef ptrdiff_t difference_type;
typedef const T *pointer; typedef T *pointer;
typedef const T &reference; typedef T &reference;
}; };
// Iterator classes: // Iterator classes:
template < class Category, class T, class Distance = ptrdiff_t,
class Pointer = T *, class Reference = T & >
struct iterator {
typedef Category iterator_category;
typedef T value_type;
typedef Distance difference_type;
typedef Pointer pointer;
typedef Reference reference;
};
template < class T > class ra_iterator { template < class T >
typedef random_access_iterator_tag iterator_category; class random_access_iterator
typedef T value_type; : public iterator< random_access_iterator_tag, T > {
typedef std::ptrdiff_t difference_type;
typedef T *pointer;
typedef T &reference;
pointer current;
public: public:
ra_iterator(pointer value = NULL) : current(value) {} typedef typename iterator< random_access_iterator_tag, T >::iterator_category
ra_iterator(const ra_iterator &iter) : current(iter.base()) {} iterator_category;
typedef
ra_iterator &operator=(const ra_iterator< T > &iter) { typename iterator< random_access_iterator_tag, T >::value_type value_type;
current = iter.base(); typedef typename iterator< random_access_iterator_tag, T >::difference_type
return (*this); difference_type;
} typedef T *pointer;
typedef T &reference;
private:
pointer _ptr;
pointer base(void) const { return current; } public:
reference operator*(void) const { return *current; } random_access_iterator(pointer ptr = NULL) : _ptr(ptr) {}
pointer operator->(void) const { return current; } random_access_iterator(const random_access_iterator &other)
reference operator[](const difference_type n) const { return *(current + n); } : _ptr(other._ptr) {}
ra_iterator operator+(const difference_type n) const { random_access_iterator &operator=(const random_access_iterator &other) {
return (ra_iterator(current + n)); _ptr = other._ptr;
}
ra_iterator &operator++() {
++current;
return *this; return *this;
} }
ra_iterator operator++(int) {
ra_iterator tmp(*this); pointer base(void) { return _ptr; }
++(*this); pointer operator->(void) { return _ptr; }
return tmp; reference operator*(void) { return *_ptr; }
reference operator[](const difference_type n) { return *(_ptr + n); }
random_access_iterator operator+(const difference_type n) const {
return (random_access_iterator(_ptr + n));
} }
ra_iterator &operator+=(const difference_type other) { difference_type operator+(const random_access_iterator &right) const {
current += other; return _ptr + right._ptr;
return *this;
} }
ra_iterator operator-(const difference_type n) const { friend random_access_iterator operator+(const difference_type n,
return (iterator(current - n)); random_access_iterator &right) {
return random_access_iterator(right._ptr + n);
} }
ra_iterator &operator--() { random_access_iterator &operator++() {
--current; ++_ptr;
return *this; return *this;
} }
ra_iterator operator--(int) { random_access_iterator operator++(int) {
ra_iterator tmp(*this); random_access_iterator ret(*this);
--(*this); ++(*this);
return tmp; return ret;
} }
ra_iterator &operator-=(const difference_type other) { random_access_iterator &operator+=(const difference_type n) {
current -= other; _ptr += n;
return *this; return *this;
} }
bool operator==(const ra_iterator &right) const { random_access_iterator operator-(const difference_type n) const {
return current == right.base(); return (random_access_iterator(_ptr - n));
}
bool operator!=(const ra_iterator &right) const {
return current != right.base();
}
bool operator<(const ra_iterator &right) const {
return current < right.base();
} }
bool operator>(const ra_iterator &right) const { difference_type operator-(const random_access_iterator &right) const {
return current > right.base(); return _ptr - right._ptr;
} }
bool operator<=(const ra_iterator &right) const { friend random_access_iterator operator-(const difference_type n,
return current <= right.base(); random_access_iterator &right) {
return random_access_iterator(right._ptr - n);
} }
bool operator>=(const ra_iterator &right) const { random_access_iterator &operator--() {
return current >= right.base(); --_ptr;
}
};
template < class T > class rev_iterator {
T current;
typedef random_access_iterator_tag iterator_category;
typedef T value_type;
typedef std::ptrdiff_t difference_type;
typedef T *pointer;
typedef T &reference;
public:
template <class It>
rev_iterator(It value = NULL) : current(value) {}
rev_iterator(const rev_iterator &iter) : current(iter.base()) {}
rev_iterator &operator=(const rev_iterator< T > &iter) {
current = iter.base();
return (*this);
}
T base(void) const { return current; }
reference operator*(void) const { return *(current - 1); }
pointer operator->(void) const { return current - 1; }
reference operator[](const difference_type n) const { return *(current - n); }
rev_iterator operator+(const difference_type n) const {
return (rev_iterator(current - n));
}
rev_iterator &operator++() {
--current;
return *this; return *this;
} }
rev_iterator operator++(int) const { random_access_iterator operator--(int) {
rev_iterator tmp(*this); random_access_iterator ret(*this);
--(*this); --(*this);
return tmp; return ret;
} }
rev_iterator &operator+=(const difference_type n) { random_access_iterator &operator-=(const difference_type n) {
current -= n; _ptr -= n;
return *this; return *this;
} }
rev_iterator operator-(const difference_type n) const { friend bool operator==(const random_access_iterator &left,
return (rev_iterator(current + n)); const random_access_iterator &right) {
return left._ptr == right._ptr;
} }
rev_iterator &operator--() { friend bool operator!=(const random_access_iterator &left,
++current; const random_access_iterator &right) {
return *this; return left._ptr != right._ptr;
}
rev_iterator operator--(int) {
rev_iterator tmp(*this);
++(*this);
return tmp;
}
rev_iterator &operator-=(const difference_type n) {
current += n;
return *this;
}
bool operator==(const rev_iterator< T > &right) const {
return current == right.base();
} }
bool operator!=(const rev_iterator< T > &right) const { friend bool operator<(const random_access_iterator &left,
return current != right.base(); const random_access_iterator &right) {
return left._ptr < right._ptr;
} }
bool operator<(const rev_iterator< T > &right) const { friend bool operator<=(const random_access_iterator &left,
return current >= right.base(); const random_access_iterator &right) {
return left._ptr <= right._ptr;
} }
bool operator>(const rev_iterator< T > &right) const { friend bool operator>(const random_access_iterator &left,
return current <= right.base(); const random_access_iterator &right) {
return left._ptr > right._ptr;
} }
bool operator<=(const rev_iterator< T > &right) const { friend bool operator>=(const random_access_iterator &left,
return current > right.base(); const random_access_iterator &right) {
return left._ptr >= right._ptr;
} }
bool operator>=(const rev_iterator< T > &right) const { operator random_access_iterator< const T >() const {
return current < right.base(); return random_access_iterator< const T >(_ptr);
} }
}; };

121
includes/reverse_iterator.hpp

@ -0,0 +1,121 @@
#pragma once
#include "iterator.hpp"
namespace ft {
template < class Iterator > class reverse_iterator {
public:
typedef Iterator iterator_type;
typedef typename Iterator::iterator_category iterator_category;
typedef typename Iterator::value_type value_type;
typedef typename Iterator::difference_type difference_type;
typedef typename Iterator::pointer *pointer;
typedef typename Iterator::reference &reference;
private:
Iterator _base;
public:
reverse_iterator(Iterator value = NULL) : _base(value) {}
template < typename T >
reverse_iterator(const reverse_iterator< T > &iter) : _base(iter.base()) {}
reverse_iterator &operator=(const reverse_iterator &other) {
_base = other._base;
return *this;
}
Iterator base(void) const { return _base; }
reference operator*(void) const {
Iterator ret = _base;
return *(--ret);
}
reverse_iterator operator+(const difference_type n) const {
return (reverse_iterator(_base - n));
}
reverse_iterator &operator++(void) {
--_base;
return *this;
}
reverse_iterator operator++(int) const {
reverse_iterator ret(*this);
--(*this);
return ret;
}
reverse_iterator &operator+=(const difference_type n) {
_base -= n;
return *this;
}
reverse_iterator operator-(const difference_type n) const {
return (reverse_iterator(_base + n));
}
reverse_iterator &operator--(void) {
++_base;
return *this;
}
reverse_iterator operator--(int) {
reverse_iterator ret(*this);
++(*this);
return ret;
}
reverse_iterator &operator-=(const difference_type n) {
_base += n;
return *this;
}
pointer operator->(void) const { return &(operator*()); }
reference operator[](const difference_type n) const { return base()[-n-1]; }
template < typename It >
friend reverse_iterator operator+(const int n,
const reverse_iterator< It > &op) {
return reverse_iterator(op._base - n);
}
};
template < typename It1, typename It2 >
bool operator==(const reverse_iterator< It1 > &lhs,
const reverse_iterator< It2 > &rhs) {
return (lhs.base() == rhs.base());
}
template < typename It1, typename It2 >
bool operator!=(const reverse_iterator< It1 > &lhs,
const reverse_iterator< It2 > &rhs) {
return (lhs.base() != rhs.base());
}
template < typename It1, typename It2 >
bool operator<(const reverse_iterator< It1 > &lhs,
const reverse_iterator< It2 > &rhs) {
return (lhs.base() > rhs.base());
}
template < typename It1, typename It2 >
bool operator<=(const reverse_iterator< It1 > &lhs,
const reverse_iterator< It2 > &rhs) {
return (lhs.base() >= rhs.base());
}
template < typename It1, typename It2 >
bool operator>(const reverse_iterator< It1 > &lhs,
const reverse_iterator< It2 > &rhs) {
return (lhs.base() < rhs.base());
}
template < typename It1, typename It2 >
bool operator>=(const reverse_iterator< It1 > &lhs,
const reverse_iterator< It2 > &rhs) {
return (lhs.base() <= rhs.base());
}
template < class It1, class It2 >
typename reverse_iterator< It1 >::difference_type
operator-(const reverse_iterator< It1 > &lhs,
const reverse_iterator< It2 > &rhs) {
return lhs.base() - rhs.base();
}
} // namespace ft

145
includes/vector.hpp

@ -1,5 +1,6 @@
#pragma once #pragma once
#include "iterator.hpp" #include "iterator.hpp"
#include "reverse_iterator.hpp"
#include "utils.hpp" #include "utils.hpp"
#include <iostream> #include <iostream>
@ -8,33 +9,33 @@
namespace ft { namespace ft {
template < class T, class Allocator = std::allocator< T > > class vector { template < class T, class Alloc = std::allocator< T > > class vector {
public: public:
typedef T value_type; typedef T value_type;
typedef Allocator allocator_type; typedef Alloc allocator_type;
typedef typename Allocator::pointer pointer; typedef typename Alloc::pointer pointer;
typedef typename Allocator::const_pointer cst_pointer; typedef typename Alloc::const_pointer const_pointer;
typedef value_type &reference; typedef value_type &reference;
typedef const value_type &cst_reference; typedef const value_type &const_reference;
typedef ft::ra_iterator< reference > iterator; typedef ft::random_access_iterator< T > iterator;
typedef ft::ra_iterator< cst_reference > cst_iterator; typedef ft::random_access_iterator< const T > const_iterator;
typedef ft::rev_iterator< iterator > reverse_iterator; typedef ft::reverse_iterator< iterator > reverse_iterator;
typedef ft::rev_iterator< cst_iterator > cst_reverse_iterator; typedef ft::reverse_iterator< const_iterator > const_reverse_iterator;
typedef std::ptrdiff_t difference_type; typedef std::ptrdiff_t difference_type;
typedef std::size_t size_type; typedef std::size_t size_type;
private: private:
Allocator _alloc; Alloc _alloc;
pointer _begin; pointer _begin;
size_type _size; size_type _size;
size_type _capacity; size_type _capacity;
public: public:
explicit vector(const Allocator &alloc = allocator_type()) explicit vector(const Alloc &alloc = allocator_type())
: _alloc(alloc), _begin(NULL), _size(0), _capacity(0){}; : _alloc(alloc), _begin(NULL), _size(0), _capacity(0){};
explicit vector(size_type count, cst_reference value = T(), explicit vector(size_type count, const_reference value = T(),
const Allocator &alloc = allocator_type()) const Alloc &alloc = allocator_type())
: _alloc(alloc), _size(count), _capacity(count) { : _alloc(alloc), _size(count), _capacity(count) {
_begin = _alloc.allocate(count); _begin = _alloc.allocate(count);
for (size_type i = 0; i < count; i++) for (size_type i = 0; i < count; i++)
@ -42,14 +43,14 @@ public:
} }
template < class It > template < class It >
vector(It first, It last, const Allocator &alloc = allocator_type(), vector(It first, It last, const Alloc &alloc = allocator_type(),
typename ft::enable_if< !is_integral< It >::value, bool >::type = 0) typename ft::enable_if< !is_integral< It >::value, bool >::type = 0)
: _alloc(alloc) { : _alloc(alloc) {
_size = distance(first, last); _size = ft::distance(first, last) - 1;
_capacity = _size; _capacity = _size;
_begin = _alloc.allocate(_size); _begin = _alloc.allocate(_size);
for (size_type i = 0; i < _size; i++) for (size_type i = 0; i < _size; i++)
_alloc.construct(_begin + i, first[i]); _alloc.construct(_begin + i, *(first++));
} }
vector(const vector &other) vector(const vector &other)
@ -77,23 +78,23 @@ public:
return (*this); return (*this);
} }
void assign(size_type count, cst_reference value) { void assign(size_type count, const_reference value) {
resize(count); resize(count);
do { while (count--) {
_alloc.destroy(_begin + count); _alloc.destroy(_begin + count);
_alloc.construct(_begin + count, value); _alloc.construct(_begin + count, value);
} while (count-- > 0); };
} }
template < class It > template < class It >
void void
assign(It first, It last, assign(It first, It last,
typename ft::enable_if< !is_integral< It >::value, bool >::type = 0) { typename ft::enable_if< !is_integral< It >::value, bool >::type = 0) {
size_type i = ft::distance(first, last); size_type count = ft::distance(first, last) - 1;
resize(i); resize(count);
do { while (count-- > 0) {
_alloc.destroy(_begin + i); _alloc.destroy(_begin + count);
_alloc.construct(_begin + i, first[i]); _alloc.construct(_begin + count, *(--last));
} while (i-- > 0); }
} }
allocator_type get_allocator(void) const { return _alloc; } allocator_type get_allocator(void) const { return _alloc; }
@ -104,47 +105,39 @@ public:
throw(std::out_of_range("vector: Out of range access")); throw(std::out_of_range("vector: Out of range access"));
return *(_begin + pos); return *(_begin + pos);
} }
cst_reference at(size_type pos) const { const_reference at(size_type pos) const {
if (pos >= _size) if (pos >= _size)
throw(std::out_of_range("vector: Out of range access")); throw(std::out_of_range("vector: Out of range access"));
return *(_begin + pos); return *(_begin + pos);
} }
reference operator[](size_type pos) { return _begin[pos]; } reference operator[](size_type pos) { return _begin[pos]; }
cst_reference operator[](size_type pos) const { return _begin[pos]; } const_reference operator[](size_type pos) const { return _begin[pos]; }
reference front(void) { return _begin[0]; } reference front(void) { return _begin[0]; }
cst_reference front(void) const { return _begin[0]; } const_reference front(void) const { return _begin[0]; }
reference back(void) { return _begin[_size - 1]; } reference back(void) { return _begin[_size - 1]; }
cst_reference back(void) const { return _begin[_size - 1]; } const_reference back(void) const { return _begin[_size - 1]; }
pointer data(void) { return _begin; } pointer data(void) { return _begin; }
cst_pointer data(void) const { return _begin; } const_pointer data(void) const { return _begin; }
// ITERATORS: // ITERATORS:
ra_iterator< T > begin(void) { return ra_iterator< T >(_begin); } iterator begin(void) { return iterator(_begin); }
ra_iterator< const T > begin(void) const { const_iterator begin(void) const { return const_iterator(_begin); }
return ra_iterator< const T >(_begin);
}
ra_iterator< T > end(void) { return ra_iterator< T >(_begin + _size); } iterator end(void) { return iterator(_begin + _size); }
ra_iterator< const T > end(void) const { const_iterator end(void) const { return const_iterator(_begin + _size); }
return ra_iterator< const T >(_begin + _size);
}
rev_iterator< iterator > rbegin(void) { reverse_iterator rbegin(void) { return reverse_iterator(end()); }
return rev_iterator< pointer >(end()); const_reverse_iterator rbegin(void) const {
} return const_reverse_iterator(end());
rev_iterator< cst_iterator > rbegin(void) const {
return rev_iterator< cst_pointer >(end());
} }
rev_iterator< iterator > rend(void) { reverse_iterator rend(void) { return reverse_iterator(begin()); }
return rev_iterator< pointer >(begin()); const_reverse_iterator rend(void) const {
} return const_reverse_iterator(begin());
rev_iterator< cst_iterator > rend(void) const {
return rev_iterator< cst_pointer >(begin());
} }
// CAPACITY: // CAPACITY:
@ -154,8 +147,8 @@ public:
void reserve(size_type new_cap) { void reserve(size_type new_cap) {
if (new_cap > max_size()) if (new_cap > max_size())
throw(std::length_error("vector::reserve: new_cap > max_size")); throw(std::length_error("vector::reserve: new_cap > max_size"));
Allocator new_alloc; Alloc new_alloc;
pointer new_begin; pointer new_begin;
new_begin = new_alloc.allocate(new_cap); new_begin = new_alloc.allocate(new_cap);
for (size_type i = 0; i < _size; i++) for (size_type i = 0; i < _size; i++)
new_alloc.construct(new_begin + i, *(_begin + i)); new_alloc.construct(new_begin + i, *(_begin + i));
@ -173,7 +166,7 @@ public:
_alloc.destroy(_begin + i); _alloc.destroy(_begin + i);
_size = 0; _size = 0;
} }
iterator insert(iterator pos, cst_reference value) { iterator insert(iterator pos, const_reference value) {
if (_size == _capacity) if (_size == _capacity)
resize(_size + 1); resize(_size + 1);
iterator it = end() + 1; iterator it = end() + 1;
@ -183,7 +176,7 @@ public:
*it = value; *it = value;
return _begin; return _begin;
} }
iterator insert(iterator pos, size_type count, cst_reference value) { iterator insert(iterator pos, size_type count, const_reference value) {
if ((_size + count) > _capacity) if ((_size + count) > _capacity)
resize(_size + count); resize(_size + count);
iterator it = end() + count; iterator it = end() + count;
@ -196,22 +189,20 @@ public:
return _begin; return _begin;
} }
template < class It > iterator insert(iterator pos, It first, It last) { template < class It > iterator insert(iterator pos, It first, It last) {
size_type count = ft::distance(first, last); size_type count = ft::distance(first, last) - 1;
if ((_size + count) > _capacity) if ((_size + count) > _capacity)
resize(_size + count); resize(_size + count);
iterator it = end() + count; iterator it = end();
while (--it >= (pos + count)) while (--it >= (pos + count))
*it = *(it - count); *it = *(it - count);
while (it >= pos) { while (it >= pos) {
*it = *last; *(--it) = *(--last);
it--;
last--;
} }
return _begin; return _begin;
} }
iterator erase(iterator pos) { iterator erase(iterator pos) {
while (pos < end()) { while (pos < end()) {
_alloc.destroy(pos); _alloc.destroy(pos.base());
*pos = *(pos + 1); *pos = *(pos + 1);
pos++; pos++;
} }
@ -220,35 +211,33 @@ public:
} }
iterator erase(iterator first, iterator last) { iterator erase(iterator first, iterator last) {
while (last++ < end()) { while (last++ < end()) {
_alloc.destroy(first); _alloc.destroy(first.base());
*(first++) = *last; *(first++) = *last;
} }
while (first < end() && _size--) { while (first < end() && _size--) {
_alloc.destroy(first); _alloc.destroy(first.base());
*(first++) = value_type(); *(first++) = value_type();
} }
return _begin; return _begin;
} }
void push_back(cst_reference value) { void push_back(const_reference value) {
if (_size == _capacity) if (_size == _capacity)
resize(_size + 1); resize(_size + 1);
_alloc.construct(back(), value); _alloc.construct(_begin + _size - 1, value);
} }
void pop_back(void) { void pop_back(void) {
_alloc.destroy(back()); _alloc.destroy(_begin + _size - 1);
_size--; _size--;
} }
void resize(size_type count, T value = T()) { void resize(size_type count, T value = T()) {
size_type i = count;
if (count < _size) { if (count < _size) {
while (i < _size && --_size) while (count < --_size)
_alloc.destroy(_begin + i); _alloc.destroy(_begin + _size);
} else { } else {
if (count > _capacity) if (count > _capacity)
reserve(count); reserve(count);
while (i >= _size) while (_size < count)
_alloc.construct(_begin + --i, value); _alloc.construct(_begin + _size++, value);
_size = count;
} }
} }
void swap(vector &other) { void swap(vector &other) {
@ -257,7 +246,7 @@ public:
this = tmp; this = tmp;
} }
void print(void) { void print(void) {
ft::ra_iterator< T > i = begin(); ft::random_access_iterator< T > i = begin();
while (i < end()) { while (i < end()) {
std::cout << *i << " "; std::cout << *i << " ";
i++; i++;

3
tester.cpp

@ -64,9 +64,6 @@ void test_vectors(void) {
std::cout << "12.c) test5.size() | " << test5.size() << std::endl; std::cout << "12.c) test5.size() | " << test5.size() << std::endl;
std::cout << "12.d) test5.max_size() | " << test5.max_size() << std::endl; std::cout << "12.d) test5.max_size() | " << test5.max_size() << std::endl;
std::cout << "12.e) test5.capacity() | " << test5.capacity() << std::endl; std::cout << "12.e) test5.capacity() | " << test5.capacity() << std::endl;
} }
int main(void) { test_vectors(); } int main(void) { test_vectors(); }

Loading…
Cancel
Save