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 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
334  using const_reference = const value_type &;
335  using iterator = value_type *;
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
383  end()
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
494  Filled(const IndexValueType value)
495  {
496  return MakeFilled<Self>(value);
497  }
498 
499 
500 private:
501  void
503  {
504  if (pos >= VDimension)
505  {
506  throw std::out_of_range("array::ExceptionThrowingBoundsCheck");
507  }
508  }
509 
510 }; //------------ End struct Index
511 
512 template <unsigned int VDimension>
513 Index<VDimension>
515 {
516  Self ind{ { 0 } };
517 
518  ind.m_InternalArray[dim] = 1;
519  return ind;
520 }
521 
522 template <unsigned int VDimension>
523 std::ostream &
524 operator<<(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.
541 template <unsigned int VDimension>
542 inline bool
544 {
545  return std::equal(one.begin(), one.end(), two.begin());
546 }
547 
548 template <unsigned int VDimension>
549 inline bool
551 {
552  return !(one == two);
553 }
554 
555 template <unsigned int VDimension>
556 inline bool
558 {
559  return std::lexicographical_compare(one.begin(), one.end(), two.begin(), two.end());
560 }
561 
562 template <unsigned int VDimension>
563 inline bool
565 {
566  return two < one;
567 }
568 
569 template <unsigned int VDimension>
570 inline bool
572 {
573  return !(one > two);
574 }
575 
576 template <unsigned int VDimension>
577 inline bool
579 {
580  return !(one < two);
581 }
582 
583 // Specialized algorithms [6.2.2.2].
584 template <unsigned int VDimension>
585 inline void
587 {
589 }
590 
591 
593 template <typename... T>
594 auto
595 MakeIndex(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
itk::Index::operator[]
constexpr const_reference operator[](size_type pos) const
Definition: itkIndex.h:438
itk::Index< Self::Dimension >::const_reverse_iterator
std::reverse_iterator< const_iterator > const_reverse_iterator
Definition: itkIndex.h:340
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:557
itk::Index::begin
constexpr const_iterator begin() const
Definition: itkIndex.h:371
itk::operator<=
bool operator<=(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:571
itk::Index::max_size
constexpr size_type max_size() const
Definition: itkIndex.h:425
itk::Size
Represent a n-dimensional size (bounds) of a n-dimensional image.
Definition: itkSize.h:69
itk::operator<<
std::ostream & operator<<(std::ostream &os, const Array< TValue > &arr)
Definition: itkArray.h:216
itk::Index::back
constexpr reference back()
Definition: itkIndex.h:467
itkOffset.h
itk::Index::assign
void assign(const value_type &newValue)
Definition: itkIndex.h:347
itk::Index< Self::Dimension >::reference
value_type & reference
Definition: itkIndex.h:333
itk::Index::CopyWithRound
void CopyWithRound(const FixedArray< TCoordRep, VDimension > &point)
Definition: itkIndex.h:298
itk::Index::begin
constexpr iterator begin()
Definition: itkIndex.h:365
itk::Index::at
const_reference at(size_type pos) const
Definition: itkIndex.h:448
itk::Index::SetIndex
void SetIndex(const IndexValueType val[VDimension])
Definition: itkIndex.h:240
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:216
itk::swap
void swap(Index< VDimension > &one, Index< VDimension > &two)
Definition: itkIndex.h:586
itk::Index::operator-
const Self operator-(const OffsetType &off) const
Definition: itkIndex.h:189
itk::Index::front
constexpr reference front()
Definition: itkIndex.h:455
itk::Index::SetElement
void SetElement(unsigned long element, IndexValueType val)
Definition: itkIndex.h:252
itk::Index::operator+
const Self operator+(const SizeType &sz) const
Definition: itkIndex.h:101
itk::Index::Fill
void Fill(IndexValueType value)
Definition: itkIndex.h:272
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::front
constexpr const_reference front() const
Definition: itkIndex.h:461
itk::Index::back
constexpr const_reference back() const
Definition: itkIndex.h:473
itk::Index::GetIndex
const IndexValueType * GetIndex() const
Definition: itkIndex.h:230
itk::Index::rend
const_reverse_iterator rend() const
Definition: itkIndex.h:413
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:441
itk::Index::size
constexpr size_type size() const
Definition: itkIndex.h:419
itk::Index::cend
constexpr const_iterator cend() const
Definition: itkIndex.h:377
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:334
itk::Index::cbegin
constexpr const_iterator cbegin() const
Definition: itkIndex.h:359
itk::Index::m_InternalArray
IndexValueType m_InternalArray[VDimension]
Definition: itkIndex.h:291
itk::operator>=
bool operator>=(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:578
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:401
itk::operator>
bool operator>(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:564
itk::OffsetValueType
long OffsetValueType
Definition: itkIntTypes.h:97
itk::Index::empty
constexpr bool empty() const
Definition: itkIndex.h:431
itk::Index< Self::Dimension >::difference_type
ptrdiff_t difference_type
Definition: itkIndex.h:338
itk::operator==
bool operator==(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:543
itk::FixedArray
Simulate a standard C array with copy semantics.
Definition: itkFixedArray.h:53
itk::Index::CopyWithCast
void CopyWithCast(const FixedArray< TCoordRep, VDimension > &point)
Definition: itkIndex.h:310
itk::Index::GetIndexDimension
static constexpr unsigned int GetIndexDimension()
Definition: itkIndex.h:93
itk::Index< Self::Dimension >::iterator
value_type * iterator
Definition: itkIndex.h:335
itk::Index::Filled
static constexpr Self Filled(const IndexValueType value)
Definition: itkIndex.h:494
itk::Index::GetElement
IndexValueType GetElement(unsigned long element) const
Definition: itkIndex.h:264
itk::Offset
Represent a n-dimensional offset between two n-dimensional indexes of n-dimensional image.
Definition: itkOffset.h:66
itk::Index::rbegin
reverse_iterator rbegin()
Definition: itkIndex.h:395
itk::Index< Self::Dimension >::value_type
itk::IndexValueType value_type
Definition: itkIndex.h:332
itk::operator!=
bool operator!=(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:550
itk::MakeIndex
auto MakeIndex(const T... values)
Definition: itkIndex.h:595
itk::Index::rend
reverse_iterator rend()
Definition: itkIndex.h:407
itk::Size::m_InternalArray
SizeValueType m_InternalArray[VDimension]
Definition: itkSize.h:243
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: itkAnnulusOperator.h:24
itk::Index::data
const IndexValueType * data() const
Definition: itkIndex.h:485
itk::Index::end
constexpr const_iterator end() const
Definition: itkIndex.h:389
itk::Index< Self::Dimension >::size_type
unsigned int size_type
Definition: itkIndex.h:337
itk::Index::GetBasisIndex
static Self GetBasisIndex(unsigned int dim)
Definition: itkIndex.h:514
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:336
itk::Index< Self::Dimension >::reverse_iterator
std::reverse_iterator< iterator > reverse_iterator
Definition: itkIndex.h:339
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:436
itk::Index::end
constexpr iterator end()
Definition: itkIndex.h:383
itk::Index::ExceptionThrowingBoundsCheck
void ExceptionThrowingBoundsCheck(size_type pos) const
Definition: itkIndex.h:502
itk::Index::swap
void swap(Index &other)
Definition: itkIndex.h:353
itk::Index::operator-=
const Self & operator-=(const SizeType &sz)
Definition: itkIndex.h:140
itk::Index::data
IndexValueType * data()
Definition: itkIndex.h:479
itk::Index::operator-=
const Self & operator-=(const OffsetType &offset)
Definition: itkIndex.h:177