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 
27 namespace itk
28 {
29 
69 template <unsigned int VDimension = 2>
70 struct ITK_TEMPLATE_EXPORT Index final
71 {
72 public:
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 &
116  operator+=(const SizeType & sz)
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 &
142  operator-=(const SizeType & sz)
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
336  using const_reference = const value_type &;
337  using iterator = value_type *;
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
385  end()
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
496  Filled(const IndexValueType value)
497  {
498  return MakeFilled<Self>(value);
499  }
500 
501 
502 private:
503  void
505  {
506  if (pos >= VDimension)
507  {
508  throw std::out_of_range("array::ExceptionThrowingBoundsCheck");
509  }
510  }
511 
512 }; //------------ End struct Index
513 
514 template <unsigned int VDimension>
515 Index<VDimension>
517 {
518  Self ind{ { 0 } };
519 
520  ind.m_InternalArray[dim] = 1;
521  return ind;
522 }
523 
524 template <unsigned int VDimension>
525 std::ostream &
526 operator<<(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.
543 template <unsigned int VDimension>
544 inline bool
546 {
547  return std::equal(one.begin(), one.end(), two.begin());
548 }
549 
550 template <unsigned int VDimension>
551 inline bool
553 {
554  return !(one == two);
555 }
556 
557 template <unsigned int VDimension>
558 inline bool
560 {
561  return std::lexicographical_compare(one.begin(), one.end(), two.begin(), two.end());
562 }
563 
564 template <unsigned int VDimension>
565 inline bool
567 {
568  return two < one;
569 }
570 
571 template <unsigned int VDimension>
572 inline bool
574 {
575  return !(one > two);
576 }
577 
578 template <unsigned int VDimension>
579 inline bool
581 {
582  return !(one < two);
583 }
584 
585 // Specialized algorithms [6.2.2.2].
586 template <unsigned int VDimension>
587 inline void
589 {
591 }
592 
593 
595 template <typename... T>
596 auto
597 MakeIndex(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
itk::Index::operator[]
constexpr const_reference operator[](size_type pos) const
Definition: itkIndex.h:440
itk::Index< Self::Dimension >::const_reverse_iterator
std::reverse_iterator< const_iterator > const_reverse_iterator
Definition: itkIndex.h:342
itk::Index
Represent a n-dimensional index in a n-dimensional image.
Definition: itkIndex.h:70
itk::operator<
bool operator<(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:559
itk::Index::begin
constexpr const_iterator begin() const
Definition: itkIndex.h:373
itk::operator<=
bool operator<=(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:573
itk::Index::max_size
constexpr size_type max_size() const
Definition: itkIndex.h:427
itk::Size
Represent a n-dimensional size (bounds) of a n-dimensional image.
Definition: itkSize.h:71
itk::operator<<
std::ostream & operator<<(std::ostream &os, const Array< TValue > &arr)
Definition: itkArray.h:216
itkOffset.h
itk::Index::assign
void assign(const value_type &newValue)
Definition: itkIndex.h:349
itk::Index< Self::Dimension >::reference
value_type & reference
Definition: itkIndex.h:335
itk::Index::CopyWithRound
void CopyWithRound(const FixedArray< TCoordRep, VDimension > &point)
Definition: itkIndex.h:300
itk::Index::begin
constexpr iterator begin()
Definition: itkIndex.h:367
itk::swap
void swap(Array< T > &a, Array< T > &b)
Definition: itkArray.h:242
itk::Index::at
const_reference at(size_type pos) const
Definition: itkIndex.h:450
itk::Index::SetIndex
void SetIndex(const IndexValueType val[VDimension])
Definition: itkIndex.h:242
itk::Index::operator+=
const Self & operator+=(const OffsetType &offset)
Definition: itkIndex.h:167
itk::Index< Self::Dimension >::IndexValueType
itk::IndexValueType IndexValueType
Definition: itkIndex.h:81
itk::Index::operator*
const Self operator*(const SizeType &vec) const
Definition: itkIndex.h:218
itk::swap
void swap(Index< VDimension > &one, Index< VDimension > &two)
Definition: itkIndex.h:588
itk::Index::operator-
const Self operator-(const OffsetType &off) const
Definition: itkIndex.h:191
itk::Index::SetElement
void SetElement(unsigned long element, IndexValueType val)
Definition: itkIndex.h:254
itk::Index::operator+
const Self operator+(const SizeType &sz) const
Definition: itkIndex.h:103
itk::Index::Fill
void Fill(IndexValueType value)
Definition: itkIndex.h:274
itk::Index::front
const_reference front() const
Definition: itkIndex.h:463
itk::Index< Self::Dimension >::OffsetValueType
itk::OffsetValueType OffsetValueType
Definition: itkIndex.h:88
itk::IndexValueType
long IndexValueType
Definition: itkIntTypes.h:90
itk::Index::back
const_reference back() const
Definition: itkIndex.h:475
itk::Index::operator+
const Self operator+(const OffsetType &offset) const
Definition: itkIndex.h:154
itk::Index::front
reference front()
Definition: itkIndex.h:457
itk::Index::GetIndex
const IndexValueType * GetIndex() const
Definition: itkIndex.h:232
itk::Index::rend
const_reverse_iterator rend() const
Definition: itkIndex.h:415
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:443
itk::Index::size
constexpr size_type size() const
Definition: itkIndex.h:421
itk::Index::cend
constexpr const_iterator cend() const
Definition: itkIndex.h:379
itk::Index::operator-
const OffsetType operator-(const Self &vec) const
Definition: itkIndex.h:204
itk::Index< Self::Dimension >::const_reference
const value_type & const_reference
Definition: itkIndex.h:336
itk::Index::cbegin
constexpr const_iterator cbegin() const
Definition: itkIndex.h:361
itk::Index::back
reference back()
Definition: itkIndex.h:469
itk::Index::m_InternalArray
IndexValueType m_InternalArray[VDimension]
Definition: itkIndex.h:293
itk::operator>=
bool operator>=(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:580
itk::Offset::m_InternalArray
OffsetValueType m_InternalArray[VDimension]
Definition: itkOffset.h:245
itkMakeFilled.h
itk::Index::rbegin
const_reverse_iterator rbegin() const
Definition: itkIndex.h:403
itk::operator>
bool operator>(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:566
itk::OffsetValueType
long OffsetValueType
Definition: itkIntTypes.h:94
itk::Index::empty
constexpr bool empty() const
Definition: itkIndex.h:433
itk::Index< Self::Dimension >::difference_type
ptrdiff_t difference_type
Definition: itkIndex.h:340
itk::operator==
bool operator==(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:545
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:312
itk::Index::GetIndexDimension
static constexpr unsigned int GetIndexDimension()
Definition: itkIndex.h:95
itk::Index< Self::Dimension >::iterator
value_type * iterator
Definition: itkIndex.h:337
itk::Index::Filled
static constexpr Self Filled(const IndexValueType value)
Definition: itkIndex.h:496
itk::Index::GetElement
IndexValueType GetElement(unsigned long element) const
Definition: itkIndex.h:266
itk::Offset
Represent a n-dimensional offset between two n-dimensional indexes of n-dimensional image.
Definition: itkOffset.h:69
itk::Index::rbegin
reverse_iterator rbegin()
Definition: itkIndex.h:397
itk::Index< Self::Dimension >::value_type
itk::IndexValueType value_type
Definition: itkIndex.h:334
itk::operator!=
bool operator!=(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:552
itk::MakeIndex
auto MakeIndex(const T... values)
Definition: itkIndex.h:597
itk::Index::rend
reverse_iterator rend()
Definition: itkIndex.h:409
itk::Size::m_InternalArray
SizeValueType m_InternalArray[VDimension]
Definition: itkSize.h:245
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:487
itk::Index::end
constexpr const_iterator end() const
Definition: itkIndex.h:391
itk::Index< Self::Dimension >::size_type
unsigned int size_type
Definition: itkIndex.h:339
itk::Index::GetBasisIndex
static Self GetBasisIndex(unsigned int dim)
Definition: itkIndex.h:516
AddImageFilter
Definition: itkAddImageFilter.h:81
itk::Index::operator+=
const Self & operator+=(const SizeType &sz)
Definition: itkIndex.h:116
itk::Index::operator-
const Self operator-(const SizeType &sz) const
Definition: itkIndex.h:129
itk::Index< Self::Dimension >::const_iterator
const value_type * const_iterator
Definition: itkIndex.h:338
itk::Index< Self::Dimension >::reverse_iterator
std::reverse_iterator< iterator > reverse_iterator
Definition: itkIndex.h:341
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:385
itk::Index::ExceptionThrowingBoundsCheck
void ExceptionThrowingBoundsCheck(size_type pos) const
Definition: itkIndex.h:504
itk::Index::swap
void swap(Index &other)
Definition: itkIndex.h:355
itk::Index::operator-=
const Self & operator-=(const SizeType &sz)
Definition: itkIndex.h:142
itk::Index::data
IndexValueType * data()
Definition: itkIndex.h:481
itk::Index::operator-=
const Self & operator-=(const OffsetType &offset)
Definition: itkIndex.h:179