unkeyed_iterator.hpp 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
  1. //
  2. // unkeyed_iterator.hpp
  3. // iterator
  4. //
  5. // Created by Sam Jaffe on 2/20/17.
  6. //
  7. #pragma once
  8. #include <iterator>
  9. namespace iterator {
  10. template <typename Iterator>
  11. class unkeyed_iterator {
  12. private:
  13. using impl_value_type = typename std::iterator_traits<Iterator>::value_type;
  14. using impl_reference = typename std::iterator_traits<Iterator>::reference;
  15. static constexpr std::size_t const value_index = std::tuple_size<impl_value_type>::value - 1;
  16. public:
  17. using value_type = typename std::remove_reference<decltype(std::get<value_index>(std::declval<impl_value_type>()))>::type;
  18. using reference = decltype(std::get<value_index>(std::declval<impl_reference>()));
  19. using pointer = value_type *;
  20. using difference_type = typename std::iterator_traits<Iterator>::difference_type;
  21. using iterator_category = typename std::iterator_traits<Iterator>::iterator_category;
  22. unkeyed_iterator() = default;
  23. unkeyed_iterator(Iterator it) : base(it) {}
  24. reference operator*() const { return std::get<value_index>(*base); }
  25. pointer operator->() const { return std::addressof(operator*()); }
  26. unkeyed_iterator & operator++() { ++base; return *this; }
  27. unkeyed_iterator operator++(int) { unkeyed_iterator tmp{*this}; operator++(); return tmp; }
  28. unkeyed_iterator & operator--() { --base; return *this; }
  29. unkeyed_iterator operator--(int) { unkeyed_iterator tmp{*this}; operator--(); return tmp; }
  30. unkeyed_iterator operator+(difference_type n) const { return unkeyed_iterator{*this} += n; }
  31. unkeyed_iterator & operator+=(difference_type n) { base += n; return *this; }
  32. unkeyed_iterator operator-(difference_type n) const { return unkeyed_iterator{*this} -= n; }
  33. unkeyed_iterator & operator-=(difference_type n) { base -= n;return *this; }
  34. bool operator==(unkeyed_iterator const & other) const { return base == other.base; }
  35. bool operator!=(unkeyed_iterator const & other) const { return base != other.base; }
  36. bool operator< (unkeyed_iterator const & other) const { return base < other.base; }
  37. bool operator<=(unkeyed_iterator const & other) const { return !(other < *this); }
  38. private:
  39. Iterator base;
  40. };
  41. }