ITK  6.0.0
Insight Toolkit
itkIndex.h
Go to the documentation of this file.
1/*=========================================================================
2 *
3 * Copyright NumFOCUS
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * https://www.apache.org/licenses/LICENSE-2.0.txt
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 *=========================================================================*/
18#ifndef itkIndex_h
19#define itkIndex_h
20
21#include "itkMakeFilled.h"
22#include "itkOffset.h"
23
24#include <cstddef> // For ptrdiff_t.
25#include <type_traits> // For is_integral.
26
27namespace itk
28{
29
67template <unsigned int VDimension = 2>
68struct ITK_TEMPLATE_EXPORT Index final
69{
70public:
71 // Using the `rule of zero` to this aggregate type
72 // C++20 changes the definition of aggregate such that classes with any user-declared ctors are no longer aggregates.
73
75 using Self = Index;
76
80
83
87
89 static constexpr unsigned int Dimension = VDimension;
90
92 static constexpr unsigned int
94 {
95 return VDimension;
96 }
97
98
100 const Self
101 operator+(const SizeType & sz) const
102 {
103 Self result;
104
105 for (unsigned int i = 0; i < VDimension; ++i)
106 {
107 result[i] = m_InternalArray[i] + static_cast<IndexValueType>(sz[i]);
108 }
109 return result;
110 }
111
113 const Self &
115 {
116 for (unsigned int i = 0; i < VDimension; ++i)
117 {
118 m_InternalArray[i] += static_cast<IndexValueType>(sz[i]);
119 }
120 return *this;
121 }
126 const Self
127 operator-(const SizeType & sz) const
128 {
129 Self result;
130
131 for (unsigned int i = 0; i < VDimension; ++i)
132 {
133 result[i] = m_InternalArray[i] - static_cast<IndexValueType>(sz[i]);
134 }
135 return result;
136 }
137
139 const Self &
141 {
142 for (unsigned int i = 0; i < VDimension; ++i)
143 {
144 m_InternalArray[i] -= static_cast<IndexValueType>(sz[i]);
145 }
146 return *this;
147 }
151 const Self
152 operator+(const OffsetType & offset) const
153 {
154 Self result;
155
156 for (unsigned int i = 0; i < VDimension; ++i)
157 {
158 result[i] = m_InternalArray[i] + offset[i];
159 }
160 return result;
161 }
162
164 const Self &
165 operator+=(const OffsetType & offset)
166 {
167 for (unsigned int i = 0; i < VDimension; ++i)
168 {
169 m_InternalArray[i] += offset[i];
170 }
171 return *this;
172 }
176 const Self &
177 operator-=(const OffsetType & offset)
178 {
179 for (unsigned int i = 0; i < VDimension; ++i)
180 {
181 m_InternalArray[i] -= offset[i];
182 }
183 return *this;
184 }
188 const Self
189 operator-(const OffsetType & off) const
190 {
191 Self result;
192
193 for (unsigned int i = 0; i < VDimension; ++i)
194 {
195 result[i] = m_InternalArray[i] - off.m_InternalArray[i];
196 }
197 return result;
198 }
199
201 const OffsetType
202 operator-(const Self & vec) const
203 {
204 OffsetType result;
205
206 for (unsigned int i = 0; i < VDimension; ++i)
207 {
208 result[i] = m_InternalArray[i] - vec.m_InternalArray[i];
209 }
210 return result;
211 }
212
216 const Self operator*(const SizeType & vec) const
217 {
218 Self result;
219
220 for (unsigned int i = 0; i < VDimension; ++i)
221 {
222 result[i] = m_InternalArray[i] * static_cast<IndexValueType>(vec.m_InternalArray[i]);
223 }
224 return result;
225 }
226
229 const IndexValueType *
230 GetIndex() const
231 {
232 return m_InternalArray;
233 }
234
239 void
240 SetIndex(const IndexValueType val[VDimension])
241 {
242 std::copy_n(val, VDimension, m_InternalArray);
243 }
244
251 void
252 SetElement(unsigned long element, IndexValueType val)
253 {
254 m_InternalArray[element] = val;
255 }
256
264 GetElement(unsigned long element) const
265 {
266 return m_InternalArray[element];
267 }
268
271 void
273 {
274 std::fill_n(begin(), size(), value);
275 } // MATCH std::array assign, ITK Fill
276
281 /*
282 * Ask the compiler to align a type to the maximum useful alignment for the target
283 * machine you are compiling for. Whenever you leave out the alignment factor in an
284 * aligned attribute specification, the compiler automatically sets the alignment
285 * for the type to the largest alignment that is ever used for any data type on
286 * the target machine you are compiling for. Doing this can often make copy
287 * operations more efficient, because the compiler can use whatever instructions
288 * copy the biggest chunks of memory when performing copies to or from the variables
289 * that have types that you have aligned this way.
290 */
291 static_assert(VDimension > 0, "Error: Only positive value sized VDimension allowed");
292 alignas(IndexValueType) IndexValueType m_InternalArray[VDimension];
296 template <typename TCoordRep>
297 inline void
299 {
300 for (unsigned int i = 0; i < VDimension; ++i)
301 {
302 m_InternalArray[i] = Math::Round<IndexValueType>(point[i]);
303 }
304 }
308 template <typename TCoordRep>
309 inline void
311 {
312 for (unsigned int i = 0; i < VDimension; ++i)
313 {
314 m_InternalArray[i] = static_cast<IndexValueType>(point[i]);
315 }
316 }
322 static Self
323 GetBasisIndex(unsigned int dim);
324
325
326 // ======================= Mirror the access pattern behavior of the std::array class
336 using const_iterator = const value_type *;
337 using size_type = unsigned int;
338 using difference_type = ptrdiff_t;
339 using reverse_iterator = std::reverse_iterator<iterator>;
340 using const_reverse_iterator = std::reverse_iterator<const_iterator>;
341
346 void
347 assign(const value_type & newValue)
348 {
349 std::fill_n(begin(), size(), newValue);
350 }
351
352 void
353 swap(Index & other)
354 {
355 std::swap(m_InternalArray, other.m_InternalArray);
356 }
357
358 constexpr const_iterator
359 cbegin() const
360 {
361 return &m_InternalArray[0];
362 }
363
364 constexpr iterator
366 {
367 return &m_InternalArray[0];
368 }
369
370 constexpr const_iterator
371 begin() const
372 {
373 return &m_InternalArray[0];
374 }
375
376 constexpr const_iterator
377 cend() const
378 {
379 return &m_InternalArray[VDimension];
380 }
381
382 constexpr iterator
384 {
385 return &m_InternalArray[VDimension];
386 }
387
388 constexpr const_iterator
389 end() const
390 {
391 return &m_InternalArray[VDimension];
392 }
393
394 reverse_iterator
396 {
397 return reverse_iterator(end());
398 }
399
400 const_reverse_iterator
401 rbegin() const
402 {
403 return const_reverse_iterator(end());
404 }
405
406 reverse_iterator
408 {
409 return reverse_iterator(begin());
410 }
411
412 const_reverse_iterator
413 rend() const
414 {
415 return const_reverse_iterator(begin());
416 }
417
418 constexpr size_type
419 size() const
420 {
421 return VDimension;
422 }
423
424 constexpr size_type
425 max_size() const
426 {
427 return VDimension;
428 }
429
430 constexpr bool
431 empty() const
432 {
433 return false;
434 }
435
436 constexpr reference operator[](size_type pos) { return m_InternalArray[pos]; }
437
438 constexpr const_reference operator[](size_type pos) const { return m_InternalArray[pos]; }
439
440 reference
442 {
443 ExceptionThrowingBoundsCheck(pos);
444 return m_InternalArray[pos];
445 }
446
447 const_reference
448 at(size_type pos) const
449 {
450 ExceptionThrowingBoundsCheck(pos);
451 return m_InternalArray[pos];
452 }
453
454 constexpr reference
456 {
457 return *begin();
458 }
459
460 constexpr const_reference
461 front() const
462 {
463 return *begin();
464 }
465
466 constexpr reference
468 {
469 return VDimension ? *(end() - 1) : *end();
470 }
471
472 constexpr const_reference
473 back() const
474 {
475 return VDimension ? *(end() - 1) : *end();
476 }
477
480 {
481 return &m_InternalArray[0];
482 }
483
484 const IndexValueType *
485 data() const
486 {
487 return &m_InternalArray[0];
488 }
489
490
493 static constexpr Self
495 {
496 return MakeFilled<Self>(value);
497 }
498
499
500private:
501 void
503 {
504 if (pos >= VDimension)
505 {
506 throw std::out_of_range("array::ExceptionThrowingBoundsCheck");
507 }
508 }
509
510}; //------------ End struct Index
511
512template <unsigned int VDimension>
513Index<VDimension>
515{
516 Self ind{ { 0 } };
517
518 ind.m_InternalArray[dim] = 1;
519 return ind;
520}
521
522template <unsigned int VDimension>
523std::ostream &
524operator<<(std::ostream & os, const Index<VDimension> & obj)
525{
526 os << '[';
527 for (unsigned int i = 0; i + 1 < VDimension; ++i)
528 {
529 os << obj[i] << ", ";
530 }
531 if constexpr (VDimension >= 1)
532 {
533 os << obj[VDimension - 1];
534 }
535 os << ']';
536 return os;
537}
538
539// ======================= Mirror the access pattern behavior of the std::array class
540// Array comparisons.
541template <unsigned int VDimension>
542inline bool
544{
545 return std::equal(one.begin(), one.end(), two.begin());
546}
547
548template <unsigned int VDimension>
549inline bool
551{
552 return !(one == two);
553}
554
555template <unsigned int VDimension>
556inline bool
557operator<(const Index<VDimension> & one, const Index<VDimension> & two)
558{
559 return std::lexicographical_compare(one.begin(), one.end(), two.begin(), two.end());
560}
561
562template <unsigned int VDimension>
563inline bool
565{
566 return two < one;
567}
568
569template <unsigned int VDimension>
570inline bool
571operator<=(const Index<VDimension> & one, const Index<VDimension> & two)
572{
573 return !(one > two);
574}
575
576template <unsigned int VDimension>
577inline bool
579{
580 return !(one < two);
581}
582
583// Specialized algorithms [6.2.2.2].
584template <unsigned int VDimension>
585inline void
587{
589}
590
591
593template <typename... T>
594auto
595MakeIndex(const T... values)
596{
597 const auto toValueType = [](const auto value) {
598 static_assert(std::is_integral_v<decltype(value)>, "Each value must have an integral type!");
599 return static_cast<IndexValueType>(value);
600 };
601 return Index<sizeof...(T)>{ { toValueType(values)... } };
602}
605} // end namespace itk
606
607#endif
Pixel-wise addition of two images.
Simulate a standard C array with copy semantics.
Definition: itkFixedArray.h:54
The "itk" namespace contains all Insight Segmentation and Registration Toolkit (ITK) classes....
auto MakeIndex(const T... values)
Definition: itkIndex.h:595
*par Constraints *The filter image with at least two dimensions and a vector *length of at least The theory supports extension to scalar but *the implementation of the itk vector classes do not **The template parameter TRealType must be floating point(float or double) or *a user-defined "real" numerical type with arithmetic operations defined *sufficient to compute derivatives. **\par Performance *This filter will automatically multithread if run with *SetUsePrincipleComponents
void swap(Index< VDimension > &one, Index< VDimension > &two)
Definition: itkIndex.h:586
bool operator>(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:564
bool operator<=(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:571
long IndexValueType
Definition: itkIntTypes.h:93
bool operator==(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:543
std::ostream & operator<<(std::ostream &os, const Index< VDimension > &obj)
Definition: itkIndex.h:524
bool operator!=(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:550
bool operator<(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:557
bool operator>=(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:578
long OffsetValueType
Definition: itkIntTypes.h:97
Represent a n-dimensional index in a n-dimensional image.
Definition: itkIndex.h:69
constexpr const_reference operator[](size_type pos) const
Definition: itkIndex.h:438
const Self operator*(const SizeType &vec) const
Definition: itkIndex.h:216
const OffsetType operator-(const Self &vec) const
Definition: itkIndex.h:202
void CopyWithCast(const FixedArray< TCoordRep, VDimension > &point)
Definition: itkIndex.h:310
const Self & operator+=(const OffsetType &offset)
Definition: itkIndex.h:165
const value_type * const_iterator
Definition: itkIndex.h:336
constexpr reference front()
Definition: itkIndex.h:455
const Self & operator-=(const SizeType &sz)
Definition: itkIndex.h:140
const_reverse_iterator rbegin() const
Definition: itkIndex.h:401
static constexpr Self Filled(const IndexValueType value)
Definition: itkIndex.h:494
reverse_iterator rend()
Definition: itkIndex.h:407
void assign(const value_type &newValue)
Definition: itkIndex.h:347
value_type * iterator
Definition: itkIndex.h:335
constexpr size_type max_size() const
Definition: itkIndex.h:425
reverse_iterator rbegin()
Definition: itkIndex.h:395
void swap(Index &other)
Definition: itkIndex.h:353
void CopyWithRound(const FixedArray< TCoordRep, VDimension > &point)
Definition: itkIndex.h:298
const_reverse_iterator rend() const
Definition: itkIndex.h:413
void ExceptionThrowingBoundsCheck(size_type pos) const
Definition: itkIndex.h:502
IndexValueType m_InternalArray[VDimension]
Definition: itkIndex.h:291
constexpr bool empty() const
Definition: itkIndex.h:431
constexpr size_type size() const
Definition: itkIndex.h:419
const IndexValueType * GetIndex() const
Definition: itkIndex.h:230
constexpr const_iterator begin() const
Definition: itkIndex.h:371
const Self operator-(const OffsetType &off) const
Definition: itkIndex.h:189
static Self GetBasisIndex(unsigned int dim)
Definition: itkIndex.h:514
unsigned int size_type
Definition: itkIndex.h:337
itk::IndexValueType IndexValueType
Definition: itkIndex.h:79
reference at(size_type pos)
Definition: itkIndex.h:441
const Self operator+(const SizeType &sz) const
Definition: itkIndex.h:101
std::reverse_iterator< iterator > reverse_iterator
Definition: itkIndex.h:339
itk::IndexValueType value_type
Definition: itkIndex.h:332
const value_type & const_reference
Definition: itkIndex.h:334
std::reverse_iterator< const_iterator > const_reverse_iterator
Definition: itkIndex.h:340
IndexValueType GetElement(unsigned long element) const
Definition: itkIndex.h:264
constexpr reference operator[](size_type pos)
Definition: itkIndex.h:436
constexpr const_iterator end() const
Definition: itkIndex.h:389
constexpr reference back()
Definition: itkIndex.h:467
constexpr iterator end()
Definition: itkIndex.h:383
const Self operator-(const SizeType &sz) const
Definition: itkIndex.h:127
void Fill(IndexValueType value)
Definition: itkIndex.h:272
constexpr const_reference back() const
Definition: itkIndex.h:473
const IndexValueType * data() const
Definition: itkIndex.h:485
void SetElement(unsigned long element, IndexValueType val)
Definition: itkIndex.h:252
const Self & operator+=(const SizeType &sz)
Definition: itkIndex.h:114
constexpr iterator begin()
Definition: itkIndex.h:365
value_type & reference
Definition: itkIndex.h:333
IndexValueType * data()
Definition: itkIndex.h:479
const Self operator+(const OffsetType &offset) const
Definition: itkIndex.h:152
ptrdiff_t difference_type
Definition: itkIndex.h:338
constexpr const_iterator cend() const
Definition: itkIndex.h:377
constexpr const_reference front() const
Definition: itkIndex.h:461
itk::OffsetValueType OffsetValueType
Definition: itkIndex.h:86
constexpr const_iterator cbegin() const
Definition: itkIndex.h:359
static constexpr unsigned int GetIndexDimension()
Definition: itkIndex.h:93
void SetIndex(const IndexValueType val[VDimension])
Definition: itkIndex.h:240
const Self & operator-=(const OffsetType &offset)
Definition: itkIndex.h:177
const_reference at(size_type pos) const
Definition: itkIndex.h:448
OffsetValueType m_InternalArray[VDimension]
Definition: itkOffset.h:242
SizeValueType m_InternalArray[VDimension]
Definition: itkSize.h:243