ITK  5.3.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  * https://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 "itkMakeFilled.h"
24 #include <algorithm> // For copy_n.
25 #include <type_traits> // For is_integral.
26 #include <memory>
27 
28 namespace itk
29 {
30 
69 template <unsigned int VDimension = 2>
70 struct ITK_TEMPLATE_EXPORT Size final
71 {
72 public:
73  // Using the `rule of zero` to this aggregate type
74  // C++20 changes the definition of aggregate such that classes with any user-declared ctors are no longer aggregates.
75 
77  using Self = Size;
78 
82 
84  static constexpr unsigned int Dimension = VDimension;
85 
87  static constexpr unsigned int
89  {
90  return VDimension;
91  }
92 
94  const Self
95  operator+(const Self & vec) const
96  {
97  Self result;
98 
99  for (unsigned int i = 0; i < VDimension; ++i)
100  {
101  result[i] = m_InternalArray[i] + vec.m_InternalArray[i];
102  }
103  return result;
104  }
105 
107  const Self &
108  operator+=(const Self & vec)
109  {
110  for (unsigned int i = 0; i < VDimension; ++i)
111  {
112  m_InternalArray[i] += vec.m_InternalArray[i];
113  }
114  return *this;
115  }
119  const Self
120  operator-(const Self & vec) const
121  {
122  Self result;
123 
124  for (unsigned int i = 0; i < VDimension; ++i)
125  {
126  result[i] = m_InternalArray[i] - vec.m_InternalArray[i];
127  }
128  return result;
129  }
130 
132  const Self &
133  operator-=(const Self & vec)
134  {
135  for (unsigned int i = 0; i < VDimension; ++i)
136  {
137  m_InternalArray[i] -= vec.m_InternalArray[i];
138  }
139  return *this;
140  }
144  const Self operator*(const Self & vec) const
145  {
146  Self result;
147 
148  for (unsigned int i = 0; i < VDimension; ++i)
149  {
150  result[i] = m_InternalArray[i] * vec.m_InternalArray[i];
151  }
152  return result;
153  }
154 
156  const Self &
157  operator*=(const Self & vec)
158  {
159  for (unsigned int i = 0; i < VDimension; ++i)
160  {
161  m_InternalArray[i] *= vec.m_InternalArray[i];
162  }
163  return *this;
164  }
169  const SizeValueType *
170  GetSize() const
171  {
172  return m_InternalArray;
173  }
174 
179  void
180  SetSize(const SizeValueType val[VDimension])
181  {
182  std::copy_n(val, VDimension, m_InternalArray);
183  }
184 
191  void
192  SetElement(unsigned long element, SizeValueType val)
193  {
194  m_InternalArray[element] = val;
195  }
196 
204  GetElement(unsigned long element) const
205  {
206  return m_InternalArray[element];
207  }
208 
211  void
213  {
214  std::fill_n(begin(), size(), value);
215  } // MATCH std::array assign, ITK Fill
216 
221  /*
222  * Ask the compiler to align a type to the maximum useful alignment for the target
223  * machine you are compiling for. Whenever you leave out the alignment factor in an
224  * aligned attribute specification, the compiler automatically sets the alignment
225  * for the type to the largest alignment that is ever used for any data type on
226  * the target machine you are compiling for. Doing this can often make copy
227  * operations more efficient, because the compiler can use whatever instructions
228  * copy the biggest chunks of memory when performing copies to or from the variables
229  * that have types that you have aligned this way.
230  */
231  static_assert(VDimension > 0, "Error: Only positive value sized VDimension allowed");
232  alignas(SizeValueType) SizeValueType m_InternalArray[VDimension];
235  // ======================= Mirror the access pattern behavior of the std::array class
243  using const_reference = const value_type &;
244  using iterator = value_type *;
245  using const_iterator = const value_type *;
246  using size_type = unsigned int;
247  using difference_type = ptrdiff_t;
248  using reverse_iterator = std::reverse_iterator<iterator>;
249  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
250 
255  void
256  assign(const value_type & newValue)
257  {
258  std::fill_n(begin(), size(), newValue);
259  }
260 
261  void
262  swap(Size & other)
263  {
264  std::swap(m_InternalArray, other.m_InternalArray);
265  }
266 
267  constexpr const_iterator
268  cbegin() const
269  {
270  return &m_InternalArray[0];
271  }
272 
273  constexpr iterator
275  {
276  return &m_InternalArray[0];
277  }
278 
279  constexpr const_iterator
280  begin() const
281  {
282  return &m_InternalArray[0];
283  }
284 
285  constexpr const_iterator
286  cend() const
287  {
288  return &m_InternalArray[VDimension];
289  }
290 
291  constexpr iterator
292  end()
293  {
294  return &m_InternalArray[VDimension];
295  }
296 
297  constexpr const_iterator
298  end() const
299  {
300  return &m_InternalArray[VDimension];
301  }
302 
303  reverse_iterator
305  {
306  return reverse_iterator(end());
307  }
308 
309  const_reverse_iterator
310  rbegin() const
311  {
312  return const_reverse_iterator(end());
313  }
314 
315  reverse_iterator
317  {
318  return reverse_iterator(begin());
319  }
320 
321  const_reverse_iterator
322  rend() const
323  {
324  return const_reverse_iterator(begin());
325  }
326 
327  constexpr size_type
328  size() const
329  {
330  return VDimension;
331  }
332 
333  constexpr size_type
334  max_size() const
335  {
336  return VDimension;
337  }
338 
339  constexpr bool
340  empty() const
341  {
342  return false;
343  }
344 
345  constexpr reference operator[](size_type pos) { return m_InternalArray[pos]; }
346 
347  constexpr const_reference operator[](size_type pos) const { return m_InternalArray[pos]; }
348 
349  reference
351  {
352  ExceptionThrowingBoundsCheck(pos);
353  return m_InternalArray[pos];
354  }
355 
356  const_reference
357  at(size_type pos) const
358  {
359  ExceptionThrowingBoundsCheck(pos);
360  return m_InternalArray[pos];
361  }
362 
363  reference
365  {
366  return *begin();
367  }
368 
369  const_reference
370  front() const
371  {
372  return *begin();
373  }
374 
375  reference
377  {
378  return VDimension ? *(end() - 1) : *end();
379  }
380 
381  const_reference
382  back() const
383  {
384  return VDimension ? *(end() - 1) : *end();
385  }
386 
387  SizeValueType *
389  {
390  return &m_InternalArray[0];
391  }
392 
393  const SizeValueType *
394  data() const
395  {
396  return &m_InternalArray[0];
397  }
398 
399 private:
400  void
402  {
403  if (pos >= VDimension)
404  {
405  throw std::out_of_range("array::ExceptionThrowingBoundsCheck");
406  }
407  }
408 
409 public:
412  static constexpr Self
413  Filled(const SizeValueType value)
414  {
415  return MakeFilled<Self>(value);
416  }
417 
418 }; //------------ End struct Size
419 
420 
421 template <unsigned int VDimension>
422 std::ostream &
423 operator<<(std::ostream & os, const Size<VDimension> & obj)
424 {
425  os << "[";
426  for (unsigned int i = 0; i + 1 < VDimension; ++i)
427  {
428  os << obj[i] << ", ";
429  }
430  if (VDimension >= 1)
431  {
432  os << obj[VDimension - 1];
433  }
434  os << "]";
435  return os;
436 }
437 
438 // ======================= Mirror the access pattern behavior of the std::array class
439 // Array comparisons.
440 template <unsigned int VDimension>
441 inline bool
443 {
444  return std::equal(one.begin(), one.end(), two.begin());
445 }
446 
447 template <unsigned int VDimension>
448 inline bool
450 {
451  return !(one == two);
452 }
453 
454 template <unsigned int VDimension>
455 inline bool
456 operator<(const Size<VDimension> & one, const Size<VDimension> & two)
457 {
458  return std::lexicographical_compare(one.begin(), one.end(), two.begin(), two.end());
459 }
460 
461 template <unsigned int VDimension>
462 inline bool
463 operator>(const Size<VDimension> & one, const Size<VDimension> & two)
464 {
465  return two < one;
466 }
467 
468 template <unsigned int VDimension>
469 inline bool
471 {
472  return !(one > two);
473 }
474 
475 template <unsigned int VDimension>
476 inline bool
478 {
479  return !(one < two);
480 }
481 
482 // Specialized algorithms [6.2.2.2].
483 template <unsigned int VDimension>
484 inline void
486 {
488 }
489 
490 
492 template <typename... T>
493 auto
494 MakeSize(const T... values)
495 {
496  const auto toValueType = [](const auto value) {
497  static_assert(std::is_integral<decltype(value)>::value, "Each value must have an integral type!");
498  return static_cast<SizeValueType>(value);
499  };
500  return Size<sizeof...(T)>{ { toValueType(values)... } };
501 }
505 // static constexpr definition explicitly needed in C++11
506 template <unsigned int VDimension>
507 constexpr unsigned int Size<VDimension>::Dimension;
508 
509 } // end namespace itk
510 
511 #endif
itk::Size::SetElement
void SetElement(unsigned long element, SizeValueType val)
Definition: itkSize.h:192
itk::Size::rbegin
reverse_iterator rbegin()
Definition: itkSize.h:304
itk::operator<
bool operator<(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:557
itk::Size< Self::ImageDimension >::difference_type
ptrdiff_t difference_type
Definition: itkSize.h:247
itk::operator<=
bool operator<=(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:571
itk::Size
Represent a n-dimensional size (bounds) of a n-dimensional image.
Definition: itkSize.h:70
itk::operator<<
std::ostream & operator<<(std::ostream &os, const Array< TValue > &arr)
Definition: itkArray.h:216
itk::Size< Self::ImageDimension >::reference
value_type & reference
Definition: itkSize.h:242
itk::Size::ExceptionThrowingBoundsCheck
void ExceptionThrowingBoundsCheck(size_type pos) const
Definition: itkSize.h:401
itk::Size< Self::ImageDimension >::iterator
value_type * iterator
Definition: itkSize.h:244
itk::MakeSize
auto MakeSize(const T... values)
Definition: itkSize.h:494
itk::swap
void swap(Array< T > &a, Array< T > &b)
Definition: itkArray.h:242
itk::Size< Self::ImageDimension >::SizeValueType
itk::SizeValueType SizeValueType
Definition: itkSize.h:81
itk::Size< Self::ImageDimension >::reverse_iterator
std::reverse_iterator< iterator > reverse_iterator
Definition: itkSize.h:248
itk::Size::Filled
static constexpr Self Filled(const SizeValueType value)
Definition: itkSize.h:413
itk::Size::begin
constexpr iterator begin()
Definition: itkSize.h:274
itk::Size< Self::ImageDimension >::size_type
unsigned int size_type
Definition: itkSize.h:246
itk::Size::operator+=
const Self & operator+=(const Self &vec)
Definition: itkSize.h:108
itk::Size::back
const_reference back() const
Definition: itkSize.h:382
itk::Size< Self::ImageDimension >::const_reference
const value_type & const_reference
Definition: itkSize.h:243
itk::Size::Fill
void Fill(SizeValueType value)
Definition: itkSize.h:212
itk::Size::end
constexpr iterator end()
Definition: itkSize.h:292
itk::Size::begin
constexpr const_iterator begin() const
Definition: itkSize.h:280
itk::Size::rbegin
const_reverse_iterator rbegin() const
Definition: itkSize.h:310
itk::Size::rend
const_reverse_iterator rend() const
Definition: itkSize.h:322
itk::Size::GetSizeDimension
static constexpr unsigned int GetSizeDimension()
Definition: itkSize.h:88
itk::Size< Self::ImageDimension >::const_iterator
const value_type * const_iterator
Definition: itkSize.h:245
itk::Size::operator[]
constexpr reference operator[](size_type pos)
Definition: itkSize.h:345
itkMacro.h
itk::Size::cend
constexpr const_iterator cend() const
Definition: itkSize.h:286
itk::Size::front
reference front()
Definition: itkSize.h:364
itk::Size< Self::ImageDimension >::const_reverse_iterator
std::reverse_iterator< const_iterator > const_reverse_iterator
Definition: itkSize.h:249
itk::Size::operator*=
const Self & operator*=(const Self &vec)
Definition: itkSize.h:157
itk::Size::back
reference back()
Definition: itkSize.h:376
itk::Size::assign
void assign(const value_type &newValue)
Definition: itkSize.h:256
itk::Size::operator-=
const Self & operator-=(const Self &vec)
Definition: itkSize.h:133
itk::Size::cbegin
constexpr const_iterator cbegin() const
Definition: itkSize.h:268
itk::operator>=
bool operator>=(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:578
itkMakeFilled.h
itk::operator>
bool operator>(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:564
itk::operator==
bool operator==(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:543
itkIntTypes.h
itk::Size::operator-
const Self operator-(const Self &vec) const
Definition: itkSize.h:120
itk::Size::operator[]
constexpr const_reference operator[](size_type pos) const
Definition: itkSize.h:347
itk::Size::SetSize
void SetSize(const SizeValueType val[VDimension])
Definition: itkSize.h:180
itk::Size::GetElement
SizeValueType GetElement(unsigned long element) const
Definition: itkSize.h:204
itk::Size::operator*
const Self operator*(const Self &vec) const
Definition: itkSize.h:144
itk::operator!=
bool operator!=(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:550
itk::Size::size
constexpr size_type size() const
Definition: itkSize.h:328
itk::Size::m_InternalArray
SizeValueType m_InternalArray[VDimension]
Definition: itkSize.h:231
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:485
itk::Size::data
const SizeValueType * data() const
Definition: itkSize.h:394
itk::Size::empty
constexpr bool empty() const
Definition: itkSize.h:340
itk::Size::operator+
const Self operator+(const Self &vec) const
Definition: itkSize.h:95
itk::Size::swap
void swap(Size &other)
Definition: itkSize.h:262
itk::Size< Self::ImageDimension >::value_type
itk::SizeValueType value_type
Definition: itkSize.h:241
itk::Size::front
const_reference front() const
Definition: itkSize.h:370
itk::Size::at
const_reference at(size_type pos) const
Definition: itkSize.h:357
itk::Size::data
SizeValueType * data()
Definition: itkSize.h:388
AddImageFilter
Definition: itkAddImageFilter.h:80
itk::Size::end
constexpr const_iterator end() const
Definition: itkSize.h:298
itk::Size::rend
reverse_iterator rend()
Definition: itkSize.h:316
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:334
itk::Size::at
reference at(size_type pos)
Definition: itkSize.h:350
itk::Size::Dimension
static constexpr unsigned int Dimension
Definition: itkSize.h:84
itk::SizeValueType
unsigned long SizeValueType
Definition: itkIntTypes.h:83
itk::Size::GetSize
const SizeValueType * GetSize() const
Definition: itkSize.h:170