RPNX::DataStructures
Header-only C++ data structures and supporting utilities.
Loading...
Searching...
No Matches
iterator.hpp
1// Copyright (c) 2026 Ryan P. Nicholl
2
3#ifndef RPNX_ITERATOR_HPP
4#define RPNX_ITERATOR_HPP
5
6#include <iterator>
7#include <stdexcept>
8#include <type_traits>
9#include <utility>
10
11namespace rpnx
12{
23 template < class It >
25 {
26 using traits = std::iterator_traits< It >;
27
28 static_assert(std::is_base_of_v< std::forward_iterator_tag, typename traits::iterator_category >, "rpnx::bounded_iterator requires a forward iterator");
29
30 public:
32 using iterator_type = It;
34 using iterator_category = typename traits::iterator_category;
36 using value_type = typename traits::value_type;
38 using difference_type = typename traits::difference_type;
40 using pointer = typename traits::pointer;
42 using reference = typename traits::reference;
43
45 bounded_iterator() = default;
46
52 constexpr bounded_iterator(It current, It last) : m_current(current), m_last(last)
53 {
54 }
55
57 constexpr reference operator*() const
58 {
59 if (m_current == m_last) [[unlikely]]
60 {
61 throw std::out_of_range("rpnx::bounded_iterator: dereference at end");
62 }
63 return *m_current;
64 }
65
67 constexpr pointer operator->() const
68 {
69 if (m_current == m_last) [[unlikely]]
70 {
71 throw std::out_of_range("rpnx::bounded_iterator: dereference at end");
72 }
73 return std::addressof(*m_current);
74 }
75
78 {
79 if (m_current == m_last) [[unlikely]]
80 {
81 throw std::out_of_range("rpnx::bounded_iterator: ++ at end");
82 }
83 ++m_current;
84 return *this;
85 }
86
89 {
90 bounded_iterator tmp = *this;
91 ++(*this);
92 return tmp;
93 }
94
96 constexpr bool operator==(const bounded_iterator& rhs) const
97 {
98 return m_current == rhs.m_current;
99 }
100
102 constexpr bool operator!=(const bounded_iterator& rhs) const
103 {
104 return !(*this == rhs);
105 }
106
107 private:
108 It m_current{};
109 It m_last{};
110 };
111
122 template < class It >
124 {
125 using traits = std::iterator_traits< It >;
126
127 static_assert(std::is_base_of_v< std::random_access_iterator_tag, typename traits::iterator_category >, "rpnx::bounded_iterator requires a random-access iterator");
128
129 public:
131 using iterator_type = It;
133 using iterator_category = typename traits::iterator_category;
135 using value_type = typename traits::value_type;
137 using difference_type = typename traits::difference_type;
139 using pointer = typename traits::pointer;
141 using reference = typename traits::reference;
142
145
153 constexpr bidirectional_bounded_iterator(It current, It first, It last) : m_current(current), m_first(first), m_last(last)
154 {
155 }
156
158 constexpr reference operator*() const
159 {
160 if (!(m_current >= m_first && m_current < m_last)) [[unlikely]]
161 {
162 throw std::out_of_range("rpnx::bounded_iterator: dereference out of range");
163 }
164 return *m_current;
165 }
166
168 constexpr pointer operator->() const
169 {
170 if (!(m_current >= m_first && m_current < m_last)) [[unlikely]]
171 {
172 throw std::out_of_range("rpnx::bounded_iterator: dereference out of range");
173 }
174 return std::addressof(*m_current);
175 }
176
179 {
180 if (!(m_current < m_last)) [[unlikely]]
181 {
182 throw std::out_of_range("rpnx::bounded_iterator: ++ past end");
183 }
184 ++m_current;
185 return *this;
186 }
187
190 {
192 ++(*this);
193 return tmp;
194 }
195
198 {
199 if (!(m_current > m_first)) [[unlikely]]
200 {
201 throw std::out_of_range("rpnx::bounded_iterator: -- before begin");
202 }
203 --m_current;
204 return *this;
205 }
206
209 {
211 --(*this);
212 return tmp;
213 }
214
217 {
218 if (n >= 0)
219 {
220 auto max = std::distance(m_current, m_last);
221 if (n > max) [[unlikely]]
222 {
223 throw std::out_of_range("rpnx::bounded_iterator: += past end");
224 }
225 m_current += n;
226 return *this;
227 }
228 else
229 {
230 auto max = std::distance(m_first, m_current);
231 if (n < -max) [[unlikely]]
232 {
233 throw std::out_of_range("rpnx::bounded_iterator: += before begin");
234 }
235 m_current += n;
236 return *this;
237 }
238 }
239
242 {
243 return (*this) += (-n);
244 }
245
248 {
250 tmp += n;
251 return tmp;
252 }
253
256 {
257 return it + n;
258 }
259
262 {
264 tmp -= n;
265 return tmp;
266 }
267
270 {
271 return *(*this + n);
272 }
273
276 {
277 return m_current - other.m_current;
278 }
279
281 constexpr bool operator==(const bidirectional_bounded_iterator& other) const
282 {
283 return m_current == other.m_current;
284 }
285
287 constexpr bool operator!=(const bidirectional_bounded_iterator& other) const
288 {
289 return !(*this == other);
290 }
291
293 constexpr bool operator<(const bidirectional_bounded_iterator& other) const
294 {
295 return m_current < other.m_current;
296 }
297
299 constexpr bool operator>(const bidirectional_bounded_iterator& other) const
300 {
301 return other < *this;
302 }
303
304 constexpr bool operator<=(const bidirectional_bounded_iterator& other) const
305 {
306 return !(other < *this);
307 }
308
309 constexpr bool operator>=(const bidirectional_bounded_iterator& other) const
310 {
311 return !(*this < other);
312 }
313
314 private:
315 It m_current{};
316 It m_first{};
317 It m_last{};
318 };
319
321 template < class It >
322 constexpr bidirectional_bounded_iterator< It > make_bounded_iterator(It it, It first, It last) noexcept
323 {
324 return bidirectional_bounded_iterator< It >(it, first, last);
325 }
326
328 template < class It >
329 constexpr bounded_iterator< It > make_bounded_iterator(It it, It last) noexcept
330 {
331 return bounded_iterator< It >(it, last);
332 }
333} // namespace rpnx
334
335#endif // RPNX_ITERATOR_HPP
Random-access iterator adapter with bidirectional range checks.
Definition iterator.hpp:124
constexpr bool operator!=(const bidirectional_bounded_iterator &other) const
Compares positions for inequality.
Definition iterator.hpp:287
constexpr reference operator*() const
Dereferences the current position.
Definition iterator.hpp:158
typename traits::difference_type difference_type
Signed iterator-distance type.
Definition iterator.hpp:137
constexpr reference operator[](difference_type n) const
Dereferences an offset position.
Definition iterator.hpp:269
typename traits::reference reference
Reference type returned by dereference.
Definition iterator.hpp:141
constexpr bidirectional_bounded_iterator operator+(difference_type n) const
Returns an iterator moved by an offset.
Definition iterator.hpp:247
friend constexpr bidirectional_bounded_iterator operator+(difference_type n, const bidirectional_bounded_iterator &it)
Returns an iterator moved by an offset.
Definition iterator.hpp:255
constexpr difference_type operator-(const bidirectional_bounded_iterator &other) const
Computes the distance from another iterator.
Definition iterator.hpp:275
typename traits::pointer pointer
Pointer type returned by member access.
Definition iterator.hpp:139
constexpr bool operator<(const bidirectional_bounded_iterator &other) const
Tests whether this position precedes another.
Definition iterator.hpp:293
typename traits::iterator_category iterator_category
Iterator category exposed by the wrapped iterator.
Definition iterator.hpp:133
typename traits::value_type value_type
Iterated value type.
Definition iterator.hpp:135
constexpr bidirectional_bounded_iterator & operator--()
Retreats one position.
Definition iterator.hpp:197
constexpr bidirectional_bounded_iterator & operator-=(difference_type n)
Moves backward by an offset with range checking.
Definition iterator.hpp:241
constexpr bidirectional_bounded_iterator operator++(int)
Advances one position.
Definition iterator.hpp:189
constexpr bool operator>=(const bidirectional_bounded_iterator &other) const
Tests whether this position does not precede another.
Definition iterator.hpp:309
constexpr bidirectional_bounded_iterator operator-(difference_type n) const
Returns an iterator moved backward by an offset.
Definition iterator.hpp:261
constexpr pointer operator->() const
Accesses the current element.
Definition iterator.hpp:168
constexpr bool operator==(const bidirectional_bounded_iterator &other) const
Compares positions for equality.
Definition iterator.hpp:281
bidirectional_bounded_iterator()=default
Constructs value-initialized current, first, and last iterators.
constexpr bidirectional_bounded_iterator operator--(int)
Retreats one position.
Definition iterator.hpp:208
constexpr bool operator<=(const bidirectional_bounded_iterator &other) const
Tests whether this position does not follow another.
Definition iterator.hpp:304
constexpr bidirectional_bounded_iterator(It current, It first, It last)
Constructs a bounded adapter over an underlying range.
Definition iterator.hpp:153
constexpr bidirectional_bounded_iterator & operator++()
Advances one position.
Definition iterator.hpp:178
constexpr bool operator>(const bidirectional_bounded_iterator &other) const
Tests whether this position follows another.
Definition iterator.hpp:299
constexpr bidirectional_bounded_iterator & operator+=(difference_type n)
Moves by an offset with range checking.
Definition iterator.hpp:216
It iterator_type
Wrapped iterator type.
Definition iterator.hpp:131
Forward iterator adapter that checks access against an end sentinel.
Definition iterator.hpp:25
constexpr reference operator*() const
Dereferences the current position.
Definition iterator.hpp:57
It iterator_type
Wrapped iterator type.
Definition iterator.hpp:32
bounded_iterator()=default
Constructs a value-initialized iterator and sentinel.
typename traits::value_type value_type
Iterated value type.
Definition iterator.hpp:36
constexpr bounded_iterator(It current, It last)
Constructs an adapter for a current position and end sentinel.
Definition iterator.hpp:52
constexpr bool operator!=(const bounded_iterator &rhs) const
Compares current positions for inequality.
Definition iterator.hpp:102
typename traits::difference_type difference_type
Signed iterator-distance type.
Definition iterator.hpp:38
constexpr pointer operator->() const
Accesses the current element.
Definition iterator.hpp:67
typename traits::pointer pointer
Pointer type returned by member access.
Definition iterator.hpp:40
constexpr bounded_iterator operator++(int)
Advances to the next position.
Definition iterator.hpp:88
constexpr bounded_iterator & operator++()
Advances to the next position.
Definition iterator.hpp:77
constexpr bool operator==(const bounded_iterator &rhs) const
Compares current positions.
Definition iterator.hpp:96
typename traits::iterator_category iterator_category
Iterator category exposed by the wrapped iterator.
Definition iterator.hpp:34
typename traits::reference reference
Reference type returned by dereference.
Definition iterator.hpp:42
Containers, iterator adapters, callable wrappers, and value utilities.
Definition annex.hpp:14
constexpr bidirectional_bounded_iterator< It > make_bounded_iterator(It it, It first, It last) noexcept
Creates a two-sided bounded random-access iterator.
Definition iterator.hpp:322