Gamedev Framework (gf)  0.12.0
A C++14 framework for 2D games
Range.h
1 /*
2  * Gamedev Framework (gf)
3  * Copyright (C) 2016-2019 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 "Math.h"
28 #include "Vector.h"
29 
30 namespace gf {
31 #ifndef DOXYGEN_SHOULD_SKIP_THIS
32 inline namespace v1 {
33 #endif
34 
42  template<typename T>
43  struct Range {
44  T lo;
45  T hi;
46 
51  struct Iterator {
52  using difference_type = std::ptrdiff_t;
53  using value_type = T;
56  using iterator_category = std::bidirectional_iterator_tag;
57 
58  T index;
59 
65  constexpr Iterator(T iteratorIndex) noexcept
66  : index(iteratorIndex)
67  {
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  };
160 
167  constexpr bool contains(T value) const noexcept {
168  return lo <= value && value < hi;
169  }
170 
177  constexpr Iterator begin() const noexcept {
178  return Iterator(lo);
179  }
180 
187  constexpr Iterator end() const noexcept {
188  return Iterator(hi);
189  }
190 
196  constexpr T length() const noexcept {
197  return hi - lo;
198  }
199 
206  constexpr bool isEmpty() const noexcept {
207  return lo >= hi;
208  }
209 
216  constexpr bool isValid() const noexcept {
217  return lo <= hi;
218  }
219 
220  };
221 
226  template<typename T>
227  inline
228  void swap(typename Range<T>::Iterator& lhs, typename Range<T>::Iterator& rhs) noexcept {
229  lhs.swap(rhs);
230  }
231 
239 
247 
255 
263 
264 // MSVC does not like extern template
265 #ifndef _MSC_VER
266  extern template struct Range<float>;
267  extern template struct Range<int>;
268  extern template struct Range<unsigned>;
269 #endif
270 
271 
272 
279  template<typename T>
280  struct PositionRange {
283 
287  struct Iterator {
288  using difference_type = std::ptrdiff_t;
292  using iterator_category = std::forward_iterator_tag;
293 
296 
303  constexpr Iterator(Range<T> iteratorRange, Vector<T, 2> iteratorPosition) noexcept
304  : range(iteratorRange)
305  , position(iteratorPosition)
306  {
307 
308  }
309 
313  void swap(Iterator& other) noexcept {
314  using std::swap;
315  swap(range, other.range);
316  swap(position, other.position);
317  }
318 
324  reference operator*() noexcept {
325  return position;
326  }
327 
333  pointer operator->() noexcept {
334  return position;
335  }
336 
342  Iterator& operator++() noexcept {
343  step();
344  return *this;
345  }
346 
352  Iterator operator++(int) noexcept {
353  Iterator copy = *this;
354  step();
355  return copy;
356  }
357 
364  constexpr bool operator!=(const Iterator& other) const noexcept {
365  return position.x != other.position.x || position.y != other.position.y;
366  }
367 
374  constexpr bool operator==(const Iterator& other) const noexcept {
375  return position.x == other.position.x && position.y == other.position.y;
376  }
377 
378  private:
379  void step() noexcept {
380  ++position.x;
381 
382  if (position.x >= range.hi) {
383  position.x = range.lo;
384  ++position.y;
385  }
386  }
387  };
388 
395  constexpr Iterator begin() const noexcept {
396  return Iterator(first, { first.lo, second.lo });
397  }
398 
405  constexpr Iterator end() const noexcept {
406  return Iterator(first, { first.lo, second.hi });
407  }
408 
409  };
410 
415  template<typename T>
416  inline
417  void swap(typename PositionRange<T>::Iterator& lhs, typename PositionRange<T>::Iterator& rhs) noexcept {
418  lhs.swap(rhs);
419  }
420 
421 
428  template<typename T>
433 
437  struct Iterator {
438  using difference_type = std::ptrdiff_t;
442  using iterator_category = std::forward_iterator_tag;
443 
446 
453  constexpr Iterator(Vector<T, 2> iteratorPosition, const NeighborSquareRange<T> *iteratorParent) noexcept
454  : position(iteratorPosition)
455  , parent(iteratorParent)
456  {
457  if (isNotNeighbor(position)) {
458  step();
459  }
460  }
461 
467  constexpr Iterator(Vector<T, 2> iteratorPosition) noexcept
468  : position(iteratorPosition)
469  , parent(nullptr)
470  {
471 
472  }
473 
477  void swap(Iterator& other) noexcept {
478  using std::swap;
479  swap(position, other.position);
480  swap(parent, other.parent);
481  }
482 
488  reference operator*() noexcept {
489  return position;
490  }
491 
497  pointer operator->() noexcept {
498  return position;
499  }
500 
506  Iterator& operator++() noexcept {
507  step();
508  return *this;
509  }
510 
516  Iterator operator++(int) noexcept {
517  Iterator copy = *this;
518  step();
519  return copy;
520  }
521 
528  constexpr bool operator!=(const Iterator& other) const noexcept {
529  return position.x != other.position.x || position.y != other.position.y;
530  }
531 
538  constexpr bool operator==(const Iterator& other) const noexcept {
539  return position.x == other.position.x && position.y == other.position.y;
540  }
541 
542  private:
543  void step() noexcept {
544  do {
545  ++position.x;
546 
547  if (position.x >= parent->first.hi) {
548  position.x = parent->first.lo;
549  ++position.y;
550  }
551  } while (isNotNeighbor(position));
552  }
553 
554  bool isNotNeighbor(Vector<T, 2> other) const noexcept {
555  return other.x == parent->origin.x && other.y == parent->origin.y;
556  }
557  };
558 
565  constexpr Iterator begin() const noexcept {
566  return Iterator({ first.lo, second.lo }, this);
567  }
568 
575  constexpr Iterator end() const noexcept {
576  return Iterator({ first.lo, second.hi });
577  }
578 
579  };
580 
585  template<typename T>
586  inline
587  void swap(typename NeighborSquareRange<T>::Iterator& lhs, typename NeighborSquareRange<T>::Iterator& rhs) noexcept {
588  lhs.swap(rhs);
589  }
590 
591 
598  template<typename T>
604 
608  struct Iterator {
609  using difference_type = std::ptrdiff_t;
613  using iterator_category = std::forward_iterator_tag;
614 
617 
624  constexpr Iterator(Vector<T, 2> iteratorPosition, const NeighborDiamondRange<T> *iteratorParent) noexcept
625  : position(iteratorPosition)
626  , parent(iteratorParent)
627  {
628  if (isNotNeighbor(position)) {
629  step();
630  }
631  }
632 
638  constexpr Iterator(Vector<T, 2> iteratorPosition) noexcept
639  : position(iteratorPosition)
640  , parent(nullptr)
641  {
642 
643  }
644 
648  void swap(Iterator& other) noexcept {
649  using std::swap;
650  swap(position, other.position);
651  swap(parent, other.parent);
652  }
653 
659  reference operator*() noexcept {
660  return position;
661  }
662 
668  pointer operator->() noexcept {
669  return position;
670  }
671 
677  Iterator& operator++() noexcept {
678  step();
679  return *this;
680  }
681 
687  Iterator operator++(int) noexcept {
688  Iterator copy = *this;
689  step();
690  return copy;
691  }
692 
699  constexpr bool operator!=(const Iterator& other) const noexcept {
700  return position.x != other.position.x || position.y != other.position.y;
701  }
702 
709  constexpr bool operator==(const Iterator& other) const noexcept {
710  return position.x == other.position.x && position.y == other.position.y;
711  }
712 
713  private:
714  void step() noexcept {
715  do {
716  ++position.x;
717 
718  if (position.x >= parent->first.hi) {
719  position.x = parent->first.lo;
720  ++position.y;
721 
722  if (position.y >= parent->second.hi) {
723  break;
724  }
725  }
726  } while (isNotNeighbor(position));
727  }
728 
729  bool isNotNeighbor(Vector<T, 2> other) const noexcept {
730  return isOrigin(other) || isOutOfDiamond(position);
731  }
732 
733  bool isOrigin(Vector<T, 2> other) const noexcept {
734  return other.x == parent->origin.x && other.y == parent->origin.y;
735  }
736 
737  bool isOutOfDiamond(Vector<T, 2> other) const noexcept {
738  return gf::absdiff(other.x, parent->origin.x) + gf::absdiff(other.y, parent->origin.y) > parent->radius;
739  }
740  };
741 
748  constexpr Iterator begin() const noexcept {
749  return Iterator({ first.lo, second.lo }, this);
750  }
751 
758  constexpr Iterator end() const noexcept {
759  return Iterator({ first.lo, second.hi });
760  }
761 
762  };
763 
768  template<typename T>
769  inline
770  void swap(typename NeighborDiamondRange<T>::Iterator& lhs, typename NeighborDiamondRange<T>::Iterator& rhs) noexcept {
771  lhs.swap(rhs);
772  }
773 
774 
775 #ifndef DOXYGEN_SHOULD_SKIP_THIS
776 }
777 #endif
778 }
779 
780 #endif // GF_RANGE_H
Range< T > second
The range in the second dimension.
Definition: Range.h:431
Vector< T, 2 > position
Definition: Range.h:615
Range< T > first
The range in the first dimension.
Definition: Range.h:600
An iterator for a 2D range.
Definition: Range.h:608
T x
First coordinate in the (x,y) representation.
Definition: Vector.h:509
A range iterator.
Definition: Range.h:51
std::forward_iterator_tag iterator_category
Definition: Range.h:613
constexpr bool operator==(const Iterator &other) const noexcept
Equality operator.
Definition: Range.h:374
pointer operator->() noexcept
Pointer operator.
Definition: Range.h:668
std::forward_iterator_tag iterator_category
Definition: Range.h:442
std::ptrdiff_t difference_type
Definition: Range.h:288
void swap(Iterator &other) noexcept
Swap the iterator with another iterator.
Definition: Range.h:74
constexpr Iterator(T iteratorIndex) noexcept
Constructor.
Definition: Range.h:65
A half-open range of values.
Definition: Range.h:43
constexpr bool operator!=(const Iterator &other) const noexcept
Inequality operator.
Definition: Range.h:528
Iterator & operator++() noexcept
Increment operator (prefix)
Definition: Range.h:677
Range< T > second
The range in the second dimension.
Definition: Range.h:601
constexpr bool operator!=(const Iterator &other) const noexcept
Inequality operator.
Definition: Range.h:145
pointer operator->() noexcept
Pointer operator.
Definition: Range.h:333
Vector< T, 2 > origin
Definition: Range.h:602
Vector< T, 2 > position
Definition: Range.h:444
const NeighborDiamondRange< T > * parent
Definition: Range.h:616
constexpr Iterator(Vector< T, 2 > iteratorPosition) noexcept
Constructor of a end sentinel.
Definition: Range.h:638
Range< T > first
The range in the first dimension.
Definition: Range.h:281
Iterator & operator++() noexcept
Increment operator (prefix)
Definition: Range.h:342
constexpr bool isEmpty() const noexcept
Check if the range is empty.
Definition: Range.h:206
T lo
The lower endpoint (included)
Definition: Range.h:44
constexpr Iterator end() const noexcept
Get a end iterator.
Definition: Range.h:405
constexpr Iterator begin() const noexcept
Get a begin iterator.
Definition: Range.h:748
Iterator operator++(int) noexcept
Increment operator (postfix)
Definition: Range.h:112
A 2D range.
Definition: Range.h:429
constexpr bool operator==(const Iterator &other) const noexcept
Equality operator.
Definition: Range.h:155
constexpr Iterator end() const noexcept
Get a end iterator.
Definition: Range.h:187
constexpr bool operator!=(const Iterator &other) const noexcept
Inequality operator.
Definition: Range.h:364
void swap(Iterator &other) noexcept
Swap the iterator with another iterator.
Definition: Range.h:313
constexpr T absdiff(T lhs, T rhs)
Absolute difference of two values.
Definition: Math.h:313
Iterator operator++(int) noexcept
Increment operator (postfix)
Definition: Range.h:352
T y
Second coordinate in the (x,y) representation.
Definition: Vector.h:520
reference operator*() noexcept
Dereference operator.
Definition: Range.h:84
constexpr Iterator(Vector< T, 2 > iteratorPosition) noexcept
Constructor of a end sentinel.
Definition: Range.h:467
constexpr Iterator(Vector< T, 2 > iteratorPosition, const NeighborSquareRange< T > *iteratorParent) noexcept
Constructor.
Definition: Range.h:453
Range< T > second
The range in the second dimension.
Definition: Range.h:282
Iterator & operator--() noexcept
Decrement operator (prefix)
Definition: Range.h:123
constexpr Iterator begin() const noexcept
Get a begin iterator.
Definition: Range.h:565
reference operator*() noexcept
Dereference operator.
Definition: Range.h:324
value_type reference
Definition: Range.h:55
std::ptrdiff_t difference_type
Definition: Range.h:609
T hi
The higher endpoint (excluded)
Definition: Range.h:45
An iterator for a 2D range.
Definition: Range.h:287
Vector< T, 2 > origin
Definition: Range.h:432
constexpr bool contains(T value) const noexcept
Check if a value is in a range.
Definition: Range.h:167
pointer operator->() noexcept
Pointer operator.
Definition: Range.h:93
void swap(Iterator &other) noexcept
Swap the iterator with another iterator.
Definition: Range.h:477
void swap(typename Range< T >::Iterator &lhs, typename Range< T >::Iterator &rhs) noexcept
Swap two range iterators.
Definition: Range.h:228
constexpr Iterator begin() const noexcept
Get a begin iterator.
Definition: Range.h:177
reference operator*() noexcept
Dereference operator.
Definition: Range.h:659
The namespace for gf classes.
Definition: Action.h:35
T value_type
Definition: Range.h:53
pointer operator->() noexcept
Pointer operator.
Definition: Range.h:497
std::forward_iterator_tag iterator_category
Definition: Range.h:292
constexpr bool operator==(const Iterator &other) const noexcept
Equality operator.
Definition: Range.h:538
void swap(Iterator &other) noexcept
Swap the iterator with another iterator.
Definition: Range.h:648
Range< T > first
The range in the first dimension.
Definition: Range.h:430
An iterator for a 2D range.
Definition: Range.h:437
Range< T > range
Definition: Range.h:294
std::bidirectional_iterator_tag iterator_category
Definition: Range.h:56
void swap(typename NeighborSquareRange< T >::Iterator &lhs, typename NeighborSquareRange< T >::Iterator &rhs) noexcept
Swap two range iterators.
Definition: Range.h:587
A 2D range.
Definition: Range.h:599
void swap(typename PositionRange< T >::Iterator &lhs, typename PositionRange< T >::Iterator &rhs) noexcept
Swap two range iterators.
Definition: Range.h:417
constexpr Iterator end() const noexcept
Get a end iterator.
Definition: Range.h:758
Iterator operator--(int) noexcept
Decrement operator (postfix)
Definition: Range.h:133
T radius
Definition: Range.h:603
A 2D vector.
Definition: Vector.h:316
constexpr Iterator begin() const noexcept
Get a begin iterator.
Definition: Range.h:395
constexpr Iterator(Vector< T, 2 > iteratorPosition, const NeighborDiamondRange< T > *iteratorParent) noexcept
Constructor.
Definition: Range.h:624
A 2D range.
Definition: Range.h:280
constexpr Iterator end() const noexcept
Get a end iterator.
Definition: Range.h:575
constexpr bool operator!=(const Iterator &other) const noexcept
Inequality operator.
Definition: Range.h:699
reference operator*() noexcept
Dereference operator.
Definition: Range.h:488
constexpr Iterator(Range< T > iteratorRange, Vector< T, 2 > iteratorPosition) noexcept
Constructor.
Definition: Range.h:303
Iterator & operator++() noexcept
Increment operator (prefix)
Definition: Range.h:506
Vector< T, 2 > position
Definition: Range.h:295
T index
The index in the range.
Definition: Range.h:58
Iterator operator++(int) noexcept
Increment operator (postfix)
Definition: Range.h:687
constexpr bool operator==(const Iterator &other) const noexcept
Equality operator.
Definition: Range.h:709
Iterator operator++(int) noexcept
Increment operator (postfix)
Definition: Range.h:516
constexpr T length() const noexcept
Get the length of the range.
Definition: Range.h:196
void swap(typename NeighborDiamondRange< T >::Iterator &lhs, typename NeighborDiamondRange< T >::Iterator &rhs) noexcept
Swap two range iterators.
Definition: Range.h:770
std::ptrdiff_t difference_type
Definition: Range.h:438
value_type pointer
Definition: Range.h:54
std::ptrdiff_t difference_type
Definition: Range.h:52
Iterator & operator++() noexcept
Increment operator (prefix)
Definition: Range.h:102
const NeighborSquareRange< T > * parent
Definition: Range.h:445
constexpr bool isValid() const noexcept
Check is the range is valid.
Definition: Range.h:216