Gamedev Framework (gf)  0.6.0
A C++11 framework for 2D games
Range.h
1 /*
2  * Gamedev Framework (gf)
3  * Copyright (C) 2016-2017 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 "Vector.h"
28 
29 namespace gf {
30 #ifndef DOXYGEN_SHOULD_SKIP_THIS
31 inline namespace v1 {
32 #endif
33 
34  /**
35  * @ingroup core
36  * @brief A half-open range of values
37  *
38  * gf::Range represents a half-open range of values.
39  *
40  */
41  template<typename T>
42  struct Range {
43  T lo; ///< The lower endpoint (included)
44  T hi; ///< The higher endpoint (excluded)
45 
46  /**
47  * @ingroup core
48  * @brief A range iterator
49  */
50  struct Iterator : public std::iterator<std::input_iterator_tag, T> {
51  T index; ///< The index in the range
52 
53  /**
54  * @brief Constructor
55  *
56  * @param iteratorIndex Index in the range
57  */
58  constexpr Iterator(T iteratorIndex) noexcept
59  : index(iteratorIndex)
60  {
61 
62  }
63 
64  /**
65  * @brief Dereference operator
66  *
67  * @return The index
68  */
69  T operator*() noexcept {
70  return index;
71  }
72 
73  /**
74  * @brief Increment operator (prefix)
75  *
76  * @return The iterator
77  */
78  Iterator& operator++() noexcept {
79  ++index;
80  return *this;
81  }
82 
83  /**
84  * @brief Increment operator (postfix)
85  *
86  * @return The iterator
87  */
88  Iterator operator++(int) noexcept {
89  Iterator copy = *this;
90  ++index;
91  return copy;
92  }
93 
94  /**
95  * @brief Inequality operator
96  *
97  * @param other Another iterator
98  * @return True if the iterator are different
99  */
100  constexpr bool operator!=(const Iterator& other) const noexcept {
101  return index != other.index;
102  }
103 
104  /**
105  * @brief Equality operator
106  *
107  * @param other Another iterator
108  * @return True if the iterator are the same
109  */
110  constexpr bool operator==(const Iterator& other) const noexcept {
111  return index == other.index;
112  }
113 
114  };
115 
116  /**
117  * @brief Check if a value is in a range
118  *
119  * @param value The value to test
120  * @return True if the value is in the range
121  */
122  constexpr bool contains(T value) const noexcept {
123  return lo <= value && value < hi;
124  }
125 
126  /**
127  * @brief Get a begin iterator
128  *
129  * @return A begin iterator
130  * @sa end()
131  */
132  constexpr Iterator begin() const noexcept {
133  return Iterator(lo);
134  }
135 
136  /**
137  * @brief Get a end iterator
138  *
139  * @return A end iterator
140  * @sa begin()
141  */
142  constexpr Iterator end() const noexcept {
143  return Iterator(hi);
144  }
145 
146  /**
147  * @brief Get the length of the range
148  *
149  * @return The length of the range
150  */
151  constexpr T length() const noexcept {
152  return hi - lo;
153  }
154 
155  /**
156  * @brief Check if the range is empty
157  *
158  * @return True if the range is empty
159  * @sa isValid()
160  */
161  constexpr bool isEmpty() const noexcept {
162  return lo >= hi;
163  }
164 
165  /**
166  * @brief Check is the range is valid
167  *
168  * @return True if the range is valid
169  * @sa isEmpty()
170  */
171  constexpr bool isValid() const noexcept {
172  return lo <= hi;
173  }
174 
175  };
176 
177  /**
178  * @ingroup core
179  * @brief A float range
180  *
181  * @sa gf::Range
182  */
183  using RangeF = Range<float>;
184 
185  /**
186  * @ingroup core
187  * @brief A int range
188  *
189  * @sa gf::Range
190  */
191  using RangeI = Range<int>;
192 
193  /**
194  * @ingroup core
195  * @brief A unsigned range
196  *
197  * @sa gf::Range
198  */
199  using RangeU = Range<unsigned>;
200 
201  /**
202  * @ingroup core
203  * @brief A `std::size_t` range
204  *
205  * @sa gf::Range
206  */
207  using RangeZ = Range<std::size_t>;
208 
209 // MSVC does not like extern template
210 #ifndef _MSC_VER
211  extern template struct Range<float>;
212  extern template struct Range<int>;
213  extern template struct Range<unsigned>;
214 #endif
215 
216 
217 
218  /**
219  * @ingroup core
220  * @brief A 2D range
221  *
222  * gf::PositionRange represents a range across a 2D area.
223  */
224  template<typename T>
225  struct PositionRange {
226  Range<T> first; ///< The range in the first dimension
227  Range<T> second; ///< The range in the second dimension
228 
229  /**
230  * @brief An iterator for a 2D range
231  */
232  struct Iterator : public std::iterator<std::input_iterator_tag, T> {
235 
236  /**
237  * @brief Constructor
238  *
239  * @param iteratorRange The range in the first dimension
240  * @param iteratorPosition The current position in 2D
241  */
242  constexpr Iterator(Range<T> iteratorRange, Vector<T, 2> iteratorPosition) noexcept
243  : range(iteratorRange)
244  , position(iteratorPosition)
245  {
246 
247  }
248 
249  /**
250  * @brief Dereference operator
251  *
252  * @return The position
253  */
254  Vector<T, 2> operator*() noexcept {
255  return position;
256  }
257 
258  /**
259  * @brief Increment operator (prefix)
260  *
261  * @return The iterator
262  */
263  Iterator& operator++() noexcept {
264  step();
265  return *this;
266  }
267 
268  /**
269  * @brief Increment operator (postfix)
270  *
271  * @return The iterator
272  */
273  Iterator operator++(int) noexcept {
274  Iterator copy = *this;
275  step();
276  return copy;
277  }
278 
279  /**
280  * @brief Inequality operator
281  *
282  * @param other Another iterator
283  * @return True if the iterator are different
284  */
285  constexpr bool operator!=(const Iterator& other) const noexcept {
286  return position.x != other.position.x || position.y != other.position.y;
287  }
288 
289  /**
290  * @brief Equality operator
291  *
292  * @param other Another iterator
293  * @return True if the iterator are the same
294  */
295  constexpr bool operator==(const Iterator& other) const noexcept {
296  return position.x == other.position.x && position.y == other.position.y;
297  }
298 
299  private:
300  void step() {
301  ++position.x;
302 
303  if (position.x >= range.hi) {
304  position.x = range.lo;
305  ++position.y;
306  }
307  }
308  };
309 
310  /**
311  * @brief Get a begin iterator
312  *
313  * @return A begin iterator
314  * @sa end()
315  */
316  constexpr Iterator begin() const noexcept {
317  return Iterator(first, { first.lo, second.lo });
318  }
319 
320  /**
321  * @brief Get a end iterator
322  *
323  * @return A end iterator
324  * @sa begin()
325  */
326  constexpr Iterator end() const noexcept {
327  return Iterator(first, { first.lo, second.hi });
328  }
329 
330  };
331 
332 
333 #ifndef DOXYGEN_SHOULD_SKIP_THIS
334 }
335 #endif
336 }
337 
338 #endif // GF_RANGE_H
A range iterator.
Definition: Range.h:50
constexpr bool operator==(const Iterator &other) const noexcept
Equality operator.
Definition: Range.h:295
constexpr Iterator(T iteratorIndex) noexcept
Constructor.
Definition: Range.h:58
A half-open range of values.
Definition: Range.h:42
constexpr bool operator!=(const Iterator &other) const noexcept
Inequality operator.
Definition: Range.h:100
T operator*() noexcept
Dereference operator.
Definition: Range.h:69
Range< T > first
The range in the first dimension.
Definition: Range.h:226
Iterator & operator++() noexcept
Increment operator (prefix)
Definition: Range.h:263
constexpr bool isEmpty() const noexcept
Check if the range is empty.
Definition: Range.h:161
T lo
The lower endpoint (included)
Definition: Range.h:43
constexpr Iterator end() const noexcept
Get a end iterator.
Definition: Range.h:326
Iterator operator++(int) noexcept
Increment operator (postfix)
Definition: Range.h:88
constexpr bool operator==(const Iterator &other) const noexcept
Equality operator.
Definition: Range.h:110
constexpr Iterator end() const noexcept
Get a end iterator.
Definition: Range.h:142
constexpr bool operator!=(const Iterator &other) const noexcept
Inequality operator.
Definition: Range.h:285
Iterator operator++(int) noexcept
Increment operator (postfix)
Definition: Range.h:273
Range< T > second
The range in the second dimension.
Definition: Range.h:227
T hi
The higher endpoint (excluded)
Definition: Range.h:44
An iterator for a 2D range.
Definition: Range.h:232
constexpr bool contains(T value) const noexcept
Check if a value is in a range.
Definition: Range.h:122
constexpr Iterator begin() const noexcept
Get a begin iterator.
Definition: Range.h:132
The namespace for gf classes.
Definition: Action.h:34
Range< T > range
Definition: Range.h:233
constexpr Iterator begin() const noexcept
Get a begin iterator.
Definition: Range.h:316
A 2D range.
Definition: Range.h:225
constexpr Iterator(Range< T > iteratorRange, Vector< T, 2 > iteratorPosition) noexcept
Constructor.
Definition: Range.h:242
Vector< T, 2 > position
Definition: Range.h:234
T index
The index in the range.
Definition: Range.h:51
Vector< T, 2 > operator*() noexcept
Dereference operator.
Definition: Range.h:254
constexpr T length() const noexcept
Get the length of the range.
Definition: Range.h:151
General purpose math vector.
Definition: Vector.h:60
Iterator & operator++() noexcept
Increment operator (prefix)
Definition: Range.h:78
constexpr bool isValid() const noexcept
Check is the range is valid.
Definition: Range.h:171