#pragma once #include #include // only for std/ft tags compatibility namespace ft { 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 std::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 std::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< std::random_access_iterator_tag, T > { public: typedef typename iterator< std::random_access_iterator_tag, T >::iterator_category iterator_category; typedef typename iterator< std::random_access_iterator_tag, T >::value_type value_type; typedef typename iterator< std::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) const { return _ptr; } reference operator*(void) const { return *_ptr; } random_access_iterator operator+(const difference_type n) const { return (random_access_iterator(_ptr + n)); } difference_type operator+(const random_access_iterator &rhs) const { return _ptr + rhs._ptr; } friend random_access_iterator operator+(const difference_type n, random_access_iterator &rhs) { return random_access_iterator(rhs._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)); } friend random_access_iterator operator-(const difference_type n, random_access_iterator &rhs) { return random_access_iterator(rhs._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 &lhs, const random_access_iterator &rhs) { return lhs._ptr == rhs._ptr; } friend bool operator!=(const random_access_iterator &lhs, const random_access_iterator &rhs) { return lhs._ptr != rhs._ptr; } friend bool operator<(const random_access_iterator &lhs, const random_access_iterator &rhs) { return lhs._ptr < rhs._ptr; } friend bool operator<=(const random_access_iterator &lhs, const random_access_iterator &rhs) { return lhs._ptr <= rhs._ptr; } friend bool operator>(const random_access_iterator &lhs, const random_access_iterator &rhs) { return lhs._ptr > rhs._ptr; } friend bool operator>=(const random_access_iterator &lhs, const random_access_iterator &rhs) { return lhs._ptr >= rhs._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 = 0; while (first != last && ++ret) first++; return ret; } template < class It1, class It2 > bool equal(It1 first1, It1 last1, It2 first2) { while (first1 != last1) { if (!(*first1 == *first2)) return false; ++first1; ++first2; } return true; } template < class It1, class It2, class BinaryPredicate > bool equal(It1 first1, It1 last1, It2 first2, BinaryPredicate pred) { while (first1 != last1) { if (!pred(*first1, *first2)) return false; ++first1; ++first2; } return true; } template < class It1, class It2 > bool lexicographical_compare(It1 first1, It1 last1, It2 first2, It2 last2) { while (first1 != last1) { if (first2 == last2 || *first2 < *first1) return false; else if (*first1 < *first2) return true; ++first1; ++first2; } return (first2 != last2); } template < class It1, class It2, class Compare > bool lexicographical_compare(It1 first1, It1 last1, It2 first2, It2 last2, Compare comp) { while (first1 != last1) { if (first2 == last2 || comp(*first2, *first1)) return false; else if (comp(*first1, *first2)) return true; ++first1; ++first2; } return (first2 != last2); } template < class T1, class T2 > typename random_access_iterator< T1 >::difference_type operator-(const random_access_iterator< T1 > &lhs, const random_access_iterator< T2 > &rhs) { return lhs.base() - rhs.base(); } } // namespace ft