ITK  5.4.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
69template <unsigned int VDimension = 2>
70struct ITK_TEMPLATE_EXPORT Index final
71{
72public:
73 // Using the `rule of zero` to this aggregate type
74 // C++20 changes the definition of aggregate such that classes with any user-declared ctors are no longer aggregates.
75
77 using Self = Index;
78
82
85
89
91 static constexpr unsigned int Dimension = VDimension;
92
94 static constexpr unsigned int
96 {
97 return VDimension;
98 }
99
100
102 const Self
103 operator+(const SizeType & sz) const
104 {
105 Self result;
106
107 for (unsigned int i = 0; i < VDimension; ++i)
108 {
109 result[i] = m_InternalArray[i] + static_cast<IndexValueType>(sz[i]);
110 }
111 return result;
112 }
113
115 const Self &
117 {
118 for (unsigned int i = 0; i < VDimension; ++i)
119 {
120 m_InternalArray[i] += static_cast<IndexValueType>(sz[i]);
121 }
122 return *this;
123 }
128 const Self
129 operator-(const SizeType & sz) const
130 {
131 Self result;
132
133 for (unsigned int i = 0; i < VDimension; ++i)
134 {
135 result[i] = m_InternalArray[i] - static_cast<IndexValueType>(sz[i]);
136 }
137 return result;
138 }
139
141 const Self &
143 {
144 for (unsigned int i = 0; i < VDimension; ++i)
145 {
146 m_InternalArray[i] -= static_cast<IndexValueType>(sz[i]);
147 }
148 return *this;
149 }
153 const Self
154 operator+(const OffsetType & offset) const
155 {
156 Self result;
157
158 for (unsigned int i = 0; i < VDimension; ++i)
159 {
160 result[i] = m_InternalArray[i] + offset[i];
161 }
162 return result;
163 }
164
166 const Self &
167 operator+=(const OffsetType & offset)
168 {
169 for (unsigned int i = 0; i < VDimension; ++i)
170 {
171 m_InternalArray[i] += offset[i];
172 }
173 return *this;
174 }
178 const Self &
179 operator-=(const OffsetType & offset)
180 {
181 for (unsigned int i = 0; i < VDimension; ++i)
182 {
183 m_InternalArray[i] -= offset[i];
184 }
185 return *this;
186 }
190 const Self
191 operator-(const OffsetType & off) const
192 {
193 Self result;
194
195 for (unsigned int i = 0; i < VDimension; ++i)
196 {
197 result[i] = m_InternalArray[i] - off.m_InternalArray[i];
198 }
199 return result;
200 }
201
203 const OffsetType
204 operator-(const Self & vec) const
205 {
206 OffsetType result;
207
208 for (unsigned int i = 0; i < VDimension; ++i)
209 {
210 result[i] = m_InternalArray[i] - vec.m_InternalArray[i];
211 }
212 return result;
213 }
214
218 const Self operator*(const SizeType & vec) const
219 {
220 Self result;
221
222 for (unsigned int i = 0; i < VDimension; ++i)
223 {
224 result[i] = m_InternalArray[i] * static_cast<IndexValueType>(vec.m_InternalArray[i]);
225 }
226 return result;
227 }
228
231 const IndexValueType *
232 GetIndex() const
233 {
234 return m_InternalArray;
235 }
236
241 void
242 SetIndex(const IndexValueType val[VDimension])
243 {
244 std::copy_n(val, VDimension, m_InternalArray);
245 }
246
253 void
254 SetElement(unsigned long element, IndexValueType val)
255 {
256 m_InternalArray[element] = val;
257 }
258
266 GetElement(unsigned long element) const
267 {
268 return m_InternalArray[element];
269 }
270
273 void
275 {
276 std::fill_n(begin(), size(), value);
277 } // MATCH std::array assign, ITK Fill
278
283 /*
284 * Ask the compiler to align a type to the maximum useful alignment for the target
285 * machine you are compiling for. Whenever you leave out the alignment factor in an
286 * aligned attribute specification, the compiler automatically sets the alignment
287 * for the type to the largest alignment that is ever used for any data type on
288 * the target machine you are compiling for. Doing this can often make copy
289 * operations more efficient, because the compiler can use whatever instructions
290 * copy the biggest chunks of memory when performing copies to or from the variables
291 * that have types that you have aligned this way.
292 */
293 static_assert(VDimension > 0, "Error: Only positive value sized VDimension allowed");
294 alignas(IndexValueType) IndexValueType m_InternalArray[VDimension];
298 template <typename TCoordRep>
299 inline void
301 {
302 for (unsigned int i = 0; i < VDimension; ++i)
303 {
304 m_InternalArray[i] = Math::Round<IndexValueType>(point[i]);
305 }
306 }
310 template <typename TCoordRep>
311 inline void
313 {
314 for (unsigned int i = 0; i < VDimension; ++i)
315 {
316 m_InternalArray[i] = static_cast<IndexValueType>(point[i]);
317 }
318 }
324 static Self
325 GetBasisIndex(unsigned int dim);
326
327
328 // ======================= Mirror the access pattern behavior of the std::array class
338 using const_iterator = const value_type *;
339 using size_type = unsigned int;
340 using difference_type = ptrdiff_t;
341 using reverse_iterator = std::reverse_iterator<iterator>;
342 using const_reverse_iterator = std::reverse_iterator<const_iterator>;
343
348 void
349 assign(const value_type & newValue)
350 {
351 std::fill_n(begin(), size(), newValue);
352 }
353
354 void
355 swap(Index & other)
356 {
357 std::swap(m_InternalArray, other.m_InternalArray);
358 }
359
360 constexpr const_iterator
361 cbegin() const
362 {
363 return &m_InternalArray[0];
364 }
365
366 constexpr iterator
368 {
369 return &m_InternalArray[0];
370 }
371
372 constexpr const_iterator
373 begin() const
374 {
375 return &m_InternalArray[0];
376 }
377
378 constexpr const_iterator
379 cend() const
380 {
381 return &m_InternalArray[VDimension];
382 }
383
384 constexpr iterator
386 {
387 return &m_InternalArray[VDimension];
388 }
389
390 constexpr const_iterator
391 end() const
392 {
393 return &m_InternalArray[VDimension];
394 }
395
396 reverse_iterator
398 {
399 return reverse_iterator(end());
400 }
401
402 const_reverse_iterator
403 rbegin() const
404 {
405 return const_reverse_iterator(end());
406 }
407
408 reverse_iterator
410 {
411 return reverse_iterator(begin());
412 }
413
414 const_reverse_iterator
415 rend() const
416 {
417 return const_reverse_iterator(begin());
418 }
419
420 constexpr size_type
421 size() const
422 {
423 return VDimension;
424 }
425
426 constexpr size_type
427 max_size() const
428 {
429 return VDimension;
430 }
431
432 constexpr bool
433 empty() const
434 {
435 return false;
436 }
437
438 constexpr reference operator[](size_type pos) { return m_InternalArray[pos]; }
439
440 constexpr const_reference operator[](size_type pos) const { return m_InternalArray[pos]; }
441
442 reference
444 {
445 ExceptionThrowingBoundsCheck(pos);
446 return m_InternalArray[pos];
447 }
448
449 const_reference
450 at(size_type pos) const
451 {
452 ExceptionThrowingBoundsCheck(pos);
453 return m_InternalArray[pos];
454 }
455
456 reference
458 {
459 return *begin();
460 }
461
462 const_reference
463 front() const
464 {
465 return *begin();
466 }
467
468 reference
470 {
471 return VDimension ? *(end() - 1) : *end();
472 }
473
474 const_reference
475 back() const
476 {
477 return VDimension ? *(end() - 1) : *end();
478 }
479
482 {
483 return &m_InternalArray[0];
484 }
485
486 const IndexValueType *
487 data() const
488 {
489 return &m_InternalArray[0];
490 }
491
492
495 static constexpr Self
497 {
498 return MakeFilled<Self>(value);
499 }
500
501
502private:
503 void
505 {
506 if (pos >= VDimension)
507 {
508 throw std::out_of_range("array::ExceptionThrowingBoundsCheck");
509 }
510 }
511
512}; //------------ End struct Index
513
514template <unsigned int VDimension>
515Index<VDimension>
517{
518 Self ind{ { 0 } };
519
520 ind.m_InternalArray[dim] = 1;
521 return ind;
522}
523
524template <unsigned int VDimension>
525std::ostream &
526operator<<(std::ostream & os, const Index<VDimension> & obj)
527{
528 os << '[';
529 for (unsigned int i = 0; i + 1 < VDimension; ++i)
530 {
531 os << obj[i] << ", ";
532 }
533 if (VDimension >= 1)
534 {
535 os << obj[VDimension - 1];
536 }
537 os << ']';
538 return os;
539}
540
541// ======================= Mirror the access pattern behavior of the std::array class
542// Array comparisons.
543template <unsigned int VDimension>
544inline bool
546{
547 return std::equal(one.begin(), one.end(), two.begin());
548}
549
550template <unsigned int VDimension>
551inline bool
553{
554 return !(one == two);
555}
556
557template <unsigned int VDimension>
558inline bool
559operator<(const Index<VDimension> & one, const Index<VDimension> & two)
560{
561 return std::lexicographical_compare(one.begin(), one.end(), two.begin(), two.end());
562}
563
564template <unsigned int VDimension>
565inline bool
567{
568 return two < one;
569}
570
571template <unsigned int VDimension>
572inline bool
573operator<=(const Index<VDimension> & one, const Index<VDimension> & two)
574{
575 return !(one > two);
576}
577
578template <unsigned int VDimension>
579inline bool
581{
582 return !(one < two);
583}
584
585// Specialized algorithms [6.2.2.2].
586template <unsigned int VDimension>
587inline void
589{
591}
592
593
595template <typename... T>
596auto
597MakeIndex(const T... values)
598{
599 const auto toValueType = [](const auto value) {
600 static_assert(std::is_integral_v<decltype(value)>, "Each value must have an integral type!");
601 return static_cast<IndexValueType>(value);
602 };
603 return Index<sizeof...(T)>{ { toValueType(values)... } };
604}
607} // end namespace itk
608
609#endif
Pixel-wise addition of two images.
Simulate a standard C array with copy semantics.
Definition: itkFixedArray.h:54
std::ostream & operator<<(std::ostream &os, const itk::DOMNode &object)
The "itk" namespace contains all Insight Segmentation and Registration Toolkit (ITK) classes....
auto MakeIndex(const T... values)
Definition: itkIndex.h:597
*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:588
bool operator>(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:566
bool operator<=(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:573
long IndexValueType
Definition: itkIntTypes.h:90
bool operator==(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:545
bool operator!=(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:552
bool operator<(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:559
bool operator>=(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:580
long OffsetValueType
Definition: itkIntTypes.h:94
Represent a n-dimensional index in a n-dimensional image.
Definition: itkIndex.h:71
constexpr const_reference operator[](size_type pos) const
Definition: itkIndex.h:440
const Self operator*(const SizeType &vec) const
Definition: itkIndex.h:218
const OffsetType operator-(const Self &vec) const
Definition: itkIndex.h:204
void CopyWithCast(const FixedArray< TCoordRep, VDimension > &point)
Definition: itkIndex.h:312
const Self & operator+=(const OffsetType &offset)
Definition: itkIndex.h:167
const value_type * const_iterator
Definition: itkIndex.h:338
const Self & operator-=(const SizeType &sz)
Definition: itkIndex.h:142
const_reverse_iterator rbegin() const
Definition: itkIndex.h:403
static constexpr Self Filled(const IndexValueType value)
Definition: itkIndex.h:496
reverse_iterator rend()
Definition: itkIndex.h:409
void assign(const value_type &newValue)
Definition: itkIndex.h:349
value_type * iterator
Definition: itkIndex.h:337
const_reference front() const
Definition: itkIndex.h:463
constexpr size_type max_size() const
Definition: itkIndex.h:427
reverse_iterator rbegin()
Definition: itkIndex.h:397
void swap(Index &other)
Definition: itkIndex.h:355
void CopyWithRound(const FixedArray< TCoordRep, VDimension > &point)
Definition: itkIndex.h:300
const_reverse_iterator rend() const
Definition: itkIndex.h:415
void ExceptionThrowingBoundsCheck(size_type pos) const
Definition: itkIndex.h:504
IndexValueType m_InternalArray[VDimension]
Definition: itkIndex.h:293
constexpr bool empty() const
Definition: itkIndex.h:433
constexpr size_type size() const
Definition: itkIndex.h:421
const IndexValueType * GetIndex() const
Definition: itkIndex.h:232
constexpr const_iterator begin() const
Definition: itkIndex.h:373
const Self operator-(const OffsetType &off) const
Definition: itkIndex.h:191
static Self GetBasisIndex(unsigned int dim)
Definition: itkIndex.h:516
unsigned int size_type
Definition: itkIndex.h:339
itk::IndexValueType IndexValueType
Definition: itkIndex.h:81
reference at(size_type pos)
Definition: itkIndex.h:443
const Self operator+(const SizeType &sz) const
Definition: itkIndex.h:103
std::reverse_iterator< iterator > reverse_iterator
Definition: itkIndex.h:341
itk::IndexValueType value_type
Definition: itkIndex.h:334
const value_type & const_reference
Definition: itkIndex.h:336
std::reverse_iterator< const_iterator > const_reverse_iterator
Definition: itkIndex.h:342
IndexValueType GetElement(unsigned long element) const
Definition: itkIndex.h:266
constexpr reference operator[](size_type pos)
Definition: itkIndex.h:438
const_reference back() const
Definition: itkIndex.h:475
constexpr const_iterator end() const
Definition: itkIndex.h:391
reference back()
Definition: itkIndex.h:469
constexpr iterator end()
Definition: itkIndex.h:385
const Self operator-(const SizeType &sz) const
Definition: itkIndex.h:129
void Fill(IndexValueType value)
Definition: itkIndex.h:274
const IndexValueType * data() const
Definition: itkIndex.h:487
void SetElement(unsigned long element, IndexValueType val)
Definition: itkIndex.h:254
reference front()
Definition: itkIndex.h:457
const Self & operator+=(const SizeType &sz)
Definition: itkIndex.h:116
constexpr iterator begin()
Definition: itkIndex.h:367
value_type & reference
Definition: itkIndex.h:335
IndexValueType * data()
Definition: itkIndex.h:481
const Self operator+(const OffsetType &offset) const
Definition: itkIndex.h:154
ptrdiff_t difference_type
Definition: itkIndex.h:340
constexpr const_iterator cend() const
Definition: itkIndex.h:379
itk::OffsetValueType OffsetValueType
Definition: itkIndex.h:88
constexpr const_iterator cbegin() const
Definition: itkIndex.h:361
static constexpr unsigned int GetIndexDimension()
Definition: itkIndex.h:95
void SetIndex(const IndexValueType val[VDimension])
Definition: itkIndex.h:242
const Self & operator-=(const OffsetType &offset)
Definition: itkIndex.h:179
const_reference at(size_type pos) const
Definition: itkIndex.h:450
OffsetValueType m_InternalArray[VDimension]
Definition: itkOffset.h:245
SizeValueType m_InternalArray[VDimension]
Definition: itkSize.h:245