#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 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 * > { typedef random_access_iterator_tag iterator_category; typedef T value_type; typedef 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 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 random_access_iterator : public iterator< random_access_iterator_tag, T > { public: 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; public: random_access_iterator(pointer ptr = NULL) : _ptr(ptr) {} random_access_iterator(const random_access_iterator &other) : _ptr(other._ptr) {} random_access_iterator &operator=(const random_access_iterator &other) { _ptr = other._ptr; return *this; } pointer base(void) { return _ptr; } reference operator*(void) { return *_ptr; } random_access_iterator operator+(const difference_type n) const { return (random_access_iterator(_ptr + n)); } difference_type operator+(const random_access_iterator &right) const { return _ptr + right._ptr; } friend random_access_iterator operator+(const difference_type n, random_access_iterator &right) { return random_access_iterator(right._ptr + n); } random_access_iterator &operator++() { ++_ptr; return *this; } random_access_iterator operator++(int) { random_access_iterator ret(*this); ++(*this); return ret; } random_access_iterator &operator+=(const difference_type n) { _ptr += n; return *this; } random_access_iterator operator-(const difference_type n) const { return (random_access_iterator(_ptr - n)); } difference_type operator-(const random_access_iterator &right) const { return _ptr - right._ptr; } friend random_access_iterator operator-(const difference_type n, random_access_iterator &right) { return random_access_iterator(right._ptr - n); } random_access_iterator &operator--() { --_ptr; return *this; } random_access_iterator operator--(int) { random_access_iterator ret(*this); --(*this); return ret; } random_access_iterator &operator-=(const difference_type n) { _ptr -= n; return *this; } pointer operator->(void) { return _ptr; } reference operator[](const difference_type n) { return *(_ptr + n); } friend bool operator==(const random_access_iterator &left, const random_access_iterator &right) { return left._ptr == right._ptr; } friend bool operator!=(const random_access_iterator &left, const random_access_iterator &right) { return left._ptr != right._ptr; } friend bool operator<(const random_access_iterator &left, const random_access_iterator &right) { return left._ptr < right._ptr; } friend bool operator<=(const random_access_iterator &left, const random_access_iterator &right) { return left._ptr <= right._ptr; } friend bool operator>(const random_access_iterator &left, const random_access_iterator &right) { return left._ptr > right._ptr; } friend bool operator>=(const random_access_iterator &left, const random_access_iterator &right) { return left._ptr >= right._ptr; } operator random_access_iterator< const T >() const { return random_access_iterator< const T >(_ptr); } }; template < class It > std::size_t distance(It first, It last) { size_t ret = 1; while (first != last && ++ret) first++; return ret; } } // namespace ft