You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
231 lines
6.3 KiB
231 lines
6.3 KiB
#pragma once
|
|
#include <cstddef>
|
|
#include <iterator> // 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
|
|
|