TIndex.h
Go to the documentation of this file.
1 #ifndef istd_TIndex_included
2 #define istd_TIndex_included
3 
4 
5 // Qt includes
6 #include <QtCore/QtGlobal>
7 
8 
9 namespace istd
10 {
11 
12 
16 template <int Dimensions>
17 class TIndex
18 {
19 public:
20  typedef int IndexType;
21  typedef int* Iterator;
22 
23  enum
24  {
25  DIMENSIONS = Dimensions
26  };
27 
31  TIndex();
32 
36  explicit TIndex(int value);
37 
41  TIndex(const TIndex& index);
42 
47  bool IsValid() const;
48 
53  bool IsZero() const;
54 
59  bool IsSizeEmpty() const;
60 
66  void Reset();
67 
71  void Clear();
72 
77  bool IsDimensionsCountFixed() const;
78 
82  int GetDimensionsCount() const;
83 
90  bool SetDimensionsCount(int count) const;
91 
95  int GetAt(int index) const;
96 
100  void SetAt(int index, int value);
101 
105  void SetAllTo(int value);
106 
112  bool IncreaseAt(int index);
113 
119  bool DecreaseAt(int index);
120 
125  bool IsInside(const TIndex& boundaries) const;
126 
131  bool Increase(const TIndex& boundaries);
132 
137  bool Decrease(const TIndex& boundaries);
138 
143  int GetProductVolume() const;
144 
148  int GetIterationIndex(const TIndex& boundaries) const;
149 
154  Iterator Begin() const;
159  Iterator End() const;
160 
161  int operator[](int index) const;
162  int& operator[](int index);
163 
164  bool operator==(const TIndex& index) const;
165  bool operator!=(const TIndex& index) const;
166 
167  TIndex operator+(const TIndex& index) const;
168  TIndex& operator+=(const TIndex& index);
169  TIndex operator-(const TIndex& index) const;
170  TIndex& operator-=(const TIndex& index);
171 
172  // static methods
176  static const TIndex<Dimensions>& GetZero();
180  static const TIndex<Dimensions>& GetInvalid();
181 
182 private:
183  int m_elements[Dimensions];
184 
185  // static attributes
186  static TIndex<Dimensions> s_zeroInstance;
187  static TIndex<Dimensions> s_invalidInstance;
188 };
189 
190 
191 // inline methods
192 
193 template <int Dimensions>
195 {
196  return true;
197 }
198 
199 
200 template <int Dimensions>
202 {
203  return Dimensions;
204 }
205 
206 
207 template <int Dimensions>
208 inline bool TIndex<Dimensions>::SetDimensionsCount(int count) const
209 {
210  return (count == GetDimensionsCount());
211 }
212 
213 
214 template <int Dimensions>
215 inline bool TIndex<Dimensions>::IsValid() const
216 {
217  for (int i = 0; i < Dimensions; ++i){
218  if (m_elements[i] < 0){
219  return false;
220  }
221  }
222 
223  return true;
224 }
225 
226 
227 template <int Dimensions>
228 inline bool TIndex<Dimensions>::IsZero() const
229 {
230  for (int i = 0; i < Dimensions; ++i){
231  if (m_elements[i] > 0){
232  return false;
233  }
234  }
235 
236  return true;
237 }
238 
239 
240 template <int Dimensions>
242 {
243  for (int i = 0; i < Dimensions; ++i){
244  if (m_elements[i] <= 0){
245  return true;
246  }
247  }
248 
249  return false;
250 }
251 
252 
253 template <int Dimensions>
255 {
256  Clear();
257 }
258 
259 
260 template <int Dimensions>
262 {
263  SetAllTo(0);
264 }
265 
266 
267 template <int Dimensions>
268 inline int TIndex<Dimensions>::GetAt(int index) const
269 {
270  Q_ASSERT(index >= 0);
271  Q_ASSERT(index < Dimensions);
272 
273  return m_elements[index];
274 }
275 
276 
277 template <int Dimensions>
278 inline void TIndex<Dimensions>::SetAt(int index, int value)
279 {
280  Q_ASSERT(index >= 0);
281  Q_ASSERT(index < Dimensions);
282 
283  m_elements[index] = value;
284 }
285 
286 
287 template <int Dimensions>
288 inline bool TIndex<Dimensions>::IncreaseAt(int index)
289 {
290  Q_ASSERT(index >= 0);
291  Q_ASSERT(index < Dimensions);
292 
293  ++m_elements[index];
294 
295  return true;
296 }
297 
298 
299 template <int Dimensions>
300 inline bool TIndex<Dimensions>::DecreaseAt(int index)
301 {
302  Q_ASSERT(index >= 0);
303  Q_ASSERT(index < Dimensions);
304 
305  --m_elements[index];
306 
307  return true;
308 }
309 
310 
311 template <int Dimensions>
313 {
314  return (Iterator)&m_elements[0];
315 }
316 
317 
318 template <int Dimensions>
320 {
321  return (Iterator)&m_elements[Dimensions];
322 }
323 
324 
325 template <int Dimensions>
326 inline int TIndex<Dimensions>::operator[](int index) const
327 {
328  return GetAt(index);
329 }
330 
331 
332 template <int Dimensions>
333 inline int& TIndex<Dimensions>::operator[](int index)
334 {
335  Q_ASSERT(index >= 0);
336  Q_ASSERT(index < Dimensions);
337 
338  return m_elements[index];
339 }
340 
341 
342 template <int Dimensions>
343 bool TIndex<Dimensions>::operator==(const TIndex& index) const
344 {
345  for (int i = 0; i < Dimensions; ++i){
346  if (m_elements[i] != index.m_elements[i]){
347  return false;
348  }
349  }
350 
351  return true;
352 }
353 
354 
355 template <int Dimensions>
356 bool TIndex<Dimensions>::operator!=(const TIndex& index) const
357 {
358  return !operator==(index);
359 }
360 
361 
362 template <int Dimensions>
364 {
365  Q_ASSERT(Dimensions >= index.GetDimensionsCount());
366 
367  TIndex<Dimensions> retVal = *this;
368 
369  for (int i = 0; i < Dimensions; ++i){
370  retVal[i] += index[i];
371  }
372 
373  return retVal;
374 }
375 
376 
377 template <int Dimensions>
379 {
380  Q_ASSERT(Dimensions >= index.GetDimensionsCount());
381 
382  for (int i = 0; i < Dimensions; ++i){
383  m_elements[i] += index[i];
384  }
385 
386  return *this;
387 }
388 
389 
390 template <int Dimensions>
392 {
393  Q_ASSERT(Dimensions >= index.GetDimensionsCount());
394 
395  TIndex<Dimensions> retVal = *this;
396 
397  for (int i = 0; i < Dimensions; ++i){
398  retVal[i] -= index[i];
399  }
400 
401  return retVal;
402 }
403 
404 
405 template <int Dimensions>
407 {
408  Q_ASSERT(Dimensions >= index.GetDimensionsCount());
409 
410  for (int i = 0; i < Dimensions; ++i){
411  m_elements[i] -= index[i];
412  }
413 
414  return *this;
415 }
416 
417 
418 
419 // public methods
420 
421 template <int Dimensions>
423 {
424  SetAllTo(value);
425 }
426 
427 
428 template <int Dimensions>
430 {
431  for (int i = 0; i < Dimensions; ++i){
432  m_elements[i] = 0;
433  }
434 }
435 
436 
437 template <int Dimensions>
439 {
440  for (int i = 0; i < Dimensions; ++i){
441  m_elements[i] = index.m_elements[i];
442  }
443 }
444 
445 
446 template <int Dimensions>
448 {
449  for (int i = 0; i < Dimensions; ++i){
450  m_elements[i] = value;
451  }
452 }
453 
454 
455 template <int Dimensions>
456 bool TIndex<Dimensions>::IsInside(const TIndex& boundaries) const
457 {
458  for (int i = 0; i < Dimensions; ++i){
459  Q_ASSERT(m_elements[i] >= 0);
460 
461  if (m_elements[i] >= boundaries.m_elements[i]){
462  return false;
463  }
464  }
465 
466  return true;
467 }
468 
469 
470 template <int Dimensions>
471 bool TIndex<Dimensions>::Increase(const TIndex& boundaries)
472 {
473  Q_ASSERT(IsInside(boundaries));
474 
475  for (int i = 0; i < Dimensions; ++i){
476  if (m_elements[i] < boundaries.m_elements[i] - 1){
477  m_elements[i]++;
478  for (int j = 0; j < i; ++j){
479  m_elements[j] = 0;
480  }
481 
482  return true;
483  }
484  }
485 
486  SetAllTo(0);
487 
488  return false;
489 }
490 
491 
492 template <int Dimensions>
493 bool TIndex<Dimensions>::Decrease(const TIndex& boundaries)
494 {
495  Q_ASSERT(IsInside(boundaries));
496 
497  for (int i = 0; i < Dimensions; ++i){
498  if (m_elements[i] > 0){
499  m_elements[i]--;
500 
501  for (int j = 0; j < i; ++j){
502  m_elements[j] = boundaries.m_elements[j] - 1;
503  }
504 
505  return true;
506  }
507  }
508 
509  for (int j = 0; j < Dimensions; ++j){
510  m_elements[j] = boundaries.m_elements[j] - 1;
511  }
512 
513  return false;
514 }
515 
516 
517 template <int Dimensions>
519 {
520  int retVal = 1;
521 
522  for (int i = 0; i < Dimensions; ++i){
523  retVal *= m_elements[i];
524  }
525 
526  return retVal;
527 }
528 
529 
530 template <int Dimensions>
531 int TIndex<Dimensions>::GetIterationIndex(const TIndex& boundaries) const
532 {
533  int retVal = 0;
534 
535  int positionBase = 1;
536  for (int i = 0; i < Dimensions; ++i){
537  retVal += m_elements[i] * positionBase;
538 
539  positionBase *= boundaries.m_elements[i];
540  }
541 
542  return retVal;
543 }
544 
545 
546 // static methods
547 
548 template <int Dimensions>
550 {
551  return s_zeroInstance;
552 }
553 
554 
555 template <int Dimensions>
557 {
558  return s_invalidInstance;
559 }
560 
561 
562 // static attributes
563 
564 template <int Dimensions>
566 template <int Dimensions>
568 
569 
570 // related global functions
571 
572 template <int Dimensions>
573 inline uint qHash(const TIndex<Dimensions>& key, uint seed = 0)
574 {
575  uint retVal = seed;
576 
577  for (int i = 0; i < Dimensions; ++i){
578  uint value = uint(key[i]);
579 
580  retVal *= 16187; // some big enough prime number
581  retVal ^= value;
582  }
583 
584  return retVal;
585 }
586 
587 
588 } // namespace istd
589 
590 
591 #endif // !istd_TIndex_included
592 
593 
static const TIndex< Dimensions > & GetZero()
Get global instance of zero index.
Definition: TIndex.h:549
bool operator!=(const TIndex &index) const
Definition: TIndex.h:356
int IndexType
Definition: TIndex.h:20
int * Iterator
Definition: TIndex.h:21
bool operator==(const TIndex &index) const
Definition: TIndex.h:343
bool SetDimensionsCount(int count) const
Set number of dimensions of this index.
Definition: TIndex.h:208
bool Decrease(const TIndex &boundaries)
Decrease this index inside the boundaries.
Definition: TIndex.h:493
bool IsZero() const
Check if this index point at zero element.
Definition: TIndex.h:228
Multidimensional index used to addressing fixed-size array.
Definition: TIndex.h:17
bool IsSizeEmpty() const
Check if this index interpreted as size is empty.
Definition: TIndex.h:241
Iterator Begin() const
Get begin value of element access iterator.
Definition: TIndex.h:312
void Reset()
Reset this object.
Definition: TIndex.h:254
static const TIndex< Dimensions > & GetInvalid()
Get global instance of invalid index.
Definition: TIndex.h:556
void SetAllTo(int value)
Set all components to specified value.
Definition: TIndex.h:447
int GetIterationIndex(const TIndex &boundaries) const
Get index of iteration from zero to current index inside some boundaries.
Definition: TIndex.h:531
bool DecreaseAt(int index)
Decrease single component at specified position.
Definition: TIndex.h:300
uint qHash(const CVarIndex &index, uint seed=0)
TIndex & operator-=(const TIndex &index)
Definition: TIndex.h:406
int operator[](int index) const
Definition: TIndex.h:326
int GetAt(int index) const
Get element stored at specified index.
Definition: TIndex.h:268
TIndex()
Default constructor with initialization of member to 0.
Definition: TIndex.h:429
bool IsDimensionsCountFixed() const
Check, if number dimensions is fixed.
Definition: TIndex.h:194
void SetAt(int index, int value)
Set element at specified index.
Definition: TIndex.h:278
bool Increase(const TIndex &boundaries)
Increase this index inside the boundaries.
Definition: TIndex.h:471
TIndex operator-(const TIndex &index) const
Definition: TIndex.h:391
TIndex & operator+=(const TIndex &index)
Definition: TIndex.h:378
bool IsInside(const TIndex &boundaries) const
Check if index is inside boundaries.
Definition: TIndex.h:456
bool IsValid() const
Check if this index is valid.
Definition: TIndex.h:215
bool IncreaseAt(int index)
Increase single component at specified position.
Definition: TIndex.h:288
int GetDimensionsCount() const
Get number of dimensions of this index.
Definition: TIndex.h:201
TIndex operator+(const TIndex &index) const
Definition: TIndex.h:363
void Clear()
Set all components to 0.
Definition: TIndex.h:261
Iterator End() const
Get end value of element access iterator.
Definition: TIndex.h:319
int GetProductVolume() const
Get total number of elements if this index is treated as size.
Definition: TIndex.h:518

© 2007-2017 Witold Gantzke and Kirill Lepskiy