TermOx
transform_iterator.hpp
1 #ifndef TERMOX_COMMON_TRANSFORM_ITERATOR_HPP
2 #define TERMOX_COMMON_TRANSFORM_ITERATOR_HPP
3 #include <cstddef>
4 #include <iterator>
5 #include <type_traits>
6 #include <utility>
7 
8 namespace ox {
9 
11 
14 template <typename Iter, typename Map_fn>
16  public:
17  using iterator_category = typename Iter::iterator_category;
18  using difference_type = typename Iter::difference_type;
19  using reference = std::invoke_result_t<Map_fn, typename Iter::reference>;
20  using value_type = std::remove_reference_t<reference>;
21  using pointer = value_type*;
22 
23  public:
24  Transform_iterator(Iter it, Map_fn map_fn)
25  : it_{it}, map_fn_{std::move(map_fn)}
26  {}
27 
28  Transform_iterator(Transform_iterator const&) = default;
29 
31 
32  Transform_iterator& operator=(Transform_iterator const& other)
33  {
34  it_ = other.it_;
35  return *this;
36  }
37  Transform_iterator& operator=(Transform_iterator&&) = default;
38 
39  public:
40  auto operator++() -> Transform_iterator&
41  {
42  ++it_;
43  return *this;
44  }
45 
46  [[nodiscard]] auto operator++(int) -> Transform_iterator
47  {
48  return {it_++, map_fn_};
49  }
50 
51  auto operator+=(difference_type n) -> Transform_iterator&
52  {
53  it_ += n;
54  return *this;
55  }
56 
57  [[nodiscard]] auto operator+(difference_type n) -> Transform_iterator
58  {
59  return {it_ + n, map_fn_};
60  }
61 
62  [[nodiscard]] friend auto operator+(difference_type n,
63  Transform_iterator const& it)
65  {
66  return {n + it.underlying(), it.map_fn_};
67  }
68 
69  auto operator--() -> Transform_iterator&
70  {
71  --it_;
72  return *this;
73  }
74 
75  [[nodiscard]] auto operator--(int) -> Transform_iterator
76  {
77  return {it_--, map_fn_};
78  }
79 
80  auto operator-=(difference_type n) -> Transform_iterator&
81  {
82  it_ -= n;
83  return *this;
84  }
85 
86  [[nodiscard]] auto operator-(Transform_iterator const& other)
87  -> difference_type
88  {
89  return it_ - other.it_;
90  }
91 
92  [[nodiscard]] auto operator-(difference_type n) -> Transform_iterator
93  {
94  return {it_ - n, map_fn_};
95  }
96 
97  [[nodiscard]] auto operator*() const -> reference { return map_fn_(*it_); }
98 
99  [[nodiscard]] auto operator==(Transform_iterator const& other) const -> bool
100  {
101  return it_ == other.it_;
102  }
103 
104  [[nodiscard]] auto operator!=(Transform_iterator const& other) const -> bool
105  {
106  return it_ != other.it_;
107  }
108 
109  template <typename T>
110  [[nodiscard]] auto operator==(T const& other) const -> bool
111  {
112  return it_ == other;
113  }
114 
115  template <typename T>
116  [[nodiscard]] auto operator!=(T const& other) const -> bool
117  {
118  return it_ != other;
119  }
120 
121  [[nodiscard]] auto underlying() const -> Iter { return it_; }
122 
123  private:
124  Iter it_;
125  Map_fn map_fn_;
126 };
127 
128 template <typename Iter, typename Map_fn>
129 [[nodiscard]] auto operator<(Transform_iterator<Iter, Map_fn> const& a,
130  Transform_iterator<Iter, Map_fn> const& b) -> bool
131 {
132  return a.underlying() < b.underlying();
133 }
134 
135 template <typename Iter, typename Map_fn>
136 [[nodiscard]] auto operator<=(Transform_iterator<Iter, Map_fn> const& a,
137  Transform_iterator<Iter, Map_fn> const& b) -> bool
138 {
139  return a.underlying() <= b.underlying();
140 }
141 
142 template <typename Iter, typename Map_fn>
143 [[nodiscard]] auto operator>(Transform_iterator<Iter, Map_fn> const& a,
144  Transform_iterator<Iter, Map_fn> const& b) -> bool
145 {
146  return a.underlying() > b.underlying();
147 }
148 
149 template <typename Iter, typename Map_fn>
150 [[nodiscard]] auto operator>=(Transform_iterator<Iter, Map_fn> const& a,
151  Transform_iterator<Iter, Map_fn> const& b) -> bool
152 {
153  return a.underlying() >= b.underlying();
154 }
155 
156 } // namespace ox
157 #endif // TERMOX_COMMON_TRANSFORM_ITERATOR_HPP
operator*() will apply map to the result of the underlying deref result.
Definition: transform_iterator.hpp:15