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