Walls And Holes  1
array2d.h
Go to the documentation of this file.
1 #ifndef ARRAY2D_H
2 #define ARRAY2D_H
3 
4 #include <QVector>
5 #include <QSize>
6 #include <QDebug>
7 #include <QPoint>
8 
9 #include "array2d_private.h"
10 
11 
12 // Iterator classes for Array2D.
13 template< typename Type > class Array2DIterator;
14 template< typename Type > class Array2DCIterator;
15 
16 // An iterator for the neighbors of a point.
17 template< typename Type > class Array2DCNeighborIterator;
18 
34 template< typename Type >
35 class Array2D {
36 public:
37 
38 
41 
42 
43  Array2D() {
44  // 0x0 grid
45  }
46 
47 
48  Array2D(int rows, int cols, Type defaultValue) {
49  data = QVector<QVector<Type>>(rows, QVector<Type>(cols, defaultValue));
50  }
51 
52  Array2D(int rows, int cols) : Array2D(rows, cols, Type()) {}
53 
54  Array2D(QSize size) : Array2D(size.width(), size.height()) {}
55 
56  const Type& operator()(int r, int c) const {
57  return data[r][c];
58  }
59 
60  Type& operator()(int r, int c) {
61  return data[r][c];
62  }
63 
64  const Type &operator ()(QPoint p) const {
65  return (*this)(p.x(), p.y());
66  }
67 
68  Type& operator()(QPoint p) {
69  return (*this)(p.x(), p.y());
70  }
71 
72  void resize(int rows, int cols)
73  {
74  data.resize(rows);
75  for (QVector<Type> &v : data)
76  v.resize(cols);
77  }
78 
79  QSize size() const { return QSize(width(), height()); }
80 
81  int width() const { return data.size(); }
82  int height() const { return data.empty() ? 0 : data[0].size(); }
83 
88  bool isInBounds(QPoint p) const { return p.x() >= 0 && p.x() < width() && p.y() >= 0 && p.y() < height(); }
89 
90 
96  IndexCollection indices() const { return IndexCollection(*this); }
97 
106 
107  /* Standard begin() and end() methods. */
108 
111  }
112 
114  return Array2DCIterator<Type>::ending(this);
115  }
116 
117 
120  }
121 
123  return Array2DIterator<Type>::ending(this);
124  }
125 
126  /* Special begin() and end() methods. */
127 
130  }
131 
133  return Array2DCNeighborIterator<Type>::ending(this, x, y);
134  }
135 
136 protected:
137  QVector<QVector<Type>> data;
138 };
139 
140 
141 /* Implementations of Array2DIterator and Array2DCIterator */
142 
143 template< typename Type >
144 class Array2DIterator {
145 public:
147  static Array2DIterator<Type> ending(Array2D<Type> *r) { return Array2DIterator<Type>(r, 0, r->size().height()); }
148 
149  Array2DIterator(Array2D<Type> *r, int x, int y) : arr(r), x(x), y(y) {}
150 
151  bool operator==(const Array2DIterator<Type> &other) const {
152  return other.arr == arr && other.x == x && other.y == y;
153  }
154 
155  bool operator!=(const Array2DIterator<Type> &other) const {
156  return !(*this == other);
157  }
158 
160  ++x;
161  if (x >= arr->size().width()) {
162  x = 0;
163  ++y;
164  }
165 
166  return *this;
167  }
168 
169  // Postfix ++
171  Array2DIterator<Type> iter(*this);
172  ++(*this);
173  return iter;
174  }
175 
176  Type &operator*() {
177  return (*arr)(x, y);
178  }
179 
180 protected:
182  int x, y;
183 };
184 
185 template< typename Type >
186 class Array2DCIterator {
187 public:
189  static Array2DCIterator<Type> ending(const Array2D<Type> *r) { return Array2DCIterator<Type>(r, 0, r->size().height()); }
190 
191  Array2DCIterator(const Array2D<Type> *r, int x, int y) : arr(r), x(x), y(y) {}
192 
193  bool operator==(const Array2DCIterator<Type> &other) const {
194  return other.arr == arr && other.x == x && other.y == y;
195  }
196 
197  bool operator!=(const Array2DCIterator<Type> &other) const {
198  return !(*this == other);
199  }
200 
202  ++x;
203  if (x >= arr->size().width()) {
204  x = 0;
205  ++y;
206  }
207 
208  return *this;
209  }
210 
211  // Postfix ++
213  Array2DIterator<Type> iter(*this);
214  ++(*this);
215  return iter;
216  }
217 
218  const Type &operator*() const {
219  return (*arr)(x, y);
220  }
221 
222 protected:
224  int x, y;
225 };
226 
227 
228 template< typename Type >
230 public:
231  static Array2DCNeighborIterator beginning(const Array2D<Type> *r, int x, int y) { return Array2DCNeighborIterator(r, x, y, 0); }
232  static Array2DCNeighborIterator ending(const Array2D<Type> *r, int x, int y) { return Array2DCNeighborIterator(r, x, y, 7); }
233 
234 
235  Array2DCNeighborIterator(const Array2D<Type> *r, int x, int y, int idx) : arr(r), centerX(x), centerY(y), neighborIndex(idx) {
236  // Make sure neighborIndex starts within bounds and doesn't go beyond 7.
237  while (!isInBounds() && neighborIndex < 7)
238  ++neighborIndex;
239  }
240 
241  bool operator==(const Array2DCNeighborIterator<Type> &other) const {
242  return other.arr == arr && other.centerX == centerX && other.centerY == centerY && other.neighborIndex == neighborIndex;
243  }
244 
245  bool operator!=(const Array2DCNeighborIterator<Type> &other) const {
246  return !(*this == other);
247  }
248 
250  ++neighborIndex;
251 
252  // Make sure neighborIndex is within bounds and not above 7.
253  while (!isInBounds() && neighborIndex < 7)
254  ++neighborIndex;
255 
256  return *this;
257  }
258 
259  // Postfix ++
261  Array2DIterator<Type> iter(*this);
262  ++(*this);
263  return iter;
264  }
265 
266  const Type &operator*() const {
267  // assumes isInBounds() is true
268  return (*arr)(getX(neighborIndex), getY(neighborIndex));
269  }
270 
271 protected:
272 
273  // Helper functions to map neighbor indices to positions.
274  // The mapping is:
275  // 0 1 2
276  // 3 4
277  // 5 6 7
278  // with the top-left corner having the smallest x and y coordinates.
279 
280  int getX(int neighbor) const {
281  if (neighbor == 0 || neighbor == 3 || neighbor == 5)
282  return centerX - 1;
283  if (neighbor == 1 || neighbor == 6)
284  return centerX;
285  return centerX + 1;
286  }
287 
288  int getY(int neighbor) const {
289  if (neighbor < 3)
290  return centerY - 1;
291  if (neighbor < 5)
292  return centerY;
293  return centerY + 1;
294  }
295 
296  bool isInBounds() const {
297  int wdth = arr->width();
298  int hght = arr->height();
299 
300  int x = getX(neighborIndex);
301  int y = getY(neighborIndex);
302 
303  return 0 <= x && x < wdth
304  && 0 <= y && y < hght;
305  }
306 
307 
311 };
312 
313 
314 #endif // ARRAY2D_H
static Array2DCNeighborIterator ending(const Array2D< Type > *r, int x, int y)
Definition: array2d.h:232
bool operator!=(const Array2DCNeighborIterator< Type > &other) const
Definition: array2d.h:245
bool isInBounds() const
Definition: array2d.h:296
Array2DCNeighborIterator< Type > begin_neighbors(int x, int y) const
Definition: array2d.h:128
Array2DCIterator< Type > operator++(int)
Definition: array2d.h:212
static Array2DCIterator< Type > beginning(const Array2D< Type > *r)
Definition: array2d.h:188
int centerX
Definition: array2d.h:309
Array2D_Private::Array2DPointAndConstDataWrapper< Type > IndexedConstDataCollection
Definition: array2d.h:40
void resize(int rows, int cols)
Definition: array2d.h:72
Array2D()
Definition: array2d.h:43
int width() const
Definition: array2d.h:81
const Type & operator*() const
Definition: array2d.h:218
A lightweight class to allow looping through all the data in an Array2D, outputting QPairs of (positi...
Definition: array2d_private.h:114
int getY(int neighbor) const
Definition: array2d.h:288
int y
Definition: array2d.h:182
QVector< QVector< Type > > data
Definition: array2d.h:137
Type & operator()(int r, int c)
Definition: array2d.h:60
bool operator==(const Array2DIterator< Type > &other) const
Definition: array2d.h:151
static Array2DCNeighborIterator beginning(const Array2D< Type > *r, int x, int y)
Definition: array2d.h:231
int height() const
Definition: array2d.h:82
Array2DCIterator< Type > & operator++()
Definition: array2d.h:201
Array2D(QSize size)
Definition: array2d.h:54
Array2DIterator< Type > operator++(int)
Definition: array2d.h:170
bool operator==(const Array2DCNeighborIterator< Type > &other) const
Definition: array2d.h:241
int x
Definition: array2d.h:182
bool isInBounds(QPoint p) const
Returns true if (p.x(), p.y()) is a valid region.
Definition: array2d.h:88
Array2D(int rows, int cols)
Definition: array2d.h:52
Array2DCNeighborIterator< Type > & operator++()
Definition: array2d.h:249
Array2DCIterator(const Array2D< Type > *r, int x, int y)
Definition: array2d.h:191
int centerY
Definition: array2d.h:309
int getX(int neighbor) const
Definition: array2d.h:280
static Array2DIterator< Type > beginning(Array2D< Type > *r)
Definition: array2d.h:146
Array2DCIterator< Type > begin() const
Definition: array2d.h:109
IndexCollection indices() const
indices Returns a lightweight object for iterating over all valid (x,y) pairs.
Definition: array2d.h:96
Array2DCNeighborIterator< Type > operator++(int)
Definition: array2d.h:260
Array2D_Private::Array2DPointWrapper IndexCollection
Definition: array2d.h:39
const Type & operator*() const
Definition: array2d.h:266
int y
Definition: array2d.h:224
Array2D< Type > * arr
Definition: array2d.h:181
int x
Definition: array2d.h:224
static Array2DIterator< Type > ending(Array2D< Type > *r)
Definition: array2d.h:147
bool operator!=(const Array2DCIterator< Type > &other) const
Definition: array2d.h:197
bool operator==(const Array2DCIterator< Type > &other) const
Definition: array2d.h:193
const Array2D< Type > * arr
Definition: array2d.h:223
Type & operator()(QPoint p)
Definition: array2d.h:68
The Array2D class is basically a 2D implementation of QVector.
Definition: array2d.h:35
IndexedConstDataCollection indexedData() const
indexedData Returns a lightweight object for iterating over all data in the grid that also provides i...
Definition: array2d.h:105
Array2D(int rows, int cols, Type defaultValue)
Definition: array2d.h:48
Array2DIterator(Array2D< Type > *r, int x, int y)
Definition: array2d.h:149
Type & operator*()
Definition: array2d.h:176
static Array2DCIterator< Type > ending(const Array2D< Type > *r)
Definition: array2d.h:189
Array2DCIterator< Type > end() const
Definition: array2d.h:113
int neighborIndex
Definition: array2d.h:310
Definition: array2d.h:17
Array2DIterator< Type > end()
Definition: array2d.h:122
const Type & operator()(int r, int c) const
Definition: array2d.h:56
QSize size() const
Definition: array2d.h:79
Definition: array2d.h:14
const Array2D< Type > * arr
Definition: array2d.h:308
Definition: array2d.h:13
Array2DIterator< Type > & operator++()
Definition: array2d.h:159
Array2DIterator< Type > begin()
Definition: array2d.h:118
bool operator!=(const Array2DIterator< Type > &other) const
Definition: array2d.h:155
A lightweight class to allow looping through all the valid indices in Array2D.
Definition: array2d_private.h:75
Array2DCNeighborIterator< Type > end_neighbors(int x, int y) const
Definition: array2d.h:132
Array2DCNeighborIterator(const Array2D< Type > *r, int x, int y, int idx)
Definition: array2d.h:235