Gamedev Framework (gf)  0.17.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 
73  void swap(Iterator& other) noexcept {
74  using std::swap;
75  swap(index, other.index);
76  }
77 
83  reference operator*() noexcept {
84  return index;
85  }
86 
92  pointer operator->() noexcept {
93  return index;
94  }
95 
101  Iterator& operator++() noexcept {
102  ++index;
103  return *this;
104  }
105 
111  Iterator operator++(int) noexcept {
112  Iterator copy = *this;
113  ++index;
114  return copy;
115  }
116 
122  Iterator& operator--() noexcept {
123  --index;
124  return *this;
125  }
126 
132  Iterator operator--(int) noexcept {
133  Iterator copy = *this;
134  --index;
135  return copy;
136  }
137 
144  constexpr bool operator!=(const Iterator& other) const noexcept {
145  return index != other.index;
146  }
147 
154  constexpr bool operator==(const Iterator& other) const noexcept {
155  return index == other.index;
156  }
157  };
158 
165  constexpr bool contains(T value) const noexcept {
166  return lo <= value && value < hi;
167  }
168 
175  constexpr Iterator begin() const noexcept {
176  return Iterator(lo);
177  }
178 
185  constexpr Iterator end() const noexcept {
186  return Iterator(hi);
187  }
188 
194  constexpr T length() const noexcept {
195  return hi - lo;
196  }
197 
204  constexpr bool isEmpty() const noexcept {
205  return lo >= hi;
206  }
207 
214  constexpr bool isValid() const noexcept {
215  return lo <= hi;
216  }
217  };
218 
223  template<typename T>
224  inline
225  void swap(typename Range<T>::Iterator& lhs, typename Range<T>::Iterator& rhs) noexcept {
226  lhs.swap(rhs);
227  }
228 
236 
244 
252 
260 
261 // MSVC does not like extern template
262 #ifndef _MSC_VER
263  extern template struct GF_API Range<float>;
264  extern template struct GF_API Range<int>;
265  extern template struct GF_API Range<unsigned>;
266 #endif
267 
268 
269 
276  template<typename T>
277  struct PositionRange {
280 
284  struct Iterator {
285  using difference_type = std::ptrdiff_t;
289  using iterator_category = std::forward_iterator_tag;
290 
293 
300  constexpr Iterator(Range<T> iteratorRange, Vector<T, 2> iteratorPosition) noexcept
301  : range(iteratorRange)
302  , position(iteratorPosition)
303  {
304  }
305 
309  void swap(Iterator& other) noexcept {
310  using std::swap;
311  swap(range, other.range);
312  swap(position, other.position);
313  }
314 
320  reference operator*() noexcept {
321  return position;
322  }
323 
329  pointer operator->() noexcept {
330  return position;
331  }
332 
338  Iterator& operator++() noexcept {
339  step();
340  return *this;
341  }
342 
348  Iterator operator++(int) noexcept {
349  Iterator copy = *this;
350  step();
351  return copy;
352  }
353 
360  constexpr bool operator!=(const Iterator& other) const noexcept {
361  return position.x != other.position.x || position.y != other.position.y;
362  }
363 
370  constexpr bool operator==(const Iterator& other) const noexcept {
371  return position.x == other.position.x && position.y == other.position.y;
372  }
373 
374  private:
375  void step() noexcept {
376  ++position.x;
377 
378  if (position.x >= range.hi) {
379  position.x = range.lo;
380  ++position.y;
381  }
382  }
383  };
384 
391  constexpr Iterator begin() const noexcept {
392  return Iterator(first, { first.lo, second.lo });
393  }
394 
401  constexpr Iterator end() const noexcept {
402  return Iterator(first, { first.lo, second.hi });
403  }
404  };
405 
410  template<typename T>
411  inline
412  void swap(typename PositionRange<T>::Iterator& lhs, typename PositionRange<T>::Iterator& rhs) noexcept {
413  lhs.swap(rhs);
414  }
415 
416 
423  template<typename T>
428 
432  struct Iterator {
433  using difference_type = std::ptrdiff_t;
437  using iterator_category = std::forward_iterator_tag;
438 
441 
448  constexpr Iterator(Vector<T, 2> iteratorPosition, const NeighborSquareRange<T> *iteratorParent) noexcept
449  : position(iteratorPosition)
450  , parent(iteratorParent)
451  {
452  if (isNotNeighbor(position)) {
453  step();
454  }
455  }
456 
462  constexpr Iterator(Vector<T, 2> iteratorPosition) noexcept
463  : position(iteratorPosition)
464  , parent(nullptr)
465  {
466  }
467 
471  void swap(Iterator& other) noexcept {
472  using std::swap;
473  swap(position, other.position);
474  swap(parent, other.parent);
475  }
476 
482  reference operator*() noexcept {
483  return position;
484  }
485 
491  pointer operator->() noexcept {
492  return position;
493  }
494 
500  Iterator& operator++() noexcept {
501  step();
502  return *this;
503  }
504 
510  Iterator operator++(int) noexcept {
511  Iterator copy = *this;
512  step();
513  return copy;
514  }
515 
522  constexpr bool operator!=(const Iterator& other) const noexcept {
523  return position.x != other.position.x || position.y != other.position.y;
524  }
525 
532  constexpr bool operator==(const Iterator& other) const noexcept {
533  return position.x == other.position.x && position.y == other.position.y;
534  }
535 
536  private:
537  void step() noexcept {
538  do {
539  ++position.x;
540 
541  if (position.x >= parent->first.hi) {
542  position.x = parent->first.lo;
543  ++position.y;
544  }
545  } while (isNotNeighbor(position));
546  }
547 
548  bool isNotNeighbor(Vector<T, 2> other) const noexcept {
549  return other.x == parent->origin.x && other.y == parent->origin.y;
550  }
551  };
552 
559  constexpr Iterator begin() const noexcept {
560  return Iterator({ first.lo, second.lo }, this);
561  }
562 
569  constexpr Iterator end() const noexcept {
570  return Iterator({ first.lo, second.hi });
571  }
572  };
573 
578  template<typename T>
579  inline
580  void swap(typename NeighborSquareRange<T>::Iterator& lhs, typename NeighborSquareRange<T>::Iterator& rhs) noexcept {
581  lhs.swap(rhs);
582  }
583 
584 
591  template<typename T>
597 
601  struct Iterator {
602  using difference_type = std::ptrdiff_t;
606  using iterator_category = std::forward_iterator_tag;
607 
610 
617  constexpr Iterator(Vector<T, 2> iteratorPosition, const NeighborDiamondRange<T> *iteratorParent) noexcept
618  : position(iteratorPosition)
619  , parent(iteratorParent)
620  {
621  if (isNotNeighbor(position)) {
622  step();
623  }
624  }
625 
631  constexpr Iterator(Vector<T, 2> iteratorPosition) noexcept
632  : position(iteratorPosition)
633  , parent(nullptr)
634  {
635  }
636 
640  void swap(Iterator& other) noexcept {
641  using std::swap;
642  swap(position, other.position);
643  swap(parent, other.parent);
644  }
645 
651  reference operator*() noexcept {
652  return position;
653  }
654 
660  pointer operator->() noexcept {
661  return position;
662  }
663 
669  Iterator& operator++() noexcept {
670  step();
671  return *this;
672  }
673 
679  Iterator operator++(int) noexcept {
680  Iterator copy = *this;
681  step();
682  return copy;
683  }
684 
691  constexpr bool operator!=(const Iterator& other) const noexcept {
692  return position.x != other.position.x || position.y != other.position.y;
693  }
694 
701  constexpr bool operator==(const Iterator& other) const noexcept {
702  return position.x == other.position.x && position.y == other.position.y;
703  }
704 
705  private:
706  void step() noexcept {
707  do {
708  ++position.x;
709 
710  if (position.x >= parent->first.hi) {
711  position.x = parent->first.lo;
712  ++position.y;
713 
714  if (position.y >= parent->second.hi) {
715  break;
716  }
717  }
718  } while (isNotNeighbor(position));
719  }
720 
721  bool isNotNeighbor(Vector<T, 2> other) const noexcept {
722  return isOrigin(other) || isOutOfDiamond(position);
723  }
724 
725  bool isOrigin(Vector<T, 2> other) const noexcept {
726  return other.x == parent->origin.x && other.y == parent->origin.y;
727  }
728 
729  bool isOutOfDiamond(Vector<T, 2> other) const noexcept {
730  return gf::absdiff(other.x, parent->origin.x) + gf::absdiff(other.y, parent->origin.y) > parent->radius;
731  }
732  };
733 
740  constexpr Iterator begin() const noexcept {
741  return Iterator({ first.lo, second.lo }, this);
742  }
743 
750  constexpr Iterator end() const noexcept {
751  return Iterator({ first.lo, second.hi });
752  }
753  };
754 
759  template<typename T>
760  inline
761  void swap(typename NeighborDiamondRange<T>::Iterator& lhs, typename NeighborDiamondRange<T>::Iterator& rhs) noexcept {
762  lhs.swap(rhs);
763  }
764 
765 
766 #ifndef DOXYGEN_SHOULD_SKIP_THIS
767 }
768 #endif
769 }
770 
771 #endif // GF_RANGE_H
Range< T > second
The range in the second dimension.
Definition: Range.h:426
Vector< T, 2 > position
Definition: Range.h:608
Range< T > first
The range in the first dimension.
Definition: Range.h:593
An iterator for a 2D range.
Definition: Range.h:601
T x
First coordinate in the (x,y) representation.
Definition: Vector.h:514
A range iterator.
Definition: Range.h:51
std::forward_iterator_tag iterator_category
Definition: Range.h:606
constexpr bool operator==(const Iterator &other) const noexcept
Equality operator.
Definition: Range.h:370
pointer operator->() noexcept
Pointer operator.
Definition: Range.h:660
std::forward_iterator_tag iterator_category
Definition: Range.h:437
std::ptrdiff_t difference_type
Definition: Range.h:285
void swap(Iterator &other) noexcept
Swap the iterator with another iterator.
Definition: Range.h:73
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:522
Iterator & operator++() noexcept
Increment operator (prefix)
Definition: Range.h:669
Range< T > second
The range in the second dimension.
Definition: Range.h:594
constexpr bool operator!=(const Iterator &other) const noexcept
Inequality operator.
Definition: Range.h:144
pointer operator->() noexcept
Pointer operator.
Definition: Range.h:329
Vector< T, 2 > origin
Definition: Range.h:595
Vector< T, 2 > position
Definition: Range.h:439
const NeighborDiamondRange< T > * parent
Definition: Range.h:609
constexpr Iterator(Vector< T, 2 > iteratorPosition) noexcept
Constructor of a end sentinel.
Definition: Range.h:631
Range< T > first
The range in the first dimension.
Definition: Range.h:278
Iterator & operator++() noexcept
Increment operator (prefix)
Definition: Range.h:338
constexpr bool isEmpty() const noexcept
Check if the range is empty.
Definition: Range.h:204
T lo
The lower endpoint (included)
Definition: Range.h:44
constexpr Iterator end() const noexcept
Get a end iterator.
Definition: Range.h:401
constexpr Iterator begin() const noexcept
Get a begin iterator.
Definition: Range.h:740
Iterator operator++(int) noexcept
Increment operator (postfix)
Definition: Range.h:111
A 2D range.
Definition: Range.h:424
constexpr bool operator==(const Iterator &other) const noexcept
Equality operator.
Definition: Range.h:154
constexpr Iterator end() const noexcept
Get a end iterator.
Definition: Range.h:185
constexpr bool operator!=(const Iterator &other) const noexcept
Inequality operator.
Definition: Range.h:360
void swap(Iterator &other) noexcept
Swap the iterator with another iterator.
Definition: Range.h:309
constexpr T absdiff(T lhs, T rhs)
Absolute difference of two values.
Definition: Math.h:354
Iterator operator++(int) noexcept
Increment operator (postfix)
Definition: Range.h:348
T y
Second coordinate in the (x,y) representation.
Definition: Vector.h:525
reference operator*() noexcept
Dereference operator.
Definition: Range.h:83
constexpr Iterator(Vector< T, 2 > iteratorPosition) noexcept
Constructor of a end sentinel.
Definition: Range.h:462
constexpr Iterator(Vector< T, 2 > iteratorPosition, const NeighborSquareRange< T > *iteratorParent) noexcept
Constructor.
Definition: Range.h:448
Range< T > second
The range in the second dimension.
Definition: Range.h:279
Iterator & operator--() noexcept
Decrement operator (prefix)
Definition: Range.h:122
constexpr Iterator begin() const noexcept
Get a begin iterator.
Definition: Range.h:559
reference operator*() noexcept
Dereference operator.
Definition: Range.h:320
value_type reference
Definition: Range.h:55
std::ptrdiff_t difference_type
Definition: Range.h:602
T hi
The higher endpoint (excluded)
Definition: Range.h:45
An iterator for a 2D range.
Definition: Range.h:284
Vector< T, 2 > origin
Definition: Range.h:427
constexpr bool contains(T value) const noexcept
Check if a value is in a range.
Definition: Range.h:165
pointer operator->() noexcept
Pointer operator.
Definition: Range.h:92
void swap(Iterator &other) noexcept
Swap the iterator with another iterator.
Definition: Range.h:471
void swap(typename Range< T >::Iterator &lhs, typename Range< T >::Iterator &rhs) noexcept
Swap two range iterators.
Definition: Range.h:225
constexpr Iterator begin() const noexcept
Get a begin iterator.
Definition: Range.h:175
reference operator*() noexcept
Dereference operator.
Definition: Range.h:651
The namespace for gf classes.
Definition: Action.h:35
T value_type
Definition: Range.h:53
pointer operator->() noexcept
Pointer operator.
Definition: Range.h:491
std::forward_iterator_tag iterator_category
Definition: Range.h:289
constexpr bool operator==(const Iterator &other) const noexcept
Equality operator.
Definition: Range.h:532
void swap(Iterator &other) noexcept
Swap the iterator with another iterator.
Definition: Range.h:640
Range< T > first
The range in the first dimension.
Definition: Range.h:425
An iterator for a 2D range.
Definition: Range.h:432
Range< T > range
Definition: Range.h:291
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:580
A 2D range.
Definition: Range.h:592
void swap(typename PositionRange< T >::Iterator &lhs, typename PositionRange< T >::Iterator &rhs) noexcept
Swap two range iterators.
Definition: Range.h:412
constexpr Iterator end() const noexcept
Get a end iterator.
Definition: Range.h:750
Iterator operator--(int) noexcept
Decrement operator (postfix)
Definition: Range.h:132
T radius
Definition: Range.h:596
A 2D vector.
Definition: Vector.h:316
constexpr Iterator begin() const noexcept
Get a begin iterator.
Definition: Range.h:391
constexpr Iterator(Vector< T, 2 > iteratorPosition, const NeighborDiamondRange< T > *iteratorParent) noexcept
Constructor.
Definition: Range.h:617
A 2D range.
Definition: Range.h:277
constexpr Iterator end() const noexcept
Get a end iterator.
Definition: Range.h:569
constexpr bool operator!=(const Iterator &other) const noexcept
Inequality operator.
Definition: Range.h:691
reference operator*() noexcept
Dereference operator.
Definition: Range.h:482
constexpr Iterator(Range< T > iteratorRange, Vector< T, 2 > iteratorPosition) noexcept
Constructor.
Definition: Range.h:300
Iterator & operator++() noexcept
Increment operator (prefix)
Definition: Range.h:500
Vector< T, 2 > position
Definition: Range.h:292
T index
The index in the range.
Definition: Range.h:58
Iterator operator++(int) noexcept
Increment operator (postfix)
Definition: Range.h:679
constexpr bool operator==(const Iterator &other) const noexcept
Equality operator.
Definition: Range.h:701
Iterator operator++(int) noexcept
Increment operator (postfix)
Definition: Range.h:510
constexpr T length() const noexcept
Get the length of the range.
Definition: Range.h:194
void swap(typename NeighborDiamondRange< T >::Iterator &lhs, typename NeighborDiamondRange< T >::Iterator &rhs) noexcept
Swap two range iterators.
Definition: Range.h:761
std::ptrdiff_t difference_type
Definition: Range.h:433
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:101
const NeighborSquareRange< T > * parent
Definition: Range.h:440
constexpr bool isValid() const noexcept
Check is the range is valid.
Definition: Range.h:214