ITK  5.2.0
Insight Toolkit
itkSize.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 itkSize_h
19 #define itkSize_h
20 
21 #include "itkIntTypes.h"
22 #include "itkMacro.h"
23 #include <algorithm> // For copy_n.
24 #include <type_traits>
25 #include <memory>
26 
27 namespace itk
28 {
29 
67 
68 template <unsigned int VDimension = 2>
69 struct ITK_TEMPLATE_EXPORT Size final
70 {
71 public:
72  // Using the `rule of zero` to this aggregate type
73  // C++20 changes the definition of aggregate such that classes with any user-declared ctors are no longer aggregates.
74 
76  using Self = Size;
77 
81 
83  static constexpr unsigned int Dimension = VDimension;
84 
86  static constexpr unsigned int
88  {
89  return VDimension;
90  }
91 
93  const Self
94  operator+(const Self & vec) const
95  {
96  Self result;
97 
98  for (unsigned int i = 0; i < VDimension; i++)
99  {
100  result[i] = m_InternalArray[i] + vec.m_InternalArray[i];
101  }
102  return result;
103  }
104 
106  const Self &
107  operator+=(const Self & vec)
108  {
109  for (unsigned int i = 0; i < VDimension; i++)
110  {
111  m_InternalArray[i] += vec.m_InternalArray[i];
112  }
113  return *this;
114  }
116 
118  const Self
119  operator-(const Self & vec) const
120  {
121  Self result;
122 
123  for (unsigned int i = 0; i < VDimension; i++)
124  {
125  result[i] = m_InternalArray[i] - vec.m_InternalArray[i];
126  }
127  return result;
128  }
129 
131  const Self &
132  operator-=(const Self & vec)
133  {
134  for (unsigned int i = 0; i < VDimension; i++)
135  {
136  m_InternalArray[i] -= vec.m_InternalArray[i];
137  }
138  return *this;
139  }
141 
143  const Self operator*(const Self & vec) const
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 
168  const SizeValueType *
169  GetSize() const
170  {
171  return m_InternalArray;
172  }
173 
178  void
179  SetSize(const SizeValueType val[VDimension])
180  {
181  std::copy_n(val, VDimension, m_InternalArray);
182  }
183 
190  void
191  SetElement(unsigned long element, SizeValueType val)
192  {
193  m_InternalArray[element] = val;
194  }
195 
203  GetElement(unsigned long element) const
204  {
205  return m_InternalArray[element];
206  }
207 
210  void
212  {
213  std::fill_n(begin(), size(), value);
214  } // MATCH std::array assign, ITK Fill
215 
220  /*
221  * Ask the compiler to align a type to the maximum useful alignment for the target
222  * machine you are compiling for. Whenever you leave out the alignment factor in an
223  * aligned attribute specification, the compiler automatically sets the alignment
224  * for the type to the largest alignment that is ever used for any data type on
225  * the target machine you are compiling for. Doing this can often make copy
226  * operations more efficient, because the compiler can use whatever instructions
227  * copy the biggest chunks of memory when performing copies to or from the variables
228  * that have types that you have aligned this way.
229  */
230  static_assert(VDimension > 0, "Error: Only positive value sized VDimension allowed");
231  alignas(SizeValueType) SizeValueType m_InternalArray[VDimension];
233 
234  // ======================= Mirror the access pattern behavior of the std::array class
242  using const_reference = const value_type &;
243  using iterator = value_type *;
244  using const_iterator = const value_type *;
245  using size_type = unsigned int;
246  using difference_type = std::ptrdiff_t;
247  using reverse_iterator = std::reverse_iterator<iterator>;
248  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
249 
254  void
255  assign(const value_type & newValue)
256  {
257  std::fill_n(begin(), size(), newValue);
258  }
259 
260  void
261  swap(Size & other)
262  {
263  std::swap(m_InternalArray, other.m_InternalArray);
264  }
265 
266  iterator
268  {
269  return iterator(&m_InternalArray[0]);
270  }
271 
272  const_iterator
273  begin() const
274  {
275  return const_iterator(&m_InternalArray[0]);
276  }
277 
278  iterator
279  end()
280  {
281  return iterator(&m_InternalArray[VDimension]);
282  }
283 
284  const_iterator
285  end() const
286  {
287  return const_iterator(&m_InternalArray[VDimension]);
288  }
289 
290  reverse_iterator
292  {
293  return reverse_iterator(end());
294  }
295 
296  const_reverse_iterator
297  rbegin() const
298  {
299  return const_reverse_iterator(end());
300  }
301 
302  reverse_iterator
304  {
305  return reverse_iterator(begin());
306  }
307 
308  const_reverse_iterator
309  rend() const
310  {
311  return const_reverse_iterator(begin());
312  }
313 
314  constexpr size_type
315  size() const
316  {
317  return VDimension;
318  }
319 
320  constexpr size_type
321  max_size() const
322  {
323  return VDimension;
324  }
325 
326  constexpr bool
327  empty() const
328  {
329  return false;
330  }
331 
332  reference operator[](size_type pos) { return m_InternalArray[pos]; }
333 
334  const_reference operator[](size_type pos) const { return m_InternalArray[pos]; }
335 
336  reference
338  {
339  ExceptionThrowingBoundsCheck(pos);
340  return m_InternalArray[pos];
341  }
342 
343  const_reference
344  at(size_type pos) const
345  {
346  ExceptionThrowingBoundsCheck(pos);
347  return m_InternalArray[pos];
348  }
349 
350  reference
352  {
353  return *begin();
354  }
355 
356  const_reference
357  front() const
358  {
359  return *begin();
360  }
361 
362  reference
364  {
365  return VDimension ? *(end() - 1) : *end();
366  }
367 
368  const_reference
369  back() const
370  {
371  return VDimension ? *(end() - 1) : *end();
372  }
373 
374  SizeValueType *
376  {
377  return &m_InternalArray[0];
378  }
379 
380  const SizeValueType *
381  data() const
382  {
383  return &m_InternalArray[0];
384  }
385 
386 private:
387  void
389  {
390  if (pos >= VDimension)
391  {
392  throw std::out_of_range("array::ExceptionThrowingBoundsCheck");
393  }
394  }
395 
396 public:
399  static Self
400  Filled(const SizeValueType value)
401  {
402  Self result;
403  result.Fill(value);
404  return result;
405  }
407 
408 }; //------------ End struct Size
409 
410 
411 template <unsigned int VDimension>
412 std::ostream &
413 operator<<(std::ostream & os, const Size<VDimension> & obj)
414 {
415  os << "[";
416  for (unsigned int i = 0; i + 1 < VDimension; ++i)
417  {
418  os << obj[i] << ", ";
419  }
420  if (VDimension >= 1)
421  {
422  os << obj[VDimension - 1];
423  }
424  os << "]";
425  return os;
426 }
427 
428 // ======================= Mirror the access pattern behavior of the std::array class
429 // Array comparisons.
430 template <unsigned int VDimension>
431 inline bool
433 {
434  return std::equal(one.begin(), one.end(), two.begin());
435 }
436 
437 template <unsigned int VDimension>
438 inline bool
440 {
441  return !(one == two);
442 }
443 
444 template <unsigned int VDimension>
445 inline bool
446 operator<(const Size<VDimension> & one, const Size<VDimension> & two)
447 {
448  return std::lexicographical_compare(one.begin(), one.end(), two.begin(), two.end());
449 }
450 
451 template <unsigned int VDimension>
452 inline bool
453 operator>(const Size<VDimension> & one, const Size<VDimension> & two)
454 {
455  return two < one;
456 }
457 
458 template <unsigned int VDimension>
459 inline bool
461 {
462  return !(one > two);
463 }
464 
465 template <unsigned int VDimension>
466 inline bool
468 {
469  return !(one < two);
470 }
471 
472 // Specialized algorithms [6.2.2.2].
473 template <unsigned int VDimension>
474 inline void
476 {
478 }
479 
480 // static constexpr definition explicitly needed in C++11
481 template <unsigned int VDimension>
482 constexpr unsigned int Size<VDimension>::Dimension;
483 
484 } // end namespace itk
485 
486 #endif
itk::Size::end
iterator end()
Definition: itkSize.h:279
itk::Size::begin
iterator begin()
Definition: itkSize.h:267
itk::Size::SetElement
void SetElement(unsigned long element, SizeValueType val)
Definition: itkSize.h:191
itk::Size::rbegin
reverse_iterator rbegin()
Definition: itkSize.h:291
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::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:218
itk::Size< Self::ImageDimension >::reference
value_type & reference
Definition: itkSize.h:241
itk::Size::ExceptionThrowingBoundsCheck
void ExceptionThrowingBoundsCheck(size_type pos) const
Definition: itkSize.h:388
itk::Size< Self::ImageDimension >::iterator
value_type * iterator
Definition: itkSize.h:243
itk::swap
void swap(Array< T > &a, Array< T > &b)
Definition: itkArray.h:244
itk::Size< Self::ImageDimension >::reverse_iterator
std::reverse_iterator< iterator > reverse_iterator
Definition: itkSize.h:247
itk::Size::end
const_iterator end() const
Definition: itkSize.h:285
itk::Size< Self::ImageDimension >::size_type
unsigned int size_type
Definition: itkSize.h:245
itk::Size::operator+=
const Self & operator+=(const Self &vec)
Definition: itkSize.h:107
itk::Size::back
const_reference back() const
Definition: itkSize.h:369
itk::Size::operator[]
reference operator[](size_type pos)
Definition: itkSize.h:332
itk::Size< Self::ImageDimension >::const_reference
const value_type & const_reference
Definition: itkSize.h:242
itk::Size::Fill
void Fill(SizeValueType value)
Definition: itkSize.h:211
itk::Size::rbegin
const_reverse_iterator rbegin() const
Definition: itkSize.h:297
itk::Size::rend
const_reverse_iterator rend() const
Definition: itkSize.h:309
itk::Size::GetSizeDimension
static constexpr unsigned int GetSizeDimension()
Definition: itkSize.h:87
itk::Size< Self::ImageDimension >::const_iterator
const value_type * const_iterator
Definition: itkSize.h:244
itkMacro.h
itk::Size::front
reference front()
Definition: itkSize.h:351
itk::Size< Self::ImageDimension >::const_reverse_iterator
std::reverse_iterator< const_iterator > const_reverse_iterator
Definition: itkSize.h:248
itk::Size::operator*=
const Self & operator*=(const Self &vec)
Definition: itkSize.h:156
itk::Size::back
reference back()
Definition: itkSize.h:363
itk::Size< Self::ImageDimension >::SizeValueType
::itk::SizeValueType SizeValueType
Definition: itkSize.h:80
itk::Size::assign
void assign(const value_type &newValue)
Definition: itkSize.h:255
itk::Size::operator-=
const Self & operator-=(const Self &vec)
Definition: itkSize.h:132
itk::operator>=
bool operator>=(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:567
itk::Size< Self::ImageDimension >::value_type
::itk::SizeValueType value_type
Definition: itkSize.h:240
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::Size::Filled
static Self Filled(const SizeValueType value)
Definition: itkSize.h:400
itkIntTypes.h
itk::Size::operator-
const Self operator-(const Self &vec) const
Definition: itkSize.h:119
itk::Size< Self::ImageDimension >::difference_type
std::ptrdiff_t difference_type
Definition: itkSize.h:246
itk::Size::SetSize
void SetSize(const SizeValueType val[VDimension])
Definition: itkSize.h:179
itk::Size::begin
const_iterator begin() const
Definition: itkSize.h:273
itk::Size::GetElement
SizeValueType GetElement(unsigned long element) const
Definition: itkSize.h:203
itk::Size::operator*
const Self operator*(const Self &vec) const
Definition: itkSize.h:143
itk::operator!=
bool operator!=(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:539
itk::Size::size
constexpr size_type size() const
Definition: itkSize.h:315
itk::Size::m_InternalArray
SizeValueType m_InternalArray[VDimension]
Definition: itkSize.h:230
itk
The "itk" namespace contains all Insight Segmentation and Registration Toolkit (ITK) classes....
Definition: itkAnnulusOperator.h:24
itk::swap
void swap(Size< VDimension > &one, Size< VDimension > &two)
Definition: itkSize.h:475
itk::Size::data
const SizeValueType * data() const
Definition: itkSize.h:381
itk::Size::empty
constexpr bool empty() const
Definition: itkSize.h:327
itk::Size::operator+
const Self operator+(const Self &vec) const
Definition: itkSize.h:94
itk::Size::swap
void swap(Size &other)
Definition: itkSize.h:261
itk::Size::operator[]
const_reference operator[](size_type pos) const
Definition: itkSize.h:334
itk::Size::front
const_reference front() const
Definition: itkSize.h:357
itk::Size::at
const_reference at(size_type pos) const
Definition: itkSize.h:344
itk::Size::data
SizeValueType * data()
Definition: itkSize.h:375
itk::Size::rend
reverse_iterator rend()
Definition: itkSize.h:303
itk::GTest::TypedefsAndConstructors::Dimension2::Dimension
constexpr unsigned int Dimension
Definition: itkGTestTypedefsAndConstructors.h:44
itk::Size::max_size
constexpr size_type max_size() const
Definition: itkSize.h:321
itk::Size::at
reference at(size_type pos)
Definition: itkSize.h:337
itk::Size::Dimension
static constexpr unsigned int Dimension
Definition: itkSize.h:83
itk::SizeValueType
unsigned long SizeValueType
Definition: itkIntTypes.h:83
itk::Size::GetSize
const SizeValueType * GetSize() const
Definition: itkSize.h:169