ITK  5.2.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  * http://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 "itkOffset.h"
22 
23 namespace itk
24 {
25 
64 
65 template <unsigned int VDimension = 2>
66 struct ITK_TEMPLATE_EXPORT Index final
67 {
68 public:
69  // Using the `rule of zero` to this aggregate type
70  // C++20 changes the definition of aggregate such that classes with any user-declared ctors are no longer aggregates.
71 
73  using Self = Index;
74 
78 
81 
85 
87  static constexpr unsigned int Dimension = VDimension;
88 
90  static constexpr unsigned int
92  {
93  return VDimension;
94  }
95 
96 
98  const Self
99  operator+(const SizeType & sz) const
100  {
101  Self result;
102 
103  for (unsigned int i = 0; i < VDimension; i++)
104  {
105  result[i] = m_InternalArray[i] + static_cast<IndexValueType>(sz[i]);
106  }
107  return result;
108  }
109 
111  const Self &
112  operator+=(const SizeType & sz)
113  {
114  for (unsigned int i = 0; i < VDimension; i++)
115  {
116  m_InternalArray[i] += static_cast<IndexValueType>(sz[i]);
117  }
118  return *this;
119  }
121 
124  const Self
125  operator-(const SizeType & sz) const
126  {
127  Self result;
128 
129  for (unsigned int i = 0; i < VDimension; i++)
130  {
131  result[i] = m_InternalArray[i] - static_cast<IndexValueType>(sz[i]);
132  }
133  return result;
134  }
135 
137  const Self &
138  operator-=(const SizeType & sz)
139  {
140  for (unsigned int i = 0; i < VDimension; i++)
141  {
142  m_InternalArray[i] -= static_cast<IndexValueType>(sz[i]);
143  }
144  return *this;
145  }
147 
149  const Self
150  operator+(const OffsetType & offset) const
151  {
152  Self result;
153 
154  for (unsigned int i = 0; i < VDimension; i++)
155  {
156  result[i] = m_InternalArray[i] + offset[i];
157  }
158  return result;
159  }
160 
162  const Self &
163  operator+=(const OffsetType & offset)
164  {
165  for (unsigned int i = 0; i < VDimension; i++)
166  {
167  m_InternalArray[i] += offset[i];
168  }
169  return *this;
170  }
172 
174  const Self &
175  operator-=(const OffsetType & offset)
176  {
177  for (unsigned int i = 0; i < VDimension; i++)
178  {
179  m_InternalArray[i] -= offset[i];
180  }
181  return *this;
182  }
184 
186  const Self
187  operator-(const OffsetType & off) const
188  {
189  Self result;
190 
191  for (unsigned int i = 0; i < VDimension; i++)
192  {
193  result[i] = m_InternalArray[i] - off.m_InternalArray[i];
194  }
195  return result;
196  }
197 
199  const OffsetType
200  operator-(const Self & vec) const
201  {
202  OffsetType result;
203 
204  for (unsigned int i = 0; i < VDimension; i++)
205  {
206  result[i] = m_InternalArray[i] - vec.m_InternalArray[i];
207  }
208  return result;
209  }
210 
214  const Self operator*(const SizeType & vec) const
215  {
216  Self result;
217 
218  for (unsigned int i = 0; i < VDimension; i++)
219  {
220  result[i] = m_InternalArray[i] * static_cast<IndexValueType>(vec.m_InternalArray[i]);
221  }
222  return result;
223  }
224 
227  const IndexValueType *
228  GetIndex() const
229  {
230  return m_InternalArray;
231  }
232 
237  void
238  SetIndex(const IndexValueType val[VDimension])
239  {
240  std::copy_n(val, VDimension, m_InternalArray);
241  }
242 
249  void
250  SetElement(unsigned long element, IndexValueType val)
251  {
252  m_InternalArray[element] = val;
253  }
254 
262  GetElement(unsigned long element) const
263  {
264  return m_InternalArray[element];
265  }
266 
269  void
271  {
272  std::fill_n(begin(), size(), value);
273  } // MATCH std::array assign, ITK Fill
274 
279  /*
280  * Ask the compiler to align a type to the maximum useful alignment for the target
281  * machine you are compiling for. Whenever you leave out the alignment factor in an
282  * aligned attribute specification, the compiler automatically sets the alignment
283  * for the type to the largest alignment that is ever used for any data type on
284  * the target machine you are compiling for. Doing this can often make copy
285  * operations more efficient, because the compiler can use whatever instructions
286  * copy the biggest chunks of memory when performing copies to or from the variables
287  * that have types that you have aligned this way.
288  */
289  static_assert(VDimension > 0, "Error: Only positive value sized VDimension allowed");
290  alignas(IndexValueType) IndexValueType m_InternalArray[VDimension];
292 
294  template <typename TCoordRep>
295  inline void
297  {
298  for (unsigned int i = 0; i < VDimension; ++i)
299  {
300  m_InternalArray[i] = Math::Round<IndexValueType>(point[i]);
301  }
302  }
304 
306  template <typename TCoordRep>
307  inline void
309  {
310  for (unsigned int i = 0; i < VDimension; ++i)
311  {
312  m_InternalArray[i] = static_cast<IndexValueType>(point[i]);
313  }
314  }
316 
320  static Self
321  GetBasisIndex(unsigned int dim);
322 
323 
324  // ======================= Mirror the access pattern behavior of the std::array class
332  using const_reference = const value_type &;
333  using iterator = value_type *;
334  using const_iterator = const value_type *;
335  using size_type = unsigned int;
336  using difference_type = std::ptrdiff_t;
337  using reverse_iterator = std::reverse_iterator<iterator>;
338  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
339 
344  void
345  assign(const value_type & newValue)
346  {
347  std::fill_n(begin(), size(), newValue);
348  }
349 
350  void
351  swap(Index & other)
352  {
353  std::swap(m_InternalArray, other.m_InternalArray);
354  }
355 
356  iterator
358  {
359  return iterator(&m_InternalArray[0]);
360  }
361 
362  const_iterator
363  begin() const
364  {
365  return const_iterator(&m_InternalArray[0]);
366  }
367 
368  iterator
369  end()
370  {
371  return iterator(&m_InternalArray[VDimension]);
372  }
373 
374  const_iterator
375  end() const
376  {
377  return const_iterator(&m_InternalArray[VDimension]);
378  }
379 
380  reverse_iterator
382  {
383  return reverse_iterator(end());
384  }
385 
386  const_reverse_iterator
387  rbegin() const
388  {
389  return const_reverse_iterator(end());
390  }
391 
392  reverse_iterator
394  {
395  return reverse_iterator(begin());
396  }
397 
398  const_reverse_iterator
399  rend() const
400  {
401  return const_reverse_iterator(begin());
402  }
403 
404  constexpr size_type
405  size() const
406  {
407  return VDimension;
408  }
409 
410  constexpr size_type
411  max_size() const
412  {
413  return VDimension;
414  }
415 
416  constexpr bool
417  empty() const
418  {
419  return false;
420  }
421 
422  reference operator[](size_type pos) { return m_InternalArray[pos]; }
423 
424  const_reference operator[](size_type pos) const { return m_InternalArray[pos]; }
425 
426  reference
428  {
429  ExceptionThrowingBoundsCheck(pos);
430  return m_InternalArray[pos];
431  }
432 
433  const_reference
434  at(size_type pos) const
435  {
436  ExceptionThrowingBoundsCheck(pos);
437  return m_InternalArray[pos];
438  }
439 
440  reference
442  {
443  return *begin();
444  }
445 
446  const_reference
447  front() const
448  {
449  return *begin();
450  }
451 
452  reference
454  {
455  return VDimension ? *(end() - 1) : *end();
456  }
457 
458  const_reference
459  back() const
460  {
461  return VDimension ? *(end() - 1) : *end();
462  }
463 
466  {
467  return &m_InternalArray[0];
468  }
469 
470  const IndexValueType *
471  data() const
472  {
473  return &m_InternalArray[0];
474  }
475 
476 
479  static Self
480  Filled(const IndexValueType value)
481  {
482  Self result;
483  result.Fill(value);
484  return result;
485  }
487 
488 
489 private:
490  void
492  {
493  if (pos >= VDimension)
494  {
495  throw std::out_of_range("array::ExceptionThrowingBoundsCheck");
496  }
497  }
498 
499 }; //------------ End struct Index
500 
501 template <unsigned int VDimension>
502 Index<VDimension>
504 {
505  Self ind{ { 0 } };
506 
507  ind.m_InternalArray[dim] = 1;
508  return ind;
509 }
510 
511 template <unsigned int VDimension>
512 std::ostream &
513 operator<<(std::ostream & os, const Index<VDimension> & obj)
514 {
515  os << "[";
516  for (unsigned int i = 0; i + 1 < VDimension; ++i)
517  {
518  os << obj[i] << ", ";
519  }
520  if (VDimension >= 1)
521  {
522  os << obj[VDimension - 1];
523  }
524  os << "]";
525  return os;
526 }
527 
528 // ======================= Mirror the access pattern behavior of the std::array class
529 // Array comparisons.
530 template <unsigned int VDimension>
531 inline bool
533 {
534  return std::equal(one.begin(), one.end(), two.begin());
535 }
536 
537 template <unsigned int VDimension>
538 inline bool
540 {
541  return !(one == two);
542 }
543 
544 template <unsigned int VDimension>
545 inline bool
547 {
548  return std::lexicographical_compare(one.begin(), one.end(), two.begin(), two.end());
549 }
550 
551 template <unsigned int VDimension>
552 inline bool
554 {
555  return two < one;
556 }
557 
558 template <unsigned int VDimension>
559 inline bool
561 {
562  return !(one > two);
563 }
564 
565 template <unsigned int VDimension>
566 inline bool
568 {
569  return !(one < two);
570 }
571 
572 // Specialized algorithms [6.2.2.2].
573 template <unsigned int VDimension>
574 inline void
576 {
578 }
579 
580 // static constexpr definition explicitly needed in C++11
581 template <unsigned int VDimension>
582 constexpr unsigned int Index<VDimension>::Dimension;
583 } // end namespace itk
584 
585 #endif
itk::Index< Self::ImageDimension >::const_reverse_iterator
std::reverse_iterator< const_iterator > const_reverse_iterator
Definition: itkIndex.h:338
itk::Index
Represent a n-dimensional index in a n-dimensional image.
Definition: itkIndex.h:66
itk::operator<
bool operator<(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:546
itk::operator<=
bool operator<=(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:560
itk::Index::max_size
constexpr size_type max_size() const
Definition: itkIndex.h:411
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:213
itkOffset.h
itk::Index::assign
void assign(const value_type &newValue)
Definition: itkIndex.h:345
itk::Index< Self::ImageDimension >::reference
value_type & reference
Definition: itkIndex.h:331
itk::Index::CopyWithRound
void CopyWithRound(const FixedArray< TCoordRep, VDimension > &point)
Definition: itkIndex.h:296
itk::Index::operator[]
const_reference operator[](size_type pos) const
Definition: itkIndex.h:424
itk::swap
void swap(Array< T > &a, Array< T > &b)
Definition: itkArray.h:239
itk::Index< Self::ImageDimension >::IndexValueType
::itk::IndexValueType IndexValueType
Definition: itkIndex.h:77
itk::Index::at
const_reference at(size_type pos) const
Definition: itkIndex.h:434
itk::Index::SetIndex
void SetIndex(const IndexValueType val[VDimension])
Definition: itkIndex.h:238
itk::Index::operator+=
const Self & operator+=(const OffsetType &offset)
Definition: itkIndex.h:163
itk::Index::operator*
const Self operator*(const SizeType &vec) const
Definition: itkIndex.h:214
itk::Index::Dimension
static constexpr unsigned int Dimension
Definition: itkIndex.h:87
itk::swap
void swap(Index< VDimension > &one, Index< VDimension > &two)
Definition: itkIndex.h:575
itk::Index::operator-
const Self operator-(const OffsetType &off) const
Definition: itkIndex.h:187
itk::Index::SetElement
void SetElement(unsigned long element, IndexValueType val)
Definition: itkIndex.h:250
itk::Index::operator+
const Self operator+(const SizeType &sz) const
Definition: itkIndex.h:99
itk::Index::Fill
void Fill(IndexValueType value)
Definition: itkIndex.h:270
itk::Index::front
const_reference front() const
Definition: itkIndex.h:447
itk::Index::end
iterator end()
Definition: itkIndex.h:369
itk::Index::back
const_reference back() const
Definition: itkIndex.h:459
itk::Index::operator+
const Self operator+(const OffsetType &offset) const
Definition: itkIndex.h:150
itk::Index::begin
iterator begin()
Definition: itkIndex.h:357
itk::Index< Self::ImageDimension >::difference_type
std::ptrdiff_t difference_type
Definition: itkIndex.h:336
itk::Index::front
reference front()
Definition: itkIndex.h:441
itk::Index::begin
const_iterator begin() const
Definition: itkIndex.h:363
itk::Index::operator[]
reference operator[](size_type pos)
Definition: itkIndex.h:422
itk::Index::GetIndex
const IndexValueType * GetIndex() const
Definition: itkIndex.h:228
itk::Index::rend
const_reverse_iterator rend() const
Definition: itkIndex.h:399
itk::Index< Self::ImageDimension >::OffsetValueType
::itk::OffsetValueType OffsetValueType
Definition: itkIndex.h:84
itk::Index::at
reference at(size_type pos)
Definition: itkIndex.h:427
itk::Index::size
constexpr size_type size() const
Definition: itkIndex.h:405
itk::Index::operator-
const OffsetType operator-(const Self &vec) const
Definition: itkIndex.h:200
itk::Index< Self::ImageDimension >::const_reference
const value_type & const_reference
Definition: itkIndex.h:332
itk::Index::back
reference back()
Definition: itkIndex.h:453
itk::Index::m_InternalArray
IndexValueType m_InternalArray[VDimension]
Definition: itkIndex.h:289
itk::operator>=
bool operator>=(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:567
itk::Offset::m_InternalArray
OffsetValueType m_InternalArray[VDimension]
Definition: itkOffset.h:243
itk::Index::rbegin
const_reverse_iterator rbegin() const
Definition: itkIndex.h:387
itk::operator>
bool operator>(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:553
itk::Index::empty
constexpr bool empty() const
Definition: itkIndex.h:417
itk::operator==
bool operator==(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:532
itk::FixedArray
Simulate a standard C array with copy semantics.
Definition: itkFixedArray.h:52
itk::Index::CopyWithCast
void CopyWithCast(const FixedArray< TCoordRep, VDimension > &point)
Definition: itkIndex.h:308
itk::Index::GetIndexDimension
static constexpr unsigned int GetIndexDimension()
Definition: itkIndex.h:91
itk::Index< Self::ImageDimension >::iterator
value_type * iterator
Definition: itkIndex.h:333
itk::Index::GetElement
IndexValueType GetElement(unsigned long element) const
Definition: itkIndex.h:262
itk::Offset
Represent a n-dimensional offset between two n-dimensional indexes of n-dimensional image.
Definition: itkOffset.h:67
itk::Index::rbegin
reverse_iterator rbegin()
Definition: itkIndex.h:381
itk::Index::end
const_iterator end() const
Definition: itkIndex.h:375
itk::operator!=
bool operator!=(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:539
itk::Index::rend
reverse_iterator rend()
Definition: itkIndex.h:393
itk::Size::m_InternalArray
SizeValueType m_InternalArray[VDimension]
Definition: itkSize.h:230
itk::Index::Filled
static Self Filled(const IndexValueType value)
Definition: itkIndex.h:480
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:471
itk::OffsetValueType
signed long OffsetValueType
Definition: itkIntTypes.h:94
itk::Index< Self::ImageDimension >::size_type
unsigned int size_type
Definition: itkIndex.h:335
itk::IndexValueType
signed long IndexValueType
Definition: itkIntTypes.h:90
itk::Index::GetBasisIndex
static Self GetBasisIndex(unsigned int dim)
Definition: itkIndex.h:503
itk::Index< Self::ImageDimension >::value_type
::itk::IndexValueType value_type
Definition: itkIndex.h:330
itk::Index::operator+=
const Self & operator+=(const SizeType &sz)
Definition: itkIndex.h:112
itk::Index::operator-
const Self operator-(const SizeType &sz) const
Definition: itkIndex.h:125
itk::Index< Self::ImageDimension >::const_iterator
const value_type * const_iterator
Definition: itkIndex.h:334
itk::Index< Self::ImageDimension >::reverse_iterator
std::reverse_iterator< iterator > reverse_iterator
Definition: itkIndex.h:337
itk::GTest::TypedefsAndConstructors::Dimension2::Dimension
constexpr unsigned int Dimension
Definition: itkGTestTypedefsAndConstructors.h:44
itk::Index::ExceptionThrowingBoundsCheck
void ExceptionThrowingBoundsCheck(size_type pos) const
Definition: itkIndex.h:491
itk::Index::swap
void swap(Index &other)
Definition: itkIndex.h:351
itk::Index::operator-=
const Self & operator-=(const SizeType &sz)
Definition: itkIndex.h:138
itk::Index::data
IndexValueType * data()
Definition: itkIndex.h:465
itk::Index::operator-=
const Self & operator-=(const OffsetType &offset)
Definition: itkIndex.h:175