| 303 | |
| 304 | template <typename Value, typename Diff = int> |
| 305 | class RangeIterator { |
| 306 | using iterator_category = std::random_access_iterator_tag; |
| 307 | using value_type = Value; |
| 308 | using difference_type = Diff; |
| 309 | using pointer = Value*; |
| 310 | using reference = Value&; |
| 311 | |
| 312 | public: |
| 313 | RangeIterator() : m_start(), m_end(), m_diff(1), m_current(), m_stop(true) {} |
| 314 | |
| 315 | RangeIterator(Value min, Value max, Diff diff) |
| 316 | : m_start(min), m_end(max), m_diff(diff), m_current(min), m_stop(false) { |
| 317 | sanity(); |
| 318 | } |
| 319 | |
| 320 | RangeIterator(Value min, Value max) : m_start(min), m_end(max), m_diff(1), m_current(min), m_stop(false) { |
| 321 | sanity(); |
| 322 | } |
| 323 | |
| 324 | RangeIterator(Value max) : m_start(), m_end(max), m_diff(1), m_current(), m_stop(false) { |
| 325 | sanity(); |
| 326 | } |
| 327 | |
| 328 | RangeIterator(RangeIterator const& rhs) { |
| 329 | copy(rhs); |
| 330 | } |
| 331 | |
| 332 | RangeIterator& operator=(RangeIterator const& rhs) { |
| 333 | copy(rhs); |
| 334 | return *this; |
| 335 | } |
| 336 | |
| 337 | RangeIterator& operator+=(Diff steps) { |
| 338 | if ((applySteps(m_current, m_diff * steps) >= m_end) != (RangeHelper::checkIfDiffLessThanZero<Diff>(m_diff))) { |
| 339 | if (!m_stop) { |
| 340 | Diff stepsLeft = stepsBetween(m_current, m_end); |
| 341 | m_current = applySteps(m_current, stepsLeft * m_diff); |
| 342 | m_stop = true; |
| 343 | } |
| 344 | } else { |
| 345 | m_current = applySteps(m_current, steps * m_diff); |
| 346 | } |
| 347 | return *this; |
| 348 | } |
| 349 | |
| 350 | RangeIterator operator-=(Diff steps) { |
| 351 | m_stop = false; |
| 352 | sanity(); |
| 353 | |
| 354 | if (applySteps(m_current, -(m_diff * steps)) < m_start) |
| 355 | m_current = m_start; |
| 356 | else |
| 357 | m_current = applySteps(m_current, -(m_diff * steps)); |
| 358 | |
| 359 | return *this; |
| 360 | } |
| 361 | |
| 362 | Value operator*() const { |