ITK  5.1.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_n(val, VDimension, m_InternalArray);
229  }
230 
237  void SetElement(unsigned long element, IndexValueType val)
238  {
239  m_InternalArray[element] = val;
240  }
241 
248  IndexValueType GetElement(unsigned long element) const
249  {
250  return m_InternalArray[element];
251  }
252 
255  void Fill(IndexValueType value)
256  {
257  std::fill_n(begin(), size(), value);
258  } // MATCH std::array assign, ITK Fill
259 
264  /*
265  * Ask the compiler to align a type to the maximum useful alignment for the target
266  * machine you are compiling for. Whenever you leave out the alignment factor in an
267  * aligned attribute specification, the compiler automatically sets the alignment
268  * for the type to the largest alignment that is ever used for any data type on
269  * the target machine you are compiling for. Doing this can often make copy
270  * operations more efficient, because the compiler can use whatever instructions
271  * copy the biggest chunks of memory when performing copies to or from the variables
272  * that have types that you have aligned this way.
273  */
274  static_assert( VDimension > 0, "Error: Only positive value sized VDimension allowed" );
275  alignas(IndexValueType) IndexValueType m_InternalArray[VDimension];
277 
279  template <typename TCoordRep>
281  {
282  for( unsigned int i = 0; i < VDimension; ++i )
283  {
284  m_InternalArray[i] = Math::Round<IndexValueType>(point[i]);
285  }
286  }
288 
290  template <typename TCoordRep>
292  {
293  for( unsigned int i = 0; i < VDimension; ++i )
294  {
295  m_InternalArray[i] = static_cast<IndexValueType>( point[i] );
296  }
297  }
299 
303  static Self GetBasisIndex(unsigned int dim);
304 
305 
306  // ======================= Mirror the access pattern behavior of the std::array class
314  using const_reference = const value_type &;
315  using iterator = value_type *;
316  using const_iterator = const value_type *;
317  using size_type = unsigned int;
318  using difference_type = std::ptrdiff_t;
319  using reverse_iterator = std::reverse_iterator<iterator>;
320  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
321 
326  void assign(const value_type & newValue)
327  {
328  std::fill_n(begin(), size(), newValue);
329  }
330 
331  void swap(Index & other)
332  {
333  std::swap(m_InternalArray, other.m_InternalArray);
334  }
335 
337  {
338  return iterator(&m_InternalArray[0]);
339  }
340 
342  {
343  return const_iterator(&m_InternalArray[0]);
344  }
345 
347  {
348  return iterator(&m_InternalArray[VDimension]);
349  }
350 
352  {
353  return const_iterator(&m_InternalArray[VDimension]);
354  }
355 
357  {
358  return reverse_iterator(end() );
359  }
360 
362  {
363  return const_reverse_iterator(end() );
364  }
365 
367  {
368  return reverse_iterator(begin() );
369  }
370 
372  {
373  return const_reverse_iterator(begin() );
374  }
375 
376  constexpr size_type size() const
377  {
378  return VDimension;
379  }
380 
381  constexpr size_type max_size() const
382  {
383  return VDimension;
384  }
385 
386  constexpr bool empty() const
387  {
388  return false;
389  }
390 
392  {
393  return m_InternalArray[pos];
394  }
395 
397  {
398  return m_InternalArray[pos];
399  }
400 
402  {
403  ExceptionThrowingBoundsCheck(pos); return m_InternalArray[pos];
404  }
405 
407  {
408  ExceptionThrowingBoundsCheck(pos); return m_InternalArray[pos];
409  }
410 
412  {
413  return *begin();
414  }
415 
417  {
418  return *begin();
419  }
420 
422  {
423  return VDimension ? *(end() - 1) : *end();
424  }
425 
427  {
428  return VDimension ? *(end() - 1) : *end();
429  }
430 
432  {
433  return &m_InternalArray[0];
434  }
435 
436  const IndexValueType * data() const
437  {
438  return &m_InternalArray[0];
439  }
440 
441 private:
443  {
444  if( pos >= VDimension )
445  {
446  throw std::out_of_range("array::ExceptionThrowingBoundsCheck");
447  }
448  }
449 
450 }; //------------ End struct Index
451 
452 template <unsigned int VDimension>
453 Index<VDimension>
455 ::GetBasisIndex(unsigned int dim)
456 {
457  Self ind{{0}};
458 
459  ind.m_InternalArray[dim] = 1;
460  return ind;
461 }
462 
463 template <unsigned int VDimension>
464 std::ostream & operator<<(std::ostream & os, const Index<VDimension> & obj)
465 {
466  os << "[";
467  for( unsigned int i = 0; i + 1 < VDimension; ++i )
468  {
469  os << obj[i] << ", ";
470  }
471  if( VDimension >= 1 )
472  {
473  os << obj[VDimension - 1];
474  }
475  os << "]";
476  return os;
477 }
478 
479 // ======================= Mirror the access pattern behavior of the std::array class
480 // Array comparisons.
481 template <unsigned int VDimension>
482 inline bool
484 {
485  return std::equal(one.begin(), one.end(), two.begin() );
486 }
487 
488 template <unsigned int VDimension>
489 inline bool
491 {
492  return !(one == two);
493 }
494 
495 template <unsigned int VDimension>
496 inline bool
498 {
499  return std::lexicographical_compare(one.begin(), one.end(),
500  two.begin(), two.end() );
501 }
502 
503 template <unsigned int VDimension>
504 inline bool
506 {
507  return two < one;
508 }
509 
510 template <unsigned int VDimension>
511 inline bool
513 {
514  return !(one > two);
515 }
516 
517 template <unsigned int VDimension>
518 inline bool
520 {
521  return !(one < two);
522 }
523 
524 // Specialized algorithms [6.2.2.2].
525 template <unsigned int VDimension>
526 inline void
528 {
530 }
531 
532 // static constexpr definition explicitly needed in C++11
533 template< unsigned int VDimension >
534 constexpr unsigned int Index<VDimension>::Dimension;
535 } // end namespace itk
536 
537 #endif
std::reverse_iterator< const_iterator > const_reverse_iterator
Definition: itkIndex.h:320
bool operator==(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:483
void swap(Index< VDimension > &one, Index< VDimension > &two)
Definition: itkIndex.h:527
constexpr size_type size() const
Definition: itkIndex.h:376
std::reverse_iterator< iterator > reverse_iterator
Definition: itkIndex.h:319
Represent a n-dimensional index in a n-dimensional image.
Definition: itkIndex.h:66
iterator end()
Definition: itkIndex.h:346
reverse_iterator rend()
Definition: itkIndex.h:366
const IndexValueType * GetIndex() const
Definition: itkIndex.h:217
const Self & operator-=(const SizeType &sz)
Definition: itkIndex.h:133
reference front()
Definition: itkIndex.h:411
SizeValueType m_InternalArray[VDimension]
Definition: itkSize.h:219
bool operator>(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:505
const_iterator end() const
Definition: itkIndex.h:351
std::ostream & operator<<(std::ostream &os, const Array< TValue > &arr)
Definition: itkArray.h:188
The "itk" namespace contains all Insight Segmentation and Registration Toolkit (ITK) classes....
Definition: itkArray.h:26
::itk::OffsetValueType OffsetValueType
Definition: itkIndex.h:84
const_reference operator[](size_type pos) const
Definition: itkIndex.h:396
static constexpr unsigned int GetIndexDimension()
Definition: itkIndex.h:90
const Self & operator+=(const SizeType &sz)
Definition: itkIndex.h:109
const_reference at(size_type pos) const
Definition: itkIndex.h:406
reverse_iterator rbegin()
Definition: itkIndex.h:356
const value_type * const_iterator
Definition: itkIndex.h:316
void SetElement(unsigned long element, IndexValueType val)
Definition: itkIndex.h:237
const IndexValueType * data() const
Definition: itkIndex.h:436
const_reverse_iterator rend() const
Definition: itkIndex.h:371
Simulate a standard C array with copy semantics.
Definition: itkFixedArray.h:52
IndexValueType m_InternalArray[VDimension]
Definition: itkIndex.h:274
void swap(Array< T > &a, Array< T > &b)
Definition: itkArray.h:211
static Self GetBasisIndex(unsigned int dim)
Definition: itkIndex.h:455
bool operator<=(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:512
bool operator!=(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:490
reference back()
Definition: itkIndex.h:421
const Self operator-(const SizeType &sz) const
Definition: itkIndex.h:121
CovariantVector< T, NVectorDimension > operator *(const T &scalar, const CovariantVector< T, NVectorDimension > &v)
IndexValueType * data()
Definition: itkIndex.h:431
iterator begin()
Definition: itkIndex.h:336
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:69
Represent a n-dimensional offset between two n-dimensional indexes of n-dimensional image.
Definition: itkOffset.h:67
const_reverse_iterator rbegin() const
Definition: itkIndex.h:361
const_reference front() const
Definition: itkIndex.h:416
::itk::IndexValueType IndexValueType
Definition: itkIndex.h:77
void SetIndex(const IndexValueType val[VDimension])
Definition: itkIndex.h:226
const_reference back() const
Definition: itkIndex.h:426
const Self & operator+=(const OffsetType &offset)
Definition: itkIndex.h:156
IndexValueType GetElement(unsigned long element) const
Definition: itkIndex.h:248
constexpr size_type max_size() const
Definition: itkIndex.h:381
void CopyWithCast(const FixedArray< TCoordRep, VDimension > &point)
Definition: itkIndex.h:291
const Self operator-(const OffsetType &off) const
Definition: itkIndex.h:178
bool operator<(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:497
void Fill(IndexValueType value)
Definition: itkIndex.h:255
const OffsetType operator-(const Self &vec) const
Definition: itkIndex.h:190
void CopyWithRound(const FixedArray< TCoordRep, VDimension > &point)
Definition: itkIndex.h:280
void swap(Index &other)
Definition: itkIndex.h:331
reference at(size_type pos)
Definition: itkIndex.h:401
const Self operator+(const OffsetType &offset) const
Definition: itkIndex.h:144
const_iterator begin() const
Definition: itkIndex.h:341
reference operator[](size_type pos)
Definition: itkIndex.h:391
::itk::IndexValueType value_type
Definition: itkIndex.h:312
static constexpr unsigned int Dimension
Definition: itkIndex.h:87
signed long OffsetValueType
Definition: itkIntTypes.h:94
constexpr bool empty() const
Definition: itkIndex.h:386
const Self operator+(const SizeType &sz) const
Definition: itkIndex.h:97
bool operator>=(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:519
void assign(const value_type &newValue)
Definition: itkIndex.h:326
const value_type & const_reference
Definition: itkIndex.h:314
OffsetValueType m_InternalArray[VDimension]
Definition: itkOffset.h:230
void ExceptionThrowingBoundsCheck(size_type pos) const
Definition: itkIndex.h:442