// -*-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 reverse_iterator { public: using iterator_type = Iterator; using iterator_category = typename ctl::iterator_traits::iterator_category; using value_type = typename ctl::iterator_traits::value_type; using difference_type = typename ctl::iterator_traits::difference_type; using pointer = typename ctl::iterator_traits::pointer; using reference = typename ctl::iterator_traits::reference; constexpr reverse_iterator() : current() { } constexpr explicit reverse_iterator(Iterator x) : current(x) { } template constexpr reverse_iterator(const reverse_iterator& other) : current(other.base()) { } template constexpr reverse_iterator& operator=(const reverse_iterator& 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 constexpr bool operator==(const reverse_iterator& lhs, const reverse_iterator& rhs) { return lhs.base() == rhs.base(); } template constexpr bool operator!=(const reverse_iterator& lhs, const reverse_iterator& rhs) { return lhs.base() != rhs.base(); } template constexpr bool operator<(const reverse_iterator& lhs, const reverse_iterator& rhs) { return rhs.base() < lhs.base(); } template constexpr bool operator<=(const reverse_iterator& lhs, const reverse_iterator& rhs) { return !(rhs < lhs); } template constexpr bool operator>(const reverse_iterator& lhs, const reverse_iterator& rhs) { return rhs < lhs; } template constexpr bool operator>=(const reverse_iterator& lhs, const reverse_iterator& rhs) { return !(lhs < rhs); } template constexpr reverse_iterator operator+(typename reverse_iterator::difference_type n, const reverse_iterator& it) { return reverse_iterator(it.base() - n); } template constexpr auto operator-(const reverse_iterator& lhs, const reverse_iterator& rhs) -> decltype(rhs.base() - lhs.base()) { return rhs.base() - lhs.base(); } } // namespace ctl #endif // CTL_REVERSE_ITERATOR_H_