mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-01-31 03:27:39 +00:00
184 lines
4.2 KiB
C
184 lines
4.2 KiB
C
|
// -*-mode:c++;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8-*-
|
||
|
// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi
|
||
|
#ifndef CTL_REVERSE_ITERATOR_H_
|
||
|
#define CTL_REVERSE_ITERATOR_H_
|
||
|
#include "iterator_traits.h"
|
||
|
#include "utility.h"
|
||
|
|
||
|
namespace ctl {
|
||
|
|
||
|
template<class Iterator>
|
||
|
class reverse_iterator
|
||
|
{
|
||
|
public:
|
||
|
using iterator_type = Iterator;
|
||
|
using iterator_category =
|
||
|
typename iterator_traits<Iterator>::iterator_category;
|
||
|
using value_type = typename iterator_traits<Iterator>::value_type;
|
||
|
using difference_type = typename iterator_traits<Iterator>::difference_type;
|
||
|
using pointer = typename iterator_traits<Iterator>::pointer;
|
||
|
using reference = typename iterator_traits<Iterator>::reference;
|
||
|
|
||
|
constexpr reverse_iterator() : current()
|
||
|
{
|
||
|
}
|
||
|
|
||
|
constexpr explicit reverse_iterator(Iterator x) : current(x)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
template<class U>
|
||
|
constexpr reverse_iterator(const reverse_iterator<U>& other)
|
||
|
: current(other.base())
|
||
|
{
|
||
|
}
|
||
|
|
||
|
template<class U>
|
||
|
constexpr reverse_iterator& operator=(const reverse_iterator<U>& other)
|
||
|
{
|
||
|
current = other.base();
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
constexpr Iterator base() const
|
||
|
{
|
||
|
return current;
|
||
|
}
|
||
|
|
||
|
constexpr reference operator*() const
|
||
|
{
|
||
|
Iterator tmp = current;
|
||
|
return *--tmp;
|
||
|
}
|
||
|
|
||
|
constexpr pointer operator->() const
|
||
|
{
|
||
|
return &(operator*());
|
||
|
}
|
||
|
|
||
|
constexpr reverse_iterator& operator++()
|
||
|
{
|
||
|
--current;
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
constexpr reverse_iterator operator++(int)
|
||
|
{
|
||
|
reverse_iterator tmp = *this;
|
||
|
--current;
|
||
|
return tmp;
|
||
|
}
|
||
|
|
||
|
constexpr reverse_iterator& operator--()
|
||
|
{
|
||
|
++current;
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
constexpr reverse_iterator operator--(int)
|
||
|
{
|
||
|
reverse_iterator tmp = *this;
|
||
|
++current;
|
||
|
return tmp;
|
||
|
}
|
||
|
|
||
|
constexpr reverse_iterator operator+(difference_type n) const
|
||
|
{
|
||
|
return reverse_iterator(current - n);
|
||
|
}
|
||
|
|
||
|
constexpr reverse_iterator& operator+=(difference_type n)
|
||
|
{
|
||
|
current -= n;
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
constexpr reverse_iterator operator-(difference_type n) const
|
||
|
{
|
||
|
return reverse_iterator(current + n);
|
||
|
}
|
||
|
|
||
|
constexpr reverse_iterator& operator-=(difference_type n)
|
||
|
{
|
||
|
current += n;
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
constexpr reference operator[](difference_type n) const
|
||
|
{
|
||
|
return *(*this + n);
|
||
|
}
|
||
|
|
||
|
protected:
|
||
|
Iterator current;
|
||
|
};
|
||
|
|
||
|
template<class Iterator1, class Iterator2>
|
||
|
constexpr bool
|
||
|
operator==(const reverse_iterator<Iterator1>& lhs,
|
||
|
const reverse_iterator<Iterator2>& rhs)
|
||
|
{
|
||
|
return lhs.base() == rhs.base();
|
||
|
}
|
||
|
|
||
|
template<class Iterator1, class Iterator2>
|
||
|
constexpr bool
|
||
|
operator!=(const reverse_iterator<Iterator1>& lhs,
|
||
|
const reverse_iterator<Iterator2>& rhs)
|
||
|
{
|
||
|
return lhs.base() != rhs.base();
|
||
|
}
|
||
|
|
||
|
template<class Iterator1, class Iterator2>
|
||
|
constexpr bool
|
||
|
operator<(const reverse_iterator<Iterator1>& lhs,
|
||
|
const reverse_iterator<Iterator2>& rhs)
|
||
|
{
|
||
|
return rhs.base() < lhs.base();
|
||
|
}
|
||
|
|
||
|
template<class Iterator1, class Iterator2>
|
||
|
constexpr bool
|
||
|
operator<=(const reverse_iterator<Iterator1>& lhs,
|
||
|
const reverse_iterator<Iterator2>& rhs)
|
||
|
{
|
||
|
return !(rhs < lhs);
|
||
|
}
|
||
|
|
||
|
template<class Iterator1, class Iterator2>
|
||
|
constexpr bool
|
||
|
operator>(const reverse_iterator<Iterator1>& lhs,
|
||
|
const reverse_iterator<Iterator2>& rhs)
|
||
|
{
|
||
|
return rhs < lhs;
|
||
|
}
|
||
|
|
||
|
template<class Iterator1, class Iterator2>
|
||
|
constexpr bool
|
||
|
operator>=(const reverse_iterator<Iterator1>& lhs,
|
||
|
const reverse_iterator<Iterator2>& rhs)
|
||
|
{
|
||
|
return !(lhs < rhs);
|
||
|
}
|
||
|
|
||
|
template<class Iterator>
|
||
|
constexpr reverse_iterator<Iterator>
|
||
|
operator+(typename reverse_iterator<Iterator>::difference_type n,
|
||
|
const reverse_iterator<Iterator>& it)
|
||
|
{
|
||
|
return reverse_iterator<Iterator>(it.base() - n);
|
||
|
}
|
||
|
|
||
|
template<class Iterator1, class Iterator2>
|
||
|
constexpr auto
|
||
|
operator-(const reverse_iterator<Iterator1>& lhs,
|
||
|
const reverse_iterator<Iterator2>& rhs) -> decltype(rhs.base() -
|
||
|
lhs.base())
|
||
|
{
|
||
|
return rhs.base() - lhs.base();
|
||
|
}
|
||
|
|
||
|
} // namespace ctl
|
||
|
|
||
|
#endif // CTL_REVERSE_ITERATOR_H_
|