#pragma once #include namespace ft { struct input_iterator_tag {}; struct output_iterator_tag {}; 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 class Iter::iterator_category iterator_category; typedef class Iter::value_type value_type; typedef class Iter::difference_type difference_type; typedef class Iter::pointer pointer; typedef class Iter::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 T *pointer; typedef T &reference; }; 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; }; // Iterator classes: 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; T current; public: ra_iterator(T 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); } T 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); } ra_iterator operator+(const difference_type n) const { return (iterator(current + n)); } ra_iterator &operator++() { ++current; return *this; } ra_iterator operator++(int) { ra_iterator tmp(*this); ++(*this); return tmp; } ra_iterator &operator+=(const difference_type other) { current += other; return *this; } ra_iterator operator-(const difference_type n) const { return (iterator(current - n)); } ra_iterator &operator--() { --current; return *this; } ra_iterator operator--(int) { ra_iterator tmp(*this); --(*this); return tmp; } ra_iterator &operator-=(const difference_type other) { current -= other; 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(); } 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(); } }; 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: rev_iterator(T 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; } rev_iterator operator++(int) const { rev_iterator tmp(*this); --(*this); return tmp; } rev_iterator &operator+=(const difference_type n) { current -= n; return *this; } rev_iterator operator-(const difference_type n) const { return (rev_iterator(current + n)); } 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(); } bool operator!=(const rev_iterator< T > &right) const { return current != right.base(); } bool operator<(const rev_iterator< T > &right) const { return current >= right.base(); } bool operator>(const rev_iterator< T > &right) const { return current <= right.base(); } bool operator<=(const rev_iterator< T > &right) const { return current > right.base(); } bool operator>=(const rev_iterator< T > &right) const { return current < right.base(); } }; template < class It > std::size_t distance(It first, It last) { size_t ret = 0; while (first != last && ret++) first++; return ret; } } // namespace ft