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 
27 namespace itk
28 {
29 
67 template <unsigned int VDimension = 2>
68 struct ITK_TEMPLATE_EXPORT Index final
69 {
70 public:
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 &
114  operator+=(const SizeType & sz)
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 &
140  operator-=(const SizeType & sz)
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
217  operator*(const SizeType & vec) const
218  {
219  Self result;
220 
221  for (unsigned int i = 0; i < VDimension; ++i)
222  {
223  result[i] = m_InternalArray[i] * static_cast<IndexValueType>(vec.m_InternalArray[i]);
224  }
225  return result;
226  }
227 
230  const IndexValueType *
231  GetIndex() const
232  {
233  return m_InternalArray;
234  }
235 
240  void
241  SetIndex(const IndexValueType val[VDimension])
242  {
243  std::copy_n(val, VDimension, m_InternalArray);
244  }
245 
252  void
253  SetElement(unsigned long element, IndexValueType val)
254  {
255  m_InternalArray[element] = val;
256  }
257 
265  GetElement(unsigned long element) const
266  {
267  return m_InternalArray[element];
268  }
269 
272  void
274  {
275  std::fill_n(begin(), size(), value);
276  } // MATCH std::array assign, ITK Fill
277 
282  /*
283  * Ask the compiler to align a type to the maximum useful alignment for the target
284  * machine you are compiling for. Whenever you leave out the alignment factor in an
285  * aligned attribute specification, the compiler automatically sets the alignment
286  * for the type to the largest alignment that is ever used for any data type on
287  * the target machine you are compiling for. Doing this can often make copy
288  * operations more efficient, because the compiler can use whatever instructions
289  * copy the biggest chunks of memory when performing copies to or from the variables
290  * that have types that you have aligned this way.
291  */
292  static_assert(VDimension > 0, "Error: Only positive value sized VDimension allowed");
293  alignas(IndexValueType) IndexValueType m_InternalArray[VDimension];
297  template <typename TCoordinate>
298  inline void
300  {
301  for (unsigned int i = 0; i < VDimension; ++i)
302  {
303  m_InternalArray[i] = Math::Round<IndexValueType>(point[i]);
304  }
305  }
309  template <typename TCoordinate>
310  inline void
312  {
313  for (unsigned int i = 0; i < VDimension; ++i)
314  {
315  m_InternalArray[i] = static_cast<IndexValueType>(point[i]);
316  }
317  }
323  static Self
324  GetBasisIndex(unsigned int dim);
325 
326 
327  // ======================= Mirror the access pattern behavior of the std::array class
335  using const_reference = const value_type &;
336  using iterator = value_type *;
337  using const_iterator = const value_type *;
338  using size_type = unsigned int;
339  using difference_type = ptrdiff_t;
340  using reverse_iterator = std::reverse_iterator<iterator>;
341  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
342 
347  void
348  assign(const value_type & newValue)
349  {
350  std::fill_n(begin(), size(), newValue);
351  }
352 
353  void
354  swap(Index & other) noexcept
355  {
356  std::swap(m_InternalArray, other.m_InternalArray);
357  }
358 
359  constexpr const_iterator
360  cbegin() const
361  {
362  return &m_InternalArray[0];
363  }
364 
365  constexpr iterator
367  {
368  return &m_InternalArray[0];
369  }
370 
371  constexpr const_iterator
372  begin() const
373  {
374  return &m_InternalArray[0];
375  }
376 
377  constexpr const_iterator
378  cend() const
379  {
380  return &m_InternalArray[VDimension];
381  }
382 
383  constexpr iterator
384  end()
385  {
386  return &m_InternalArray[VDimension];
387  }
388 
389  constexpr const_iterator
390  end() const
391  {
392  return &m_InternalArray[VDimension];
393  }
394 
395  reverse_iterator
397  {
398  return reverse_iterator(end());
399  }
400 
401  const_reverse_iterator
402  rbegin() const
403  {
404  return const_reverse_iterator(end());
405  }
406 
407  reverse_iterator
409  {
410  return reverse_iterator(begin());
411  }
412 
413  const_reverse_iterator
414  rend() const
415  {
416  return const_reverse_iterator(begin());
417  }
418 
419  constexpr size_type
420  size() const
421  {
422  return VDimension;
423  }
424 
425  constexpr size_type
426  max_size() const
427  {
428  return VDimension;
429  }
430 
431  constexpr bool
432  empty() const
433  {
434  return false;
435  }
436 
437  constexpr reference
439  {
440  return m_InternalArray[pos];
441  }
442 
443  constexpr const_reference
445  {
446  return m_InternalArray[pos];
447  }
448 
449  reference
451  {
452  ExceptionThrowingBoundsCheck(pos);
453  return m_InternalArray[pos];
454  }
455 
456  const_reference
457  at(size_type pos) const
458  {
459  ExceptionThrowingBoundsCheck(pos);
460  return m_InternalArray[pos];
461  }
462 
463  constexpr reference
465  {
466  return *begin();
467  }
468 
469  constexpr const_reference
470  front() const
471  {
472  return *begin();
473  }
474 
475  constexpr reference
477  {
478  return VDimension ? *(end() - 1) : *end();
479  }
480 
481  constexpr const_reference
482  back() const
483  {
484  return VDimension ? *(end() - 1) : *end();
485  }
486 
489  {
490  return &m_InternalArray[0];
491  }
492 
493  const IndexValueType *
494  data() const
495  {
496  return &m_InternalArray[0];
497  }
498 
499 
502  static constexpr Self
503  Filled(const IndexValueType value)
504  {
505  return MakeFilled<Self>(value);
506  }
507 
508 
509 private:
510  void
512  {
513  if (pos >= VDimension)
514  {
515  throw std::out_of_range("array::ExceptionThrowingBoundsCheck");
516  }
517  }
518 
519 }; //------------ End struct Index
520 
521 template <unsigned int VDimension>
522 Index<VDimension>
524 {
525  Self ind{ { 0 } };
526 
527  ind.m_InternalArray[dim] = 1;
528  return ind;
529 }
530 
531 template <unsigned int VDimension>
532 std::ostream &
533 operator<<(std::ostream & os, const Index<VDimension> & obj)
534 {
535  os << '[';
536  for (unsigned int i = 0; i + 1 < VDimension; ++i)
537  {
538  os << obj[i] << ", ";
539  }
540  if constexpr (VDimension >= 1)
541  {
542  os << obj[VDimension - 1];
543  }
544  os << ']';
545  return os;
546 }
547 
548 // ======================= Mirror the access pattern behavior of the std::array class
549 // Array comparisons.
550 template <unsigned int VDimension>
551 inline bool
553 {
554  return std::equal(one.begin(), one.end(), two.begin());
555 }
556 
557 template <unsigned int VDimension>
558 inline bool
560 {
561  return !(one == two);
562 }
563 
564 template <unsigned int VDimension>
565 inline bool
567 {
568  return std::lexicographical_compare(one.begin(), one.end(), two.begin(), two.end());
569 }
570 
571 template <unsigned int VDimension>
572 inline bool
574 {
575  return two < one;
576 }
577 
578 template <unsigned int VDimension>
579 inline bool
581 {
582  return !(one > two);
583 }
584 
585 template <unsigned int VDimension>
586 inline bool
588 {
589  return !(one < two);
590 }
591 
592 // Specialized algorithms [6.2.2.2].
593 template <unsigned int VDimension>
594 inline void
596 {
597  std::swap(one.m_InternalArray, two.m_InternalArray);
598 }
599 
600 
602 template <typename... T>
603 auto
604 MakeIndex(const T... values)
605 {
606  const auto toValueType = [](const auto value) {
607  static_assert(std::is_integral_v<decltype(value)>, "Each value must have an integral type!");
608  return static_cast<IndexValueType>(value);
609  };
610  return Index<sizeof...(T)>{ { toValueType(values)... } };
611 }
614 } // end namespace itk
615 
616 #endif
itk::Index::operator[]
constexpr const_reference operator[](size_type pos) const
Definition: itkIndex.h:444
itk::Index< Self::Dimension >::const_reverse_iterator
std::reverse_iterator< const_iterator > const_reverse_iterator
Definition: itkIndex.h:341
itk::Index
Represent a n-dimensional index in a n-dimensional image.
Definition: itkIndex.h:68
itk::operator<
bool operator<(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:566
itk::Index::begin
constexpr const_iterator begin() const
Definition: itkIndex.h:372
itk::operator<=
bool operator<=(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:580
itk::Index::max_size
constexpr size_type max_size() const
Definition: itkIndex.h:426
itk::Size
Represent a n-dimensional size (bounds) of a n-dimensional image.
Definition: itkSize.h:69
itk::Index::back
constexpr reference back()
Definition: itkIndex.h:476
itkOffset.h
itk::Index::CopyWithCast
void CopyWithCast(const FixedArray< TCoordinate, VDimension > &point)
Definition: itkIndex.h:311
itk::Index::assign
void assign(const value_type &newValue)
Definition: itkIndex.h:348
itk::Index< Self::Dimension >::reference
value_type & reference
Definition: itkIndex.h:334
itk::Index::begin
constexpr iterator begin()
Definition: itkIndex.h:366
itk::Index::at
const_reference at(size_type pos) const
Definition: itkIndex.h:457
itk::Index::SetIndex
void SetIndex(const IndexValueType val[VDimension])
Definition: itkIndex.h:241
itk::Index::CopyWithRound
void CopyWithRound(const FixedArray< TCoordinate, VDimension > &point)
Definition: itkIndex.h:299
itk::operator<<
ITKCommon_EXPORT std::ostream & operator<<(std::ostream &out, typename AnatomicalOrientation::CoordinateEnum value)
itk::Index::operator+=
const Self & operator+=(const OffsetType &offset)
Definition: itkIndex.h:165
itk::Index< Self::Dimension >::IndexValueType
itk::IndexValueType IndexValueType
Definition: itkIndex.h:79
itk::Index::operator*
const Self operator*(const SizeType &vec) const
Definition: itkIndex.h:217
itk::Index::operator-
const Self operator-(const OffsetType &off) const
Definition: itkIndex.h:189
itk::Index::front
constexpr reference front()
Definition: itkIndex.h:464
itk::Index::SetElement
void SetElement(unsigned long element, IndexValueType val)
Definition: itkIndex.h:253
itk::Index::operator+
const Self operator+(const SizeType &sz) const
Definition: itkIndex.h:101
itk::Index::Fill
void Fill(IndexValueType value)
Definition: itkIndex.h:273
itk::Index< Self::Dimension >::OffsetValueType
itk::OffsetValueType OffsetValueType
Definition: itkIndex.h:86
itk::IndexValueType
long IndexValueType
Definition: itkIntTypes.h:93
itk::Index::operator+
const Self operator+(const OffsetType &offset) const
Definition: itkIndex.h:152
itk::Index::swap
void swap(Index &other) noexcept
Definition: itkIndex.h:354
itk::Index::front
constexpr const_reference front() const
Definition: itkIndex.h:470
itk::Index::back
constexpr const_reference back() const
Definition: itkIndex.h:482
itk::Index::GetIndex
const IndexValueType * GetIndex() const
Definition: itkIndex.h:231
itk::Index::rend
const_reverse_iterator rend() const
Definition: itkIndex.h:414
itk::point
*par Constraints *The filter requires an 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
itk::Index::at
reference at(size_type pos)
Definition: itkIndex.h:450
itk::Index::size
constexpr size_type size() const
Definition: itkIndex.h:420
itk::Index::cend
constexpr const_iterator cend() const
Definition: itkIndex.h:378
itk::Index::operator-
const OffsetType operator-(const Self &vec) const
Definition: itkIndex.h:202
itk::Index< Self::Dimension >::const_reference
const value_type & const_reference
Definition: itkIndex.h:335
itk::Index::cbegin
constexpr const_iterator cbegin() const
Definition: itkIndex.h:360
itk::Index::m_InternalArray
IndexValueType m_InternalArray[VDimension]
Definition: itkIndex.h:292
itk::operator>=
bool operator>=(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:587
itk::Offset::m_InternalArray
OffsetValueType m_InternalArray[VDimension]
Definition: itkOffset.h:242
itkMakeFilled.h
itk::Index::rbegin
const_reverse_iterator rbegin() const
Definition: itkIndex.h:402
itk::operator>
bool operator>(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:573
itk::OffsetValueType
long OffsetValueType
Definition: itkIntTypes.h:97
itk::Index::empty
constexpr bool empty() const
Definition: itkIndex.h:432
itk::Index< Self::Dimension >::difference_type
ptrdiff_t difference_type
Definition: itkIndex.h:339
itk::operator==
bool operator==(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:552
itk::FixedArray
Simulate a standard C array with copy semantics.
Definition: itkFixedArray.h:53
itk::Index::GetIndexDimension
static constexpr unsigned int GetIndexDimension()
Definition: itkIndex.h:93
itk::Index< Self::Dimension >::iterator
value_type * iterator
Definition: itkIndex.h:336
itk::Index::Filled
static constexpr Self Filled(const IndexValueType value)
Definition: itkIndex.h:503
itk::Index::GetElement
IndexValueType GetElement(unsigned long element) const
Definition: itkIndex.h:265
itk::Offset
Represent a n-dimensional offset between two n-dimensional indexes of n-dimensional image.
Definition: itkOffset.h:66
itk::swap
void swap(Index< VDimension > &one, Index< VDimension > &two) noexcept
Definition: itkIndex.h:595
itk::Index::rbegin
reverse_iterator rbegin()
Definition: itkIndex.h:396
itk::Index< Self::Dimension >::value_type
itk::IndexValueType value_type
Definition: itkIndex.h:333
itk::operator!=
bool operator!=(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:559
itk::MakeIndex
auto MakeIndex(const T... values)
Definition: itkIndex.h:604
itk::Index::rend
reverse_iterator rend()
Definition: itkIndex.h:408
itk::Size::m_InternalArray
SizeValueType m_InternalArray[VDimension]
Definition: itkSize.h:244
itk::swap
void swap(Array< T > &a, Array< T > &b) noexcept
Definition: itkArray.h:242
itk
The "itk" namespace contains all Insight Segmentation and Registration Toolkit (ITK) classes....
Definition: itkAnatomicalOrientation.h:29
itk::Index::data
const IndexValueType * data() const
Definition: itkIndex.h:494
itk::Index::end
constexpr const_iterator end() const
Definition: itkIndex.h:390
itk::Index< Self::Dimension >::size_type
unsigned int size_type
Definition: itkIndex.h:338
itk::Index::GetBasisIndex
static Self GetBasisIndex(unsigned int dim)
Definition: itkIndex.h:523
AddImageFilter
Definition: itkAddImageFilter.h:81
itk::Index::operator+=
const Self & operator+=(const SizeType &sz)
Definition: itkIndex.h:114
itk::Index::operator-
const Self operator-(const SizeType &sz) const
Definition: itkIndex.h:127
itk::Index< Self::Dimension >::const_iterator
const value_type * const_iterator
Definition: itkIndex.h:337
itk::Index< Self::Dimension >::reverse_iterator
std::reverse_iterator< iterator > reverse_iterator
Definition: itkIndex.h:340
itk::GTest::TypedefsAndConstructors::Dimension2::Dimension
constexpr unsigned int Dimension
Definition: itkGTestTypedefsAndConstructors.h:44
itk::Index::operator[]
constexpr reference operator[](size_type pos)
Definition: itkIndex.h:438
itk::Index::end
constexpr iterator end()
Definition: itkIndex.h:384
itk::Index::ExceptionThrowingBoundsCheck
void ExceptionThrowingBoundsCheck(size_type pos) const
Definition: itkIndex.h:511
itk::Index::operator-=
const Self & operator-=(const SizeType &sz)
Definition: itkIndex.h:140
itk::Index::data
IndexValueType * data()
Definition: itkIndex.h:488
itk::Index::operator-=
const Self & operator-=(const OffsetType &offset)
Definition: itkIndex.h:177