Gamedev Framework (gf) 1.2.0
A C++17 framework for 2D games
Range.h
1/*
2 * Gamedev Framework (gf)
3 * Copyright (C) 2016-2022 Julien Bernard
4 *
5 * This software is provided 'as-is', without any express or implied
6 * warranty. In no event will the authors be held liable for any damages
7 * arising from the use of this software.
8 *
9 * Permission is granted to anyone to use this software for any purpose,
10 * including commercial applications, and to alter it and redistribute it
11 * freely, subject to the following restrictions:
12 *
13 * 1. The origin of this software must not be misrepresented; you must not
14 * claim that you wrote the original software. If you use this software
15 * in a product, an acknowledgment in the product documentation would be
16 * appreciated but is not required.
17 * 2. Altered source versions must be plainly marked as such, and must not be
18 * misrepresented as being the original software.
19 * 3. This notice may not be removed or altered from any source distribution.
20 */
21#ifndef GF_RANGE_H
22#define GF_RANGE_H
23
24#include <cstddef>
25#include <iterator>
26
27#include "CoreApi.h"
28#include "Math.h"
29#include "Vector.h"
30
31namespace gf {
32#ifndef DOXYGEN_SHOULD_SKIP_THIS
33inline namespace v1 {
34#endif
35
43 template<typename T>
44 struct Range {
45 T lo;
46 T hi;
47
52 struct Iterator {
53 using difference_type = std::ptrdiff_t;
54 using value_type = T;
57 using iterator_category = std::bidirectional_iterator_tag;
58
60
66 constexpr Iterator(T iteratorIndex) noexcept
67 : index(iteratorIndex)
68 {
69 }
70
74 void swap(Iterator& other) noexcept {
75 using std::swap;
76 swap(index, other.index);
77 }
78
84 reference operator*() noexcept {
85 return index;
86 }
87
93 pointer operator->() noexcept {
94 return index;
95 }
96
102 Iterator& operator++() noexcept {
103 ++index;
104 return *this;
105 }
106
112 Iterator operator++(int) noexcept {
113 Iterator copy = *this;
114 ++index;
115 return copy;
116 }
117
123 Iterator& operator--() noexcept {
124 --index;
125 return *this;
126 }
127
133 Iterator operator--(int) noexcept {
134 Iterator copy = *this;
135 --index;
136 return copy;
137 }
138
145 constexpr bool operator!=(const Iterator& other) const noexcept {
146 return index != other.index;
147 }
148
155 constexpr bool operator==(const Iterator& other) const noexcept {
156 return index == other.index;
157 }
158 };
159
166 constexpr bool contains(T value) const noexcept {
167 return lo <= value && value < hi;
168 }
169
176 constexpr Iterator begin() const noexcept {
177 return Iterator(lo);
178 }
179
186 constexpr Iterator end() const noexcept {
187 return Iterator(hi);
188 }
189
195 constexpr T length() const noexcept {
196 return hi - lo;
197 }
198
205 constexpr bool isEmpty() const noexcept {
206 return lo >= hi;
207 }
208
215 constexpr bool isValid() const noexcept {
216 return lo <= hi;
217 }
218 };
219
224 template<typename T>
225 inline
226 void swap(typename Range<T>::Iterator& lhs, typename Range<T>::Iterator& rhs) noexcept {
227 lhs.swap(rhs);
228 }
229
237
245
253
261
262// MSVC does not like extern template
263#ifndef _MSC_VER
264 extern template struct GF_CORE_API Range<float>;
265 extern template struct GF_CORE_API Range<int>;
266 extern template struct GF_CORE_API Range<unsigned>;
267#endif
268
269
270
277 template<typename T>
281
286 struct Iterator {
287 using difference_type = std::ptrdiff_t;
291 using iterator_category = std::forward_iterator_tag;
292
295
302 constexpr Iterator(Range<T> iteratorRange, Vector<T, 2> iteratorPosition) noexcept
303 : range(iteratorRange)
304 , position(iteratorPosition)
305 {
306 }
307
311 void swap(Iterator& other) noexcept {
312 using std::swap;
313 swap(range, other.range);
314 swap(position, other.position);
315 }
316
322 reference operator*() noexcept {
323 return position;
324 }
325
331 pointer operator->() noexcept {
332 return position;
333 }
334
340 Iterator& operator++() noexcept {
341 step();
342 return *this;
343 }
344
350 Iterator operator++(int) noexcept {
351 Iterator copy = *this;
352 step();
353 return copy;
354 }
355
362 constexpr bool operator!=(const Iterator& other) const noexcept {
363 return position.x != other.position.x || position.y != other.position.y;
364 }
365
372 constexpr bool operator==(const Iterator& other) const noexcept {
373 return position.x == other.position.x && position.y == other.position.y;
374 }
375
376 private:
377 void step() noexcept {
378 ++position.x;
379
380 if (position.x >= range.hi) {
381 position.x = range.lo;
382 ++position.y;
383 }
384 }
385 };
386
393 constexpr Iterator begin() const noexcept {
394 return Iterator(first, { first.lo, second.lo });
395 }
396
403 constexpr Iterator end() const noexcept {
404 return Iterator(first, { first.lo, second.hi });
405 }
406 };
407
412 template<typename T>
413 inline
414 void swap(typename PositionRange<T>::Iterator& lhs, typename PositionRange<T>::Iterator& rhs) noexcept {
415 lhs.swap(rhs);
416 }
417
418
425 template<typename T>
430
435 struct Iterator {
436 using difference_type = std::ptrdiff_t;
440 using iterator_category = std::forward_iterator_tag;
441
444
451 constexpr Iterator(Vector<T, 2> iteratorPosition, const NeighborSquareRange<T> *iteratorParent) noexcept
452 : position(iteratorPosition)
453 , parent(iteratorParent)
454 {
455 if (isNotNeighbor(position)) {
456 step();
457 }
458 }
459
465 constexpr Iterator(Vector<T, 2> iteratorPosition) noexcept
466 : position(iteratorPosition)
467 , parent(nullptr)
468 {
469 }
470
474 void swap(Iterator& other) noexcept {
475 using std::swap;
476 swap(position, other.position);
477 swap(parent, other.parent);
478 }
479
485 reference operator*() noexcept {
486 return position;
487 }
488
494 pointer operator->() noexcept {
495 return position;
496 }
497
503 Iterator& operator++() noexcept {
504 step();
505 return *this;
506 }
507
513 Iterator operator++(int) noexcept {
514 Iterator copy = *this;
515 step();
516 return copy;
517 }
518
525 constexpr bool operator!=(const Iterator& other) const noexcept {
526 return position.x != other.position.x || position.y != other.position.y;
527 }
528
535 constexpr bool operator==(const Iterator& other) const noexcept {
536 return position.x == other.position.x && position.y == other.position.y;
537 }
538
539 private:
540 void step() noexcept {
541 do {
542 ++position.x;
543
544 if (position.x >= parent->first.hi) {
545 position.x = parent->first.lo;
546 ++position.y;
547 }
548 } while (isNotNeighbor(position));
549 }
550
551 bool isNotNeighbor(Vector<T, 2> other) const noexcept {
552 return other.x == parent->origin.x && other.y == parent->origin.y;
553 }
554 };
555
562 constexpr Iterator begin() const noexcept {
563 return Iterator({ first.lo, second.lo }, this);
564 }
565
572 constexpr Iterator end() const noexcept {
573 return Iterator({ first.lo, second.hi });
574 }
575 };
576
581 template<typename T>
582 inline
583 void swap(typename NeighborSquareRange<T>::Iterator& lhs, typename NeighborSquareRange<T>::Iterator& rhs) noexcept {
584 lhs.swap(rhs);
585 }
586
587
594 template<typename T>
600
605 struct Iterator {
606 using difference_type = std::ptrdiff_t;
610 using iterator_category = std::forward_iterator_tag;
611
614
621 constexpr Iterator(Vector<T, 2> iteratorPosition, const NeighborDiamondRange<T> *iteratorParent) noexcept
622 : position(iteratorPosition)
623 , parent(iteratorParent)
624 {
625 if (isNotNeighbor(position)) {
626 step();
627 }
628 }
629
635 constexpr Iterator(Vector<T, 2> iteratorPosition) noexcept
636 : position(iteratorPosition)
637 , parent(nullptr)
638 {
639 }
640
644 void swap(Iterator& other) noexcept {
645 using std::swap;
646 swap(position, other.position);
647 swap(parent, other.parent);
648 }
649
655 reference operator*() noexcept {
656 return position;
657 }
658
664 pointer operator->() noexcept {
665 return position;
666 }
667
673 Iterator& operator++() noexcept {
674 step();
675 return *this;
676 }
677
683 Iterator operator++(int) noexcept {
684 Iterator copy = *this;
685 step();
686 return copy;
687 }
688
695 constexpr bool operator!=(const Iterator& other) const noexcept {
696 return position.x != other.position.x || position.y != other.position.y;
697 }
698
705 constexpr bool operator==(const Iterator& other) const noexcept {
706 return position.x == other.position.x && position.y == other.position.y;
707 }
708
709 private:
710 void step() noexcept {
711 do {
712 ++position.x;
713
714 if (position.x >= parent->first.hi) {
715 position.x = parent->first.lo;
716 ++position.y;
717
718 if (position.y >= parent->second.hi) {
719 break;
720 }
721 }
722 } while (isNotNeighbor(position));
723 }
724
725 bool isNotNeighbor(Vector<T, 2> other) const noexcept {
726 return isOrigin(other) || isOutOfDiamond(position);
727 }
728
729 bool isOrigin(Vector<T, 2> other) const noexcept {
730 return other.x == parent->origin.x && other.y == parent->origin.y;
731 }
732
733 bool isOutOfDiamond(Vector<T, 2> other) const noexcept {
734 return gf::absdiff(other.x, parent->origin.x) + gf::absdiff(other.y, parent->origin.y) > parent->radius;
735 }
736 };
737
744 constexpr Iterator begin() const noexcept {
745 return Iterator({ first.lo, second.lo }, this);
746 }
747
754 constexpr Iterator end() const noexcept {
755 return Iterator({ first.lo, second.hi });
756 }
757 };
758
763 template<typename T>
764 inline
766 lhs.swap(rhs);
767 }
768
769
770#ifndef DOXYGEN_SHOULD_SKIP_THIS
771}
772#endif
773}
774
775#endif // GF_RANGE_H
constexpr T absdiff(T lhs, T rhs)
Absolute difference of two values.
Definition: Math.h:352
The namespace for gf classes.
An iterator for a 2D range.
Definition: Range.h:605
constexpr bool operator!=(const Iterator &other) const noexcept
Inequality operator.
Definition: Range.h:695
Vector< T, 2 > position
Definition: Range.h:612
Iterator & operator++() noexcept
Increment operator (prefix)
Definition: Range.h:673
void swap(Iterator &other) noexcept
Swap the iterator with another iterator.
Definition: Range.h:644
constexpr bool operator==(const Iterator &other) const noexcept
Equality operator.
Definition: Range.h:705
const NeighborDiamondRange< T > * parent
Definition: Range.h:613
std::ptrdiff_t difference_type
Definition: Range.h:606
reference operator*() noexcept
Dereference operator.
Definition: Range.h:655
pointer operator->() noexcept
Pointer operator.
Definition: Range.h:664
void swap(typename NeighborDiamondRange< T >::Iterator &lhs, typename NeighborDiamondRange< T >::Iterator &rhs) noexcept
Swap two range iterators.
Definition: Range.h:765
std::forward_iterator_tag iterator_category
Definition: Range.h:610
Iterator operator++(int) noexcept
Increment operator (postfix)
Definition: Range.h:683
constexpr Iterator(Vector< T, 2 > iteratorPosition, const NeighborDiamondRange< T > *iteratorParent) noexcept
Constructor.
Definition: Range.h:621
constexpr Iterator(Vector< T, 2 > iteratorPosition) noexcept
Constructor of a end sentinel.
Definition: Range.h:635
A 2D range.
Definition: Range.h:595
Range< T > second
The range in the second dimension.
Definition: Range.h:597
Range< T > first
The range in the first dimension.
Definition: Range.h:596
constexpr Iterator end() const noexcept
Get a end iterator.
Definition: Range.h:754
Vector< T, 2 > origin
Definition: Range.h:598
T radius
Definition: Range.h:599
constexpr Iterator begin() const noexcept
Get a begin iterator.
Definition: Range.h:744
An iterator for a 2D range.
Definition: Range.h:435
Vector< T, 2 > position
Definition: Range.h:442
void swap(typename NeighborSquareRange< T >::Iterator &lhs, typename NeighborSquareRange< T >::Iterator &rhs) noexcept
Swap two range iterators.
Definition: Range.h:583
std::forward_iterator_tag iterator_category
Definition: Range.h:440
std::ptrdiff_t difference_type
Definition: Range.h:436
void swap(Iterator &other) noexcept
Swap the iterator with another iterator.
Definition: Range.h:474
const NeighborSquareRange< T > * parent
Definition: Range.h:443
constexpr bool operator==(const Iterator &other) const noexcept
Equality operator.
Definition: Range.h:535
constexpr bool operator!=(const Iterator &other) const noexcept
Inequality operator.
Definition: Range.h:525
Iterator & operator++() noexcept
Increment operator (prefix)
Definition: Range.h:503
constexpr Iterator(Vector< T, 2 > iteratorPosition) noexcept
Constructor of a end sentinel.
Definition: Range.h:465
reference operator*() noexcept
Dereference operator.
Definition: Range.h:485
constexpr Iterator(Vector< T, 2 > iteratorPosition, const NeighborSquareRange< T > *iteratorParent) noexcept
Constructor.
Definition: Range.h:451
Iterator operator++(int) noexcept
Increment operator (postfix)
Definition: Range.h:513
pointer operator->() noexcept
Pointer operator.
Definition: Range.h:494
A 2D range.
Definition: Range.h:426
Range< T > second
The range in the second dimension.
Definition: Range.h:428
Range< T > first
The range in the first dimension.
Definition: Range.h:427
Vector< T, 2 > origin
Definition: Range.h:429
constexpr Iterator begin() const noexcept
Get a begin iterator.
Definition: Range.h:562
constexpr Iterator end() const noexcept
Get a end iterator.
Definition: Range.h:572
An iterator for a 2D range.
Definition: Range.h:286
Range< T > range
Definition: Range.h:293
std::ptrdiff_t difference_type
Definition: Range.h:287
std::forward_iterator_tag iterator_category
Definition: Range.h:291
Iterator & operator++() noexcept
Increment operator (prefix)
Definition: Range.h:340
Iterator operator++(int) noexcept
Increment operator (postfix)
Definition: Range.h:350
pointer operator->() noexcept
Pointer operator.
Definition: Range.h:331
reference operator*() noexcept
Dereference operator.
Definition: Range.h:322
void swap(typename PositionRange< T >::Iterator &lhs, typename PositionRange< T >::Iterator &rhs) noexcept
Swap two range iterators.
Definition: Range.h:414
void swap(Iterator &other) noexcept
Swap the iterator with another iterator.
Definition: Range.h:311
constexpr Iterator(Range< T > iteratorRange, Vector< T, 2 > iteratorPosition) noexcept
Constructor.
Definition: Range.h:302
Vector< T, 2 > position
Definition: Range.h:294
constexpr bool operator==(const Iterator &other) const noexcept
Equality operator.
Definition: Range.h:372
constexpr bool operator!=(const Iterator &other) const noexcept
Inequality operator.
Definition: Range.h:362
A 2D range.
Definition: Range.h:278
constexpr Iterator end() const noexcept
Get a end iterator.
Definition: Range.h:403
Range< T > first
The range in the first dimension.
Definition: Range.h:279
constexpr Iterator begin() const noexcept
Get a begin iterator.
Definition: Range.h:393
Range< T > second
The range in the second dimension.
Definition: Range.h:280
A range iterator.
Definition: Range.h:52
constexpr bool operator==(const Iterator &other) const noexcept
Equality operator.
Definition: Range.h:155
value_type pointer
Definition: Range.h:55
Iterator operator--(int) noexcept
Decrement operator (postfix)
Definition: Range.h:133
constexpr bool operator!=(const Iterator &other) const noexcept
Inequality operator.
Definition: Range.h:145
std::bidirectional_iterator_tag iterator_category
Definition: Range.h:57
void swap(Iterator &other) noexcept
Swap the iterator with another iterator.
Definition: Range.h:74
Iterator operator++(int) noexcept
Increment operator (postfix)
Definition: Range.h:112
pointer operator->() noexcept
Pointer operator.
Definition: Range.h:93
Iterator & operator--() noexcept
Decrement operator (prefix)
Definition: Range.h:123
void swap(typename Range< T >::Iterator &lhs, typename Range< T >::Iterator &rhs) noexcept
Swap two range iterators.
Definition: Range.h:226
std::ptrdiff_t difference_type
Definition: Range.h:53
value_type reference
Definition: Range.h:56
Iterator & operator++() noexcept
Increment operator (prefix)
Definition: Range.h:102
reference operator*() noexcept
Dereference operator.
Definition: Range.h:84
T value_type
Definition: Range.h:54
constexpr Iterator(T iteratorIndex) noexcept
Constructor.
Definition: Range.h:66
T index
The index in the range.
Definition: Range.h:59
A half-open range of values.
Definition: Range.h:44
constexpr bool contains(T value) const noexcept
Check if a value is in a range.
Definition: Range.h:166
constexpr Iterator end() const noexcept
Get a end iterator.
Definition: Range.h:186
constexpr bool isEmpty() const noexcept
Check if the range is empty.
Definition: Range.h:205
constexpr Iterator begin() const noexcept
Get a begin iterator.
Definition: Range.h:176
T hi
The higher endpoint (excluded)
Definition: Range.h:46
constexpr bool isValid() const noexcept
Check if the range is valid.
Definition: Range.h:215
constexpr T length() const noexcept
Get the length of the range.
Definition: Range.h:195
T lo
The lower endpoint (included)
Definition: Range.h:45
A 2D vector.
Definition: Vector.h:316
T y
Second coordinate in the (x,y) representation.
Definition: Vector.h:525
T x
First coordinate in the (x,y) representation.
Definition: Vector.h:514