#ifndef CTL_MOVE_ITERATOR_H_ #define CTL_MOVE_ITERATOR_H_ #include "iterator_traits.h" namespace ctl { template class move_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 = Iterator; using reference = value_type&&; constexpr move_iterator() : current() { } explicit constexpr move_iterator(Iterator i) : current(i) { } template constexpr move_iterator(const move_iterator& u) : current(u.base()) { } constexpr Iterator base() const { return current; } constexpr reference operator*() const { return static_cast(*current); } constexpr pointer operator->() const { return current; } constexpr move_iterator& operator++() { ++current; return *this; } constexpr move_iterator operator++(int) { move_iterator tmp = *this; ++current; return tmp; } constexpr move_iterator& operator--() { --current; return *this; } constexpr move_iterator operator--(int) { move_iterator tmp = *this; --current; return tmp; } constexpr move_iterator operator+(difference_type n) const { return move_iterator(current + n); } constexpr move_iterator& operator+=(difference_type n) { current += n; return *this; } constexpr move_iterator operator-(difference_type n) const { return move_iterator(current - n); } constexpr move_iterator& operator-=(difference_type n) { current -= n; return *this; } constexpr reference operator[](difference_type n) const { return ctl::move(current[n]); } private: Iterator current; }; template __attribute__((__always_inline__)) constexpr move_iterator make_move_iterator(Iterator i) { return move_iterator(i); } template constexpr bool operator==(const move_iterator& x, const move_iterator& y) { return x.base() == y.base(); } template constexpr bool operator!=(const move_iterator& x, const move_iterator& y) { return !(x == y); } template constexpr bool operator<(const move_iterator& x, const move_iterator& y) { return x.base() < y.base(); } template constexpr bool operator<=(const move_iterator& x, const move_iterator& y) { return !(y < x); } template constexpr bool operator>(const move_iterator& x, const move_iterator& y) { return y < x; } template constexpr bool operator>=(const move_iterator& x, const move_iterator& y) { return !(x < y); } template constexpr move_iterator operator+(typename move_iterator::difference_type n, const move_iterator& x) { return x + n; } template constexpr auto operator-(const move_iterator& x, const move_iterator& y) -> decltype(x.base() - y.base()) { return x.base() - y.base(); } } // namespace ctl #endif // CTL_MOVE_ITERATOR_H_