ITK  5.0.0
Insight Segmentation and Registration Toolkit
itkIndex.h
Go to the documentation of this file.
1 /*=========================================================================
2  *
3  * Copyright Insight Software Consortium
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 GetIndexDimension()
91  {
92  return VDimension;
93  }
94 
95 
97  const Self operator+(const SizeType & sz) const
98  {
99  Self result;
100 
101  for( unsigned int i = 0; i < VDimension; i++ )
102  {
103  result[i] = m_InternalArray[i] + static_cast<IndexValueType>( sz[i] );
104  }
105  return result;
106  }
107 
109  const Self & operator+=(const SizeType & sz)
110  {
111  for( unsigned int i = 0; i < VDimension; i++ )
112  {
113  m_InternalArray[i] += static_cast<IndexValueType>( sz[i] );
114  }
115  return *this;
116  }
118 
121  const Self operator-(const SizeType & sz) const
122  {
123  Self result;
124 
125  for( unsigned int i = 0; i < VDimension; i++ )
126  {
127  result[i] = m_InternalArray[i] - static_cast<IndexValueType>( sz[i] );
128  }
129  return result;
130  }
131 
133  const Self & operator-=(const SizeType & sz)
134  {
135  for( unsigned int i = 0; i < VDimension; i++ )
136  {
137  m_InternalArray[i] -= static_cast<IndexValueType>( sz[i] );
138  }
139  return *this;
140  }
142 
144  const Self operator+(const OffsetType & offset) const
145  {
146  Self result;
147 
148  for( unsigned int i = 0; i < VDimension; i++ )
149  {
150  result[i] = m_InternalArray[i] + offset[i];
151  }
152  return result;
153  }
154 
156  const Self & operator+=(const OffsetType & offset)
157  {
158  for( unsigned int i = 0; i < VDimension; i++ )
159  {
160  m_InternalArray[i] += offset[i];
161  }
162  return *this;
163  }
165 
167  const Self & 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  }
176 
178  const Self operator-(const OffsetType & off) const
179  {
180  Self result;
181 
182  for( unsigned int i = 0; i < VDimension; i++ )
183  {
184  result[i] = m_InternalArray[i] - off.m_InternalArray[i];
185  }
186  return result;
187  }
188 
190  const OffsetType operator-(const Self & vec) const
191  {
192  OffsetType result;
193 
194  for( unsigned int i = 0; i < VDimension; i++ )
195  {
196  result[i] = m_InternalArray[i] - vec.m_InternalArray[i];
197  }
198  return result;
199  }
200 
204  const Self operator*(const SizeType & vec) const
205  {
206  Self result;
207 
208  for( unsigned int i = 0; i < VDimension; i++ )
209  {
210  result[i] = m_InternalArray[i] * static_cast<IndexValueType>( vec.m_InternalArray[i] );
211  }
212  return result;
213  }
214 
217  const IndexValueType * GetIndex() const
218  {
219  return m_InternalArray;
220  }
221 
226  void SetIndex(const IndexValueType val[VDimension])
227  {
228  std::copy(val,
229  val + VDimension,
230  m_InternalArray);
231  }
232 
239  void SetElement(unsigned long element, IndexValueType val)
240  {
241  m_InternalArray[element] = val;
242  }
243 
250  IndexValueType GetElement(unsigned long element) const
251  {
252  return m_InternalArray[element];
253  }
254 
257  void Fill(IndexValueType value)
258  {
259  std::fill_n(begin(), size(), value);
260  } // MATCH std::array assign, ITK Fill
261 
266  /*
267  * Ask the compiler to align a type to the maximum useful alignment for the target
268  * machine you are compiling for. Whenever you leave out the alignment factor in an
269  * aligned attribute specification, the compiler automatically sets the alignment
270  * for the type to the largest alignment that is ever used for any data type on
271  * the target machine you are compiling for. Doing this can often make copy
272  * operations more efficient, because the compiler can use whatever instructions
273  * copy the biggest chunks of memory when performing copies to or from the variables
274  * that have types that you have aligned this way.
275  */
276  static_assert( VDimension > 0, "Error: Only positive value sized VDimension allowed" );
277  alignas(IndexValueType) IndexValueType m_InternalArray[VDimension];
279 
281  template <typename TCoordRep>
283  {
284  for( unsigned int i = 0; i < VDimension; ++i )
285  {
286  m_InternalArray[i] = Math::Round<IndexValueType>(point[i]);
287  }
288  }
290 
292  template <typename TCoordRep>
294  {
295  for( unsigned int i = 0; i < VDimension; ++i )
296  {
297  m_InternalArray[i] = static_cast<IndexValueType>( point[i] );
298  }
299  }
301 
305  static Self GetBasisIndex(unsigned int dim);
306 
307 
308  // ======================= Mirror the access pattern behavior of the std::array class
316  using const_reference = const value_type &;
317  using iterator = value_type *;
318  using const_iterator = const value_type *;
319  using size_type = unsigned int;
320  using difference_type = std::ptrdiff_t;
321  using reverse_iterator = std::reverse_iterator<iterator>;
322  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
323 
328  void assign(const value_type & newValue)
329  {
330  std::fill_n(begin(), size(), newValue);
331  }
332 
333  void swap(Index & other)
334  {
335  std::swap_ranges(begin(), end(), other.begin() );
336  }
337 
339  {
340  return iterator(&m_InternalArray[0]);
341  }
342 
344  {
345  return const_iterator(&m_InternalArray[0]);
346  }
347 
349  {
350  return iterator(&m_InternalArray[VDimension]);
351  }
352 
354  {
355  return const_iterator(&m_InternalArray[VDimension]);
356  }
357 
359  {
360  return reverse_iterator(end() );
361  }
362 
364  {
365  return const_reverse_iterator(end() );
366  }
367 
369  {
370  return reverse_iterator(begin() );
371  }
372 
374  {
375  return const_reverse_iterator(begin() );
376  }
377 
378  constexpr size_type size() const
379  {
380  return VDimension;
381  }
382 
383  constexpr size_type max_size() const
384  {
385  return VDimension;
386  }
387 
388  constexpr bool empty() const
389  {
390  return false;
391  }
392 
394  {
395  return m_InternalArray[pos];
396  }
397 
399  {
400  return m_InternalArray[pos];
401  }
402 
404  {
405  ExceptionThrowingBoundsCheck(pos); return m_InternalArray[pos];
406  }
407 
409  {
410  ExceptionThrowingBoundsCheck(pos); return m_InternalArray[pos];
411  }
412 
414  {
415  return *begin();
416  }
417 
419  {
420  return *begin();
421  }
422 
424  {
425  return VDimension ? *(end() - 1) : *end();
426  }
427 
429  {
430  return VDimension ? *(end() - 1) : *end();
431  }
432 
434  {
435  return &m_InternalArray[0];
436  }
437 
438  const IndexValueType * data() const
439  {
440  return &m_InternalArray[0];
441  }
442 
443 private:
445  {
446  if( pos >= VDimension )
447  {
448  throw std::out_of_range("array::ExceptionThrowingBoundsCheck");
449  }
450  }
451 
452 }; //------------ End struct Index
453 
454 template <unsigned int VDimension>
455 Index<VDimension>
457 ::GetBasisIndex(unsigned int dim)
458 {
459  Self ind{{0}};
460 
461  ind.m_InternalArray[dim] = 1;
462  return ind;
463 }
464 
465 template <unsigned int VDimension>
466 std::ostream & operator<<(std::ostream & os, const Index<VDimension> & obj)
467 {
468  os << "[";
469  for( unsigned int i = 0; i + 1 < VDimension; ++i )
470  {
471  os << obj[i] << ", ";
472  }
473  if( VDimension >= 1 )
474  {
475  os << obj[VDimension - 1];
476  }
477  os << "]";
478  return os;
479 }
480 
481 // ======================= Mirror the access pattern behavior of the std::array class
482 // Array comparisons.
483 template <unsigned int VDimension>
484 inline bool
486 {
487  return std::equal(one.begin(), one.end(), two.begin() );
488 }
489 
490 template <unsigned int VDimension>
491 inline bool
493 {
494  return !(one == two);
495 }
496 
497 template <unsigned int VDimension>
498 inline bool
499 operator<(const Index<VDimension> & one, const Index<VDimension> & two)
500 {
501  return std::lexicographical_compare(one.begin(), one.end(),
502  two.begin(), two.end() );
503 }
504 
505 template <unsigned int VDimension>
506 inline bool
508 {
509  return two < one;
510 }
511 
512 template <unsigned int VDimension>
513 inline bool
514 operator<=(const Index<VDimension> & one, const Index<VDimension> & two)
515 {
516  return !(one > two);
517 }
518 
519 template <unsigned int VDimension>
520 inline bool
522 {
523  return !(one < two);
524 }
525 
526 // Specialized algorithms [6.2.2.2].
527 template <unsigned int VDimension>
528 inline void
530 {
531  std::swap_ranges(one.begin(), one.end(), two.begin() );
532 }
533 
534 // static constexpr definition explicitly needed in C++11
535 template< unsigned int VDimension >
536 constexpr unsigned int Index<VDimension>::Dimension;
537 } // end namespace itk
538 
539 #endif
std::reverse_iterator< const_iterator > const_reverse_iterator
Definition: itkIndex.h:322
bool operator==(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:485
std::reverse_iterator< iterator > reverse_iterator
Definition: itkIndex.h:321
Represent a n-dimensional index in a n-dimensional image.
Definition: itkIndex.h:66
iterator end()
Definition: itkIndex.h:348
reverse_iterator rend()
Definition: itkIndex.h:368
constexpr bool empty() const
Definition: itkIndex.h:388
const Self & operator-=(const SizeType &sz)
Definition: itkIndex.h:133
reference front()
Definition: itkIndex.h:413
SizeValueType m_InternalArray[VDimension]
Definition: itkSize.h:220
bool operator>(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:507
const OffsetType operator-(const Self &vec) const
Definition: itkIndex.h:190
::itk::OffsetValueType OffsetValueType
Definition: itkIndex.h:84
static constexpr unsigned int GetIndexDimension()
Definition: itkIndex.h:90
const Self & operator+=(const SizeType &sz)
Definition: itkIndex.h:109
reverse_iterator rbegin()
Definition: itkIndex.h:358
const value_type * const_iterator
Definition: itkIndex.h:318
const_reverse_iterator rend() const
Definition: itkIndex.h:373
void SetElement(unsigned long element, IndexValueType val)
Definition: itkIndex.h:239
Simulate a standard C array with copy semnatics.
Definition: itkFixedArray.h:51
const Self operator-(const SizeType &sz) const
Definition: itkIndex.h:121
const_reverse_iterator rbegin() const
Definition: itkIndex.h:363
IndexValueType m_InternalArray[VDimension]
Definition: itkIndex.h:276
void swap(Array< T > &a, Array< T > &b)
Definition: itkArray.h:211
static Self GetBasisIndex(unsigned int dim)
Definition: itkIndex.h:457
const Self operator+(const OffsetType &offset) const
Definition: itkIndex.h:144
bool operator!=(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:492
reference back()
Definition: itkIndex.h:423
constexpr size_type max_size() const
Definition: itkIndex.h:383
IndexValueType * data()
Definition: itkIndex.h:433
const_iterator begin() const
Definition: itkIndex.h:343
iterator begin()
Definition: itkIndex.h:338
const_reference operator[](size_type pos) const
Definition: itkIndex.h:398
const Self & operator-=(const OffsetType &offset)
Definition: itkIndex.h:167
signed long IndexValueType
Definition: itkIntTypes.h:90
Represent a n-dimensional size (bounds) of a n-dimensional image.
Definition: itkSize.h:68
Represent a n-dimensional offset between two n-dimensional indexes of n-dimensional image...
Definition: itkOffset.h:67
const Self operator*(const SizeType &vec) const
Definition: itkIndex.h:204
void ExceptionThrowingBoundsCheck(size_type pos) const
Definition: itkIndex.h:444
::itk::IndexValueType IndexValueType
Definition: itkIndex.h:77
void SetIndex(const IndexValueType val[VDimension])
Definition: itkIndex.h:226
const Self operator+(const SizeType &sz) const
Definition: itkIndex.h:97
const Self & operator+=(const OffsetType &offset)
Definition: itkIndex.h:156
constexpr size_type size() const
Definition: itkIndex.h:378
const_iterator end() const
Definition: itkIndex.h:353
void CopyWithCast(const FixedArray< TCoordRep, VDimension > &point)
Definition: itkIndex.h:293
const IndexValueType * data() const
Definition: itkIndex.h:438
void Fill(IndexValueType value)
Definition: itkIndex.h:257
void CopyWithRound(const FixedArray< TCoordRep, VDimension > &point)
Definition: itkIndex.h:282
const_reference back() const
Definition: itkIndex.h:428
const_reference front() const
Definition: itkIndex.h:418
IndexValueType GetElement(unsigned long element) const
Definition: itkIndex.h:250
void swap(Index &other)
Definition: itkIndex.h:333
reference at(size_type pos)
Definition: itkIndex.h:403
const IndexValueType * GetIndex() const
Definition: itkIndex.h:217
const_reference at(size_type pos) const
Definition: itkIndex.h:408
reference operator[](size_type pos)
Definition: itkIndex.h:393
::itk::IndexValueType value_type
Definition: itkIndex.h:314
signed long OffsetValueType
Definition: itkIntTypes.h:94
bool operator>=(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:521
const Self operator-(const OffsetType &off) const
Definition: itkIndex.h:178
void assign(const value_type &newValue)
Definition: itkIndex.h:328
const value_type & const_reference
Definition: itkIndex.h:316
OffsetValueType m_InternalArray[VDimension]
Definition: itkOffset.h:232