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