ITK  5.2.0
Insight Toolkit
itkOffset.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 itkOffset_h
19 #define itkOffset_h
20 
21 #include "itkSize.h"
22 #include "itkMath.h"
23 
24 namespace itk
25 {
26 
65 
66 template <unsigned int VDimension = 2>
67 struct ITK_TEMPLATE_EXPORT Offset final
68 {
69 public:
70  // Using the `rule of zero` to this aggregate type
71  // C++20 changes the definition of aggregate such that classes with any user-declared ctors are no longer aggregates.
72 
74  using Self = Offset;
75 
79 
81  static constexpr unsigned int Dimension = VDimension;
82 
84  static constexpr unsigned int
86  {
87  return VDimension;
88  }
89 
90 
92  const Self
93  operator+(const Self & vec) const
94  {
95  Self result;
96 
97  for (unsigned int i = 0; i < VDimension; i++)
98  {
99  result[i] = m_InternalArray[i] + vec.m_InternalArray[i];
100  }
101  return result;
102  }
103 
105  const Self
106  operator+(const Size<VDimension> & sz) const
107  {
108  Self result;
109 
110  for (unsigned int i = 0; i < VDimension; i++)
111  {
112  result[i] = m_InternalArray[i] + sz[i];
113  }
114  return result;
115  }
116 
118  const Self &
120  {
121  for (unsigned int i = 0; i < VDimension; i++)
122  {
123  m_InternalArray[i] += sz[i];
124  }
125  return *this;
126  }
128 
130  const Self &
132  {
133  for (unsigned int i = 0; i < VDimension; i++)
134  {
135  m_InternalArray[i] -= sz[i];
136  }
137  return *this;
138  }
140 
142  const Self
143  operator-(const Self & vec)
144  {
145  Self result;
146 
147  for (unsigned int i = 0; i < VDimension; i++)
148  {
149  result[i] = m_InternalArray[i] - vec.m_InternalArray[i];
150  }
151  return result;
152  }
153 
155  const Self &
156  operator+=(const Self & vec)
157  {
158  for (unsigned int i = 0; i < VDimension; i++)
159  {
160  m_InternalArray[i] += vec.m_InternalArray[i];
161  }
162  return *this;
163  }
165 
167  const Self &
168  operator-=(const Self & vec)
169  {
170  for (unsigned int i = 0; i < VDimension; i++)
171  {
172  m_InternalArray[i] -= vec.m_InternalArray[i];
173  }
174  return *this;
175  }
177 
178 
181  const OffsetValueType *
182  GetOffset() const
183  {
184  return m_InternalArray;
185  }
186 
191  void
192  SetOffset(const OffsetValueType val[VDimension])
193  {
194  std::copy_n(val, VDimension, m_InternalArray);
195  }
196 
203  void
204  SetElement(unsigned long element, OffsetValueType val)
205  {
206  m_InternalArray[element] = val;
207  }
208 
216  GetElement(unsigned long element) const
217  {
218  return m_InternalArray[element];
219  }
220 
223  void
225  {
226  std::fill_n(begin(), size(), value);
227  } // MATCH std::array assign, ITK Fill
228 
233  /*
234  * Ask the compiler to align a type to the maximum useful alignment for the target
235  * machine you are compiling for. Whenever you leave out the alignment factor in an
236  * aligned attribute specification, the compiler automatically sets the alignment
237  * for the type to the largest alignment that is ever used for any data type on
238  * the target machine you are compiling for. Doing this can often make copy
239  * operations more efficient, because the compiler can use whatever instructions
240  * copy the biggest chunks of memory when performing copies to or from the variables
241  * that have types that you have aligned this way.
242  */
243  static_assert(VDimension > 0, "Error: Only positive value sized VDimension allowed");
244  alignas(OffsetValueType) OffsetValueType m_InternalArray[VDimension];
246 
248  template <typename TCoordRep>
249  inline void
251  {
252  for (unsigned int i = 0; i < VDimension; ++i)
253  {
254  m_InternalArray[i] = Math::Round<OffsetValueType>(point[i]);
255  }
256  }
258 
260  template <typename TCoordRep>
261  inline void
263  {
264  for (unsigned int i = 0; i < VDimension; ++i)
265  {
266  m_InternalArray[i] = static_cast<OffsetValueType>(point[i]);
267  }
268  }
270 
274  static Self
275  GetBasisOffset(unsigned int dim);
276 
277 
278  // ======================= Mirror the access pattern behavior of the std::array class
286  using const_reference = const value_type &;
287  using iterator = value_type *;
288  using const_iterator = const value_type *;
289  using size_type = unsigned int;
290  using difference_type = std::ptrdiff_t;
291  using reverse_iterator = std::reverse_iterator<iterator>;
292  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
293 
298  void
299  assign(const value_type & newValue)
300  {
301  std::fill_n(begin(), size(), newValue);
302  }
303 
304  void
305  swap(Offset & other)
306  {
307  std::swap(m_InternalArray, other.m_InternalArray);
308  }
309 
310  iterator
312  {
313  return iterator(&m_InternalArray[0]);
314  }
315 
316  const_iterator
317  begin() const
318  {
319  return const_iterator(&m_InternalArray[0]);
320  }
321 
322  iterator
323  end()
324  {
325  return iterator(&m_InternalArray[VDimension]);
326  }
327 
328  const_iterator
329  end() const
330  {
331  return const_iterator(&m_InternalArray[VDimension]);
332  }
333 
334  reverse_iterator
336  {
337  return reverse_iterator(end());
338  }
339 
340  const_reverse_iterator
341  rbegin() const
342  {
343  return const_reverse_iterator(end());
344  }
345 
346  reverse_iterator
348  {
349  return reverse_iterator(begin());
350  }
351 
352  const_reverse_iterator
353  rend() const
354  {
355  return const_reverse_iterator(begin());
356  }
357 
358  constexpr size_type
359  size() const
360  {
361  return VDimension;
362  }
363 
364  constexpr size_type
365  max_size() const
366  {
367  return VDimension;
368  }
369 
370  constexpr bool
371  empty() const
372  {
373  return false;
374  }
375 
376  reference operator[](size_type pos) { return m_InternalArray[pos]; }
377 
378  const_reference operator[](size_type pos) const { return m_InternalArray[pos]; }
379 
380  reference
382  {
383  ExceptionThrowingBoundsCheck(pos);
384  return m_InternalArray[pos];
385  }
386 
387  const_reference
388  at(size_type pos) const
389  {
390  ExceptionThrowingBoundsCheck(pos);
391  return m_InternalArray[pos];
392  }
393 
394  reference
396  {
397  return *begin();
398  }
399 
400  const_reference
401  front() const
402  {
403  return *begin();
404  }
405 
406  reference
408  {
409  return VDimension ? *(end() - 1) : *end();
410  }
411 
412  const_reference
413  back() const
414  {
415  return VDimension ? *(end() - 1) : *end();
416  }
417 
420  {
421  return &m_InternalArray[0];
422  }
423 
424  const OffsetValueType *
425  data() const
426  {
427  return &m_InternalArray[0];
428  }
429 
430 private:
431  void
433  {
434  if (pos >= VDimension)
435  {
436  throw std::out_of_range("array::ExceptionThrowingBoundsCheck");
437  }
438  }
439 
440 }; //------------ End struct Offset
441 
442 template <unsigned int VDimension>
443 Offset<VDimension>
445 {
446  Self ind;
447 
448  memset(ind.m_InternalArray, 0, sizeof(OffsetValueType) * VDimension);
449  ind.m_InternalArray[dim] = 1;
450  return ind;
451 }
452 
453 template <unsigned int VDimension>
454 std::ostream &
455 operator<<(std::ostream & os, const Offset<VDimension> & ind)
456 {
457  os << "[";
458  unsigned int dimlim = VDimension - 1;
459  for (unsigned int i = 0; i < dimlim; ++i)
460  {
461  os << ind[i] << ", ";
462  }
463  if (VDimension >= 1)
464  {
465  os << ind[VDimension - 1];
466  }
467  os << "]";
468  return os;
469 }
470 
471 // ======================= Mirror the access pattern behavior of the std::array class
472 // Array comparisons.
473 template <unsigned int VDimension>
474 inline bool
476 {
477  return std::equal(one.begin(), one.end(), two.begin());
478 }
479 
480 template <unsigned int VDimension>
481 inline bool
483 {
484  return !(one == two);
485 }
486 
487 template <unsigned int VDimension>
488 inline bool
490 {
491  return std::lexicographical_compare(one.begin(), one.end(), two.begin(), two.end());
492 }
493 
494 template <unsigned int VDimension>
495 inline bool
497 {
498  return two < one;
499 }
500 
501 template <unsigned int VDimension>
502 inline bool
504 {
505  return !(one > two);
506 }
507 
508 template <unsigned int VDimension>
509 inline bool
511 {
512  return !(one < two);
513 }
514 
515 // Specialized algorithms [6.2.2.2].
516 template <unsigned int VDimension>
517 inline void
519 {
521 }
522 
523 // static constexpr definition explicitly needed in C++11
524 template <unsigned int VDimension>
525 constexpr unsigned int Offset<VDimension>::Dimension;
526 
527 } // end namespace itk
528 
529 #endif
itk::Offset::operator-=
const Self & operator-=(const Self &vec)
Definition: itkOffset.h:168
itk::Offset::CopyWithRound
void CopyWithRound(const FixedArray< TCoordRep, VDimension > &point)
Definition: itkOffset.h:250
itk::Offset::GetOffset
const OffsetValueType * GetOffset() const
Definition: itkOffset.h:182
itk::Offset::Fill
void Fill(OffsetValueType value)
Definition: itkOffset.h:224
itk::operator<
bool operator<(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:546
itk::swap
void swap(Offset< VDimension > &one, Offset< VDimension > &two)
Definition: itkOffset.h:518
itk::operator<=
bool operator<=(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:560
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
itk::Offset::SetOffset
void SetOffset(const OffsetValueType val[VDimension])
Definition: itkOffset.h:192
itk::Offset::rbegin
reverse_iterator rbegin()
Definition: itkOffset.h:335
itk::Offset::operator[]
const_reference operator[](size_type pos) const
Definition: itkOffset.h:378
itk::Offset::rend
reverse_iterator rend()
Definition: itkOffset.h:347
itk::Offset< ImageDimension+1 >::const_reverse_iterator
std::reverse_iterator< const_iterator > const_reverse_iterator
Definition: itkOffset.h:292
itk::swap
void swap(Array< T > &a, Array< T > &b)
Definition: itkArray.h:239
itk::Offset::operator-
const Self operator-(const Self &vec)
Definition: itkOffset.h:143
itk::Offset::GetBasisOffset
static Self GetBasisOffset(unsigned int dim)
Definition: itkOffset.h:444
itk::Offset::empty
constexpr bool empty() const
Definition: itkOffset.h:371
itk::Offset< ImageDimension+1 >::const_reference
const value_type & const_reference
Definition: itkOffset.h:286
itk::Offset::end
const_iterator end() const
Definition: itkOffset.h:329
itk::Offset::rend
const_reverse_iterator rend() const
Definition: itkOffset.h:353
itk::Offset< ImageDimension+1 >::iterator
value_type * iterator
Definition: itkOffset.h:287
itk::Offset::swap
void swap(Offset &other)
Definition: itkOffset.h:305
itk::Offset::operator[]
reference operator[](size_type pos)
Definition: itkOffset.h:376
itk::Offset::GetOffsetDimension
static constexpr unsigned int GetOffsetDimension()
Definition: itkOffset.h:85
itk::Offset::begin
const_iterator begin() const
Definition: itkOffset.h:317
itk::Offset::operator-=
const Self & operator-=(const Size< VDimension > &sz)
Definition: itkOffset.h:131
itk::Offset< ImageDimension+1 >::reverse_iterator
std::reverse_iterator< iterator > reverse_iterator
Definition: itkOffset.h:291
itk::Offset::data
const OffsetValueType * data() const
Definition: itkOffset.h:425
itk::Offset::back
const_reference back() const
Definition: itkOffset.h:413
itk::Offset::size
constexpr size_type size() const
Definition: itkOffset.h:359
itk::Offset::operator+=
const Self & operator+=(const Self &vec)
Definition: itkOffset.h:156
itk::Offset::operator+=
const Self & operator+=(const Size< VDimension > &sz)
Definition: itkOffset.h:119
itk::Offset::front
reference front()
Definition: itkOffset.h:395
itk::Offset::Dimension
static constexpr unsigned int Dimension
Definition: itkOffset.h:81
itk::Offset::assign
void assign(const value_type &newValue)
Definition: itkOffset.h:299
itk::operator>=
bool operator>=(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:567
itk::Offset::max_size
constexpr size_type max_size() const
Definition: itkOffset.h:365
itk::Offset::m_InternalArray
OffsetValueType m_InternalArray[VDimension]
Definition: itkOffset.h:243
itk::operator>
bool operator>(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:553
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::Offset::CopyWithCast
void CopyWithCast(const FixedArray< TCoordRep, VDimension > &point)
Definition: itkOffset.h:262
itk::Offset
Represent a n-dimensional offset between two n-dimensional indexes of n-dimensional image.
Definition: itkOffset.h:67
itk::Offset::operator+
const Self operator+(const Size< VDimension > &sz) const
Definition: itkOffset.h:106
itk::Offset::operator+
const Self operator+(const Self &vec) const
Definition: itkOffset.h:93
itk::Offset< ImageDimension+1 >::difference_type
std::ptrdiff_t difference_type
Definition: itkOffset.h:290
itk::operator!=
bool operator!=(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:539
itk
The "itk" namespace contains all Insight Segmentation and Registration Toolkit (ITK) classes....
Definition: itkAnnulusOperator.h:24
itk::Offset::rbegin
const_reverse_iterator rbegin() const
Definition: itkOffset.h:341
itk::Offset::back
reference back()
Definition: itkOffset.h:407
itk::Offset::data
OffsetValueType * data()
Definition: itkOffset.h:419
itk::Offset::front
const_reference front() const
Definition: itkOffset.h:401
itk::OffsetValueType
signed long OffsetValueType
Definition: itkIntTypes.h:94
itk::Offset::at
reference at(size_type pos)
Definition: itkOffset.h:381
itk::Offset< ImageDimension+1 >::OffsetValueType
::itk::OffsetValueType OffsetValueType
Definition: itkOffset.h:78
itk::Offset::GetElement
OffsetValueType GetElement(unsigned long element) const
Definition: itkOffset.h:216
itk::Offset< ImageDimension+1 >::reference
value_type & reference
Definition: itkOffset.h:285
itk::Offset::ExceptionThrowingBoundsCheck
void ExceptionThrowingBoundsCheck(size_type pos) const
Definition: itkOffset.h:432
itk::Offset::begin
iterator begin()
Definition: itkOffset.h:311
itk::Offset::at
const_reference at(size_type pos) const
Definition: itkOffset.h:388
itk::Offset< ImageDimension+1 >::size_type
unsigned int size_type
Definition: itkOffset.h:289
itk::Offset< ImageDimension+1 >::value_type
::itk::OffsetValueType value_type
Definition: itkOffset.h:284
itk::GTest::TypedefsAndConstructors::Dimension2::Dimension
constexpr unsigned int Dimension
Definition: itkGTestTypedefsAndConstructors.h:44
itkMath.h
itk::Offset< ImageDimension+1 >::const_iterator
const value_type * const_iterator
Definition: itkOffset.h:288
itk::Offset::SetElement
void SetElement(unsigned long element, OffsetValueType val)
Definition: itkOffset.h:204
itk::Offset::end
iterator end()
Definition: itkOffset.h:323
itkSize.h