diff --git a/includes/iterator.hpp b/includes/iterator.hpp index 0c575d3..4e46896 100644 --- a/includes/iterator.hpp +++ b/includes/iterator.hpp @@ -9,19 +9,18 @@ struct forward_iterator_tag : public input_iterator_tag {}; struct bidirectional_iterator_tag : public forward_iterator_tag {}; struct random_access_iterator_tag : public bidirectional_iterator_tag {}; -template < class Iter > struct iterator_traits { - typedef typename Iter::iterator_category iterator_category; - typedef typename Iter::value_type value_type; - typedef typename Iter::difference_type difference_type; - typedef typename Iter::pointer pointer; - typedef typename Iter::reference reference; +template < class Iterator > struct iterator_traits { + 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; }; template < class T > struct iterator_traits< T * > { -public: typedef random_access_iterator_tag iterator_category; typedef T value_type; - typedef std::ptrdiff_t difference_type; + typedef ptrdiff_t difference_type; typedef T *pointer; typedef T &reference; }; @@ -29,162 +28,129 @@ public: template < class T > struct iterator_traits< const T * > { typedef random_access_iterator_tag iterator_category; typedef T value_type; - typedef std::ptrdiff_t difference_type; - typedef const T *pointer; - typedef const T &reference; + typedef ptrdiff_t difference_type; + typedef T *pointer; + typedef T &reference; }; // 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 { - typedef random_access_iterator_tag iterator_category; - typedef T value_type; - typedef std::ptrdiff_t difference_type; - typedef T *pointer; - typedef T &reference; - pointer current; +template < class T > +class random_access_iterator + : public iterator< random_access_iterator_tag, T > { public: - ra_iterator(pointer value = NULL) : current(value) {} - ra_iterator(const ra_iterator &iter) : current(iter.base()) {} - - ra_iterator &operator=(const ra_iterator< T > &iter) { - current = iter.base(); - return (*this); - } + typedef typename iterator< random_access_iterator_tag, T >::iterator_category + iterator_category; + typedef + typename iterator< random_access_iterator_tag, T >::value_type value_type; + typedef typename iterator< random_access_iterator_tag, T >::difference_type + difference_type; + typedef T *pointer; + typedef T &reference; + +private: + pointer _ptr; - pointer base(void) const { return current; } - reference operator*(void) const { return *current; } - pointer operator->(void) const { return current; } - reference operator[](const difference_type n) const { return *(current + n); } +public: + random_access_iterator(pointer ptr = NULL) : _ptr(ptr) {} + random_access_iterator(const random_access_iterator &other) + : _ptr(other._ptr) {} - ra_iterator operator+(const difference_type n) const { - return (ra_iterator(current + n)); - } - ra_iterator &operator++() { - ++current; + random_access_iterator &operator=(const random_access_iterator &other) { + _ptr = other._ptr; return *this; } - ra_iterator operator++(int) { - ra_iterator tmp(*this); - ++(*this); - return tmp; + + pointer base(void) { return _ptr; } + pointer operator->(void) { return _ptr; } + 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) { - current += other; - return *this; + difference_type operator+(const random_access_iterator &right) const { + return _ptr + right._ptr; } - ra_iterator operator-(const difference_type n) const { - return (iterator(current - n)); + friend random_access_iterator operator+(const difference_type n, + random_access_iterator &right) { + return random_access_iterator(right._ptr + n); } - ra_iterator &operator--() { - --current; + random_access_iterator &operator++() { + ++_ptr; return *this; } - ra_iterator operator--(int) { - ra_iterator tmp(*this); - --(*this); - return tmp; + random_access_iterator operator++(int) { + random_access_iterator ret(*this); + ++(*this); + return ret; } - ra_iterator &operator-=(const difference_type other) { - current -= other; + random_access_iterator &operator+=(const difference_type n) { + _ptr += n; return *this; } - 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 { - return current < right.base(); + random_access_iterator operator-(const difference_type n) const { + return (random_access_iterator(_ptr - n)); } - bool operator>(const ra_iterator &right) const { - return current > right.base(); + difference_type operator-(const random_access_iterator &right) const { + return _ptr - right._ptr; } - bool operator<=(const ra_iterator &right) const { - return current <= right.base(); + friend random_access_iterator operator-(const difference_type n, + random_access_iterator &right) { + return random_access_iterator(right._ptr - n); } - bool operator>=(const ra_iterator &right) const { - return current >= right.base(); - } -}; - -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 - 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; + random_access_iterator &operator--() { + --_ptr; return *this; } - rev_iterator operator++(int) const { - rev_iterator tmp(*this); + random_access_iterator operator--(int) { + random_access_iterator ret(*this); --(*this); - return tmp; + return ret; } - rev_iterator &operator+=(const difference_type n) { - current -= n; + random_access_iterator &operator-=(const difference_type n) { + _ptr -= n; return *this; } - rev_iterator operator-(const difference_type n) const { - return (rev_iterator(current + n)); + friend bool operator==(const random_access_iterator &left, + const random_access_iterator &right) { + return left._ptr == right._ptr; } - rev_iterator &operator--() { - ++current; - return *this; - } - 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(); + friend bool operator!=(const random_access_iterator &left, + const random_access_iterator &right) { + return left._ptr != right._ptr; } - bool operator!=(const rev_iterator< T > &right) const { - return current != right.base(); + friend bool operator<(const random_access_iterator &left, + const random_access_iterator &right) { + return left._ptr < right._ptr; } - bool operator<(const rev_iterator< T > &right) const { - return current >= right.base(); + friend bool operator<=(const random_access_iterator &left, + const random_access_iterator &right) { + return left._ptr <= right._ptr; } - bool operator>(const rev_iterator< T > &right) const { - return current <= right.base(); + friend bool operator>(const random_access_iterator &left, + const random_access_iterator &right) { + return left._ptr > right._ptr; } - bool operator<=(const rev_iterator< T > &right) const { - return current > right.base(); + friend bool operator>=(const random_access_iterator &left, + const random_access_iterator &right) { + return left._ptr >= right._ptr; } - bool operator>=(const rev_iterator< T > &right) const { - return current < right.base(); + operator random_access_iterator< const T >() const { + return random_access_iterator< const T >(_ptr); } }; diff --git a/includes/reverse_iterator.hpp b/includes/reverse_iterator.hpp new file mode 100644 index 0000000..eb6d995 --- /dev/null +++ b/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 diff --git a/includes/vector.hpp b/includes/vector.hpp index e1f1273..7c21b27 100644 --- a/includes/vector.hpp +++ b/includes/vector.hpp @@ -1,5 +1,6 @@ #pragma once #include "iterator.hpp" +#include "reverse_iterator.hpp" #include "utils.hpp" #include @@ -8,33 +9,33 @@ namespace ft { -template < class T, class Allocator = std::allocator< T > > class vector { +template < class T, class Alloc = 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; + 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: - Allocator _alloc; + Alloc _alloc; pointer _begin; size_type _size; size_type _capacity; public: - explicit vector(const Allocator &alloc = allocator_type()) + explicit vector(const Alloc &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()) + 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++) @@ -42,14 +43,14 @@ public: } 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) : _alloc(alloc) { - _size = distance(first, last); + _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[i]); + _alloc.construct(_begin + i, *(first++)); } vector(const vector &other) @@ -77,23 +78,23 @@ public: return (*this); } - void assign(size_type count, cst_reference value) { + void assign(size_type count, const_reference value) { resize(count); - do { + while (count--) { _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); + 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; } @@ -104,47 +105,39 @@ public: throw(std::out_of_range("vector: Out of range access")); return *(_begin + pos); } - cst_reference at(size_type pos) const { + 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]; } - cst_reference operator[](size_type pos) const { 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]; } - cst_reference front(void) const { return _begin[0]; } + reference front(void) { return _begin[0]; } + const_reference front(void) const { return _begin[0]; } - reference back(void) { return _begin[_size - 1]; } - cst_reference back(void) const { return _begin[_size - 1]; } + reference back(void) { return _begin[_size - 1]; } + const_reference back(void) const { return _begin[_size - 1]; } - pointer data(void) { return _begin; } - cst_pointer data(void) const { return _begin; } + pointer data(void) { return _begin; } + const_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); - } + iterator begin(void) { return iterator(_begin); } + const_iterator begin(void) const { return const_iterator(_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); - } + iterator end(void) { return iterator(_begin + _size); } + const_iterator end(void) const { return const_iterator(_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()); + reverse_iterator rbegin(void) { return reverse_iterator(end()); } + const_reverse_iterator rbegin(void) const { + return const_reverse_iterator(end()); } - rev_iterator< iterator > rend(void) { - return rev_iterator< pointer >(begin()); - } - rev_iterator< cst_iterator > rend(void) const { - return rev_iterator< cst_pointer >(begin()); + reverse_iterator rend(void) { return reverse_iterator(begin()); } + const_reverse_iterator rend(void) const { + return const_reverse_iterator(begin()); } // CAPACITY: @@ -154,8 +147,8 @@ public: 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; + 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)); @@ -173,7 +166,7 @@ public: _alloc.destroy(_begin + i); _size = 0; } - iterator insert(iterator pos, cst_reference value) { + iterator insert(iterator pos, const_reference value) { if (_size == _capacity) resize(_size + 1); iterator it = end() + 1; @@ -183,7 +176,7 @@ public: *it = value; 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) resize(_size + count); iterator it = end() + count; @@ -196,22 +189,20 @@ public: return _begin; } 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) resize(_size + count); - iterator it = end() + count; + iterator it = end(); while (--it >= (pos + count)) *it = *(it - count); while (it >= pos) { - *it = *last; - it--; - last--; + *(--it) = *(--last); } return _begin; } iterator erase(iterator pos) { while (pos < end()) { - _alloc.destroy(pos); + _alloc.destroy(pos.base()); *pos = *(pos + 1); pos++; } @@ -220,35 +211,33 @@ public: } iterator erase(iterator first, iterator last) { while (last++ < end()) { - _alloc.destroy(first); + _alloc.destroy(first.base()); *(first++) = *last; } while (first < end() && _size--) { - _alloc.destroy(first); + _alloc.destroy(first.base()); *(first++) = value_type(); } return _begin; } - void push_back(cst_reference value) { + void push_back(const_reference value) { if (_size == _capacity) resize(_size + 1); - _alloc.construct(back(), value); + _alloc.construct(_begin + _size - 1, value); } void pop_back(void) { - _alloc.destroy(back()); + _alloc.destroy(_begin + _size - 1); _size--; } void resize(size_type count, T value = T()) { - size_type i = count; if (count < _size) { - while (i < _size && --_size) - _alloc.destroy(_begin + i); + while (count < --_size) + _alloc.destroy(_begin + _size); } else { if (count > _capacity) reserve(count); - while (i >= _size) - _alloc.construct(_begin + --i, value); - _size = count; + while (_size < count) + _alloc.construct(_begin + _size++, value); } } void swap(vector &other) { @@ -257,7 +246,7 @@ public: this = tmp; } void print(void) { - ft::ra_iterator< T > i = begin(); + ft::random_access_iterator< T > i = begin(); while (i < end()) { std::cout << *i << " "; i++; diff --git a/tester.cpp b/tester.cpp index a1ad581..a848ce2 100644 --- a/tester.cpp +++ b/tester.cpp @@ -64,9 +64,6 @@ void test_vectors(void) { 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.e) test5.capacity() | " << test5.capacity() << std::endl; - - - } int main(void) { test_vectors(); }