ITK  5.0.0
Insight Segmentation and Registration Toolkit
itkOffset.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 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 GetOffsetDimension()
85  {
86  return VDimension;
87  }
88 
89 
91  const Self operator+(const Self & vec) const
92  {
93  Self result;
94 
95  for( unsigned int i = 0; i < VDimension; i++ )
96  {
97  result[i] = m_InternalArray[i] + vec.m_InternalArray[i];
98  }
99  return result;
100  }
101 
103  const Self operator+(const Size<VDimension> & sz) const
104  {
105  Self result;
106 
107  for( unsigned int i = 0; i < VDimension; i++ )
108  {
109  result[i] = m_InternalArray[i] + sz[i];
110  }
111  return result;
112  }
113 
115  const Self & operator+=(const Size<VDimension> & sz)
116  {
117  for( unsigned int i = 0; i < VDimension; i++ )
118  {
119  m_InternalArray[i] += sz[i];
120  }
121  return *this;
122  }
124 
126  const Self & operator-=(const Size<VDimension> & sz)
127  {
128  for( unsigned int i = 0; i < VDimension; i++ )
129  {
130  m_InternalArray[i] -= sz[i];
131  }
132  return *this;
133  }
135 
137  const Self operator-(const Self & vec)
138  {
139  Self result;
140 
141  for( unsigned int i = 0; i < VDimension; i++ )
142  {
143  result[i] = m_InternalArray[i] - vec.m_InternalArray[i];
144  }
145  return result;
146  }
147 
149  const Self & operator+=(const Self & vec)
150  {
151  for( unsigned int i = 0; i < VDimension; i++ )
152  {
153  m_InternalArray[i] += vec.m_InternalArray[i];
154  }
155  return *this;
156  }
158 
160  const Self & operator-=(const Self & vec)
161  {
162  for( unsigned int i = 0; i < VDimension; i++ )
163  {
164  m_InternalArray[i] -= vec.m_InternalArray[i];
165  }
166  return *this;
167  }
169 
170 
173  const OffsetValueType * GetOffset() const
174  {
175  return m_InternalArray;
176  }
177 
182  void SetOffset(const OffsetValueType val[VDimension])
183  {
184  std::copy(val,
185  val + VDimension,
186  m_InternalArray);
187  }
188 
195  void SetElement(unsigned long element, OffsetValueType val)
196  {
197  m_InternalArray[element] = val;
198  }
199 
206  OffsetValueType GetElement(unsigned long element) const
207  {
208  return m_InternalArray[element];
209  }
210 
213  void Fill(OffsetValueType value)
214  {
215  std::fill_n(begin(), size(), value);
216  } // MATCH std::array assign, ITK Fill
217 
222  /*
223  * Ask the compiler to align a type to the maximum useful alignment for the target
224  * machine you are compiling for. Whenever you leave out the alignment factor in an
225  * aligned attribute specification, the compiler automatically sets the alignment
226  * for the type to the largest alignment that is ever used for any data type on
227  * the target machine you are compiling for. Doing this can often make copy
228  * operations more efficient, because the compiler can use whatever instructions
229  * copy the biggest chunks of memory when performing copies to or from the variables
230  * that have types that you have aligned this way.
231  */
232  static_assert( VDimension > 0, "Error: Only positive value sized VDimension allowed" );
233  alignas(OffsetValueType) OffsetValueType m_InternalArray[VDimension];
235 
237  template <typename TCoordRep>
239  {
240  for( unsigned int i = 0; i < VDimension; ++i )
241  {
242  m_InternalArray[i] = Math::Round<OffsetValueType>(point[i]);
243  }
244  }
246 
248  template <typename TCoordRep>
250  {
251  for( unsigned int i = 0; i < VDimension; ++i )
252  {
253  m_InternalArray[i] = static_cast<OffsetValueType>( point[i] );
254  }
255  }
257 
261  static Self GetBasisOffset(unsigned int dim);
262 
263 
264  // ======================= Mirror the access pattern behavior of the std::array class
272  using const_reference = const value_type &;
273  using iterator = value_type *;
274  using const_iterator = const value_type *;
275  using size_type = unsigned int;
276  using difference_type = std::ptrdiff_t;
277  using reverse_iterator = std::reverse_iterator<iterator>;
278  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
279 
284  void assign(const value_type & newValue)
285  {
286  std::fill_n(begin(), size(), newValue);
287  }
288 
289  void swap(Offset & other)
290  {
291  std::swap_ranges(begin(), end(), other.begin() );
292  }
293 
295  {
296  return iterator(&m_InternalArray[0]);
297  }
298 
300  {
301  return const_iterator(&m_InternalArray[0]);
302  }
303 
305  {
306  return iterator(&m_InternalArray[VDimension]);
307  }
308 
310  {
311  return const_iterator(&m_InternalArray[VDimension]);
312  }
313 
315  {
316  return reverse_iterator(end() );
317  }
318 
320  {
321  return const_reverse_iterator(end() );
322  }
323 
325  {
326  return reverse_iterator(begin() );
327  }
328 
330  {
331  return const_reverse_iterator(begin() );
332  }
333 
334  constexpr size_type size() const
335  {
336  return VDimension;
337  }
338 
339  constexpr size_type max_size() const
340  {
341  return VDimension;
342  }
343 
344  constexpr bool empty() const
345  {
346  return false;
347  }
348 
350  {
351  return m_InternalArray[pos];
352  }
353 
355  {
356  return m_InternalArray[pos];
357  }
358 
360  {
361  ExceptionThrowingBoundsCheck(pos); return m_InternalArray[pos];
362  }
363 
365  {
366  ExceptionThrowingBoundsCheck(pos); return m_InternalArray[pos];
367  }
368 
370  {
371  return *begin();
372  }
373 
375  {
376  return *begin();
377  }
378 
380  {
381  return VDimension ? *(end() - 1) : *end();
382  }
383 
385  {
386  return VDimension ? *(end() - 1) : *end();
387  }
388 
390  {
391  return &m_InternalArray[0];
392  }
393 
394  const OffsetValueType * data() const
395  {
396  return &m_InternalArray[0];
397  }
398 
399 private:
401  {
402  if( pos >= VDimension )
403  {
404  throw std::out_of_range("array::ExceptionThrowingBoundsCheck");
405  }
406  }
407 
408 }; //------------ End struct Offset
409 
410 template <unsigned int VDimension>
411 Offset<VDimension>
413 ::GetBasisOffset(unsigned int dim)
414 {
415  Self ind;
416 
417  memset(ind.m_InternalArray, 0, sizeof( OffsetValueType ) * VDimension);
418  ind.m_InternalArray[dim] = 1;
419  return ind;
420 }
421 
422 template <unsigned int VDimension>
423 std::ostream & operator<<(std::ostream & os, const Offset<VDimension> & ind)
424 {
425  os << "[";
426  unsigned int dimlim = VDimension - 1;
427  for( unsigned int i = 0; i < dimlim; ++i )
428  {
429  os << ind[i] << ", ";
430  }
431  if( VDimension >= 1 )
432  {
433  os << ind[VDimension - 1];
434  }
435  os << "]";
436  return os;
437 }
438 
439 // ======================= Mirror the access pattern behavior of the std::array class
440 // Array comparisons.
441 template <unsigned int VDimension>
442 inline bool
444 {
445  return std::equal(one.begin(), one.end(), two.begin() );
446 }
447 
448 template <unsigned int VDimension>
449 inline bool
451 {
452  return !(one == two);
453 }
454 
455 template <unsigned int VDimension>
456 inline bool
457 operator<(const Offset<VDimension> & one, const Offset<VDimension> & two)
458 {
459  return std::lexicographical_compare(one.begin(), one.end(),
460  two.begin(), two.end() );
461 }
462 
463 template <unsigned int VDimension>
464 inline bool
466 {
467  return two < one;
468 }
469 
470 template <unsigned int VDimension>
471 inline bool
472 operator<=(const Offset<VDimension> & one, const Offset<VDimension> & two)
473 {
474  return !(one > two);
475 }
476 
477 template <unsigned int VDimension>
478 inline bool
480 {
481  return !(one < two);
482 }
483 
484 // Specialized algorithms [6.2.2.2].
485 template <unsigned int VDimension>
486 inline void
488 {
489  std::swap_ranges(one.begin(), one.end(), two.begin() );
490 }
491 
492 // static constexpr definition explicitly needed in C++11
493 template< unsigned int VDimension >
494 constexpr unsigned int Offset<VDimension>::Dimension;
495 
496 } // end namespace itk
497 
498 #endif
const Self operator+(const Self &vec) const
Definition: itkOffset.h:91
bool operator==(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:485
void ExceptionThrowingBoundsCheck(size_type pos) const
Definition: itkOffset.h:400
reverse_iterator rend()
Definition: itkOffset.h:324
std::reverse_iterator< const_iterator > const_reverse_iterator
Definition: itkOffset.h:278
reference front()
Definition: itkOffset.h:369
void SetOffset(const OffsetValueType val[VDimension])
Definition: itkOffset.h:182
const_iterator begin() const
Definition: itkOffset.h:299
bool operator>(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:507
std::ptrdiff_t difference_type
Definition: itkOffset.h:276
constexpr bool empty() const
Definition: itkOffset.h:344
reference back()
Definition: itkOffset.h:379
const OffsetValueType * GetOffset() const
Definition: itkOffset.h:173
OffsetValueType * data()
Definition: itkOffset.h:389
const_reference at(size_type pos) const
Definition: itkOffset.h:364
const value_type * const_iterator
Definition: itkOffset.h:274
const OffsetValueType * data() const
Definition: itkOffset.h:394
iterator end()
Definition: itkOffset.h:304
const_reverse_iterator rbegin() const
Definition: itkOffset.h:319
Simulate a standard C array with copy semnatics.
Definition: itkFixedArray.h:51
reference at(size_type pos)
Definition: itkOffset.h:359
void swap(Array< T > &a, Array< T > &b)
Definition: itkArray.h:211
const_iterator end() const
Definition: itkOffset.h:309
bool operator!=(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:492
const_reverse_iterator rend() const
Definition: itkOffset.h:329
void assign(const value_type &newValue)
Definition: itkOffset.h:284
const Self & operator-=(const Self &vec)
Definition: itkOffset.h:160
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 Size< VDimension > &sz) const
Definition: itkOffset.h:103
const_reference back() const
Definition: itkOffset.h:384
reverse_iterator rbegin()
Definition: itkOffset.h:314
void CopyWithRound(const FixedArray< TCoordRep, VDimension > &point)
Definition: itkOffset.h:238
const value_type & const_reference
Definition: itkOffset.h:272
iterator begin()
Definition: itkOffset.h:294
const_reference operator[](size_type pos) const
Definition: itkOffset.h:354
void swap(Offset &other)
Definition: itkOffset.h:289
void CopyWithCast(const FixedArray< TCoordRep, VDimension > &point)
Definition: itkOffset.h:249
OffsetValueType GetElement(unsigned long element) const
Definition: itkOffset.h:206
const_reference front() const
Definition: itkOffset.h:374
static constexpr unsigned int GetOffsetDimension()
Definition: itkOffset.h:84
const Self operator-(const Self &vec)
Definition: itkOffset.h:137
reference operator[](size_type pos)
Definition: itkOffset.h:349
std::reverse_iterator< iterator > reverse_iterator
Definition: itkOffset.h:277
static Self GetBasisOffset(unsigned int dim)
Definition: itkOffset.h:413
::itk::OffsetValueType OffsetValueType
Definition: itkOffset.h:78
void Fill(OffsetValueType value)
Definition: itkOffset.h:213
const Self & operator-=(const Size< VDimension > &sz)
Definition: itkOffset.h:126
constexpr size_type max_size() const
Definition: itkOffset.h:339
void SetElement(unsigned long element, OffsetValueType val)
Definition: itkOffset.h:195
const Self & operator+=(const Self &vec)
Definition: itkOffset.h:149
constexpr size_type size() const
Definition: itkOffset.h:334
signed long OffsetValueType
Definition: itkIntTypes.h:94
const Self & operator+=(const Size< VDimension > &sz)
Definition: itkOffset.h:115
bool operator>=(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:521
::itk::OffsetValueType value_type
Definition: itkOffset.h:270
OffsetValueType m_InternalArray[VDimension]
Definition: itkOffset.h:232