ITK  6.0.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 
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  }
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  }
143  const Self
144  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 
218  [[nodiscard]] constexpr SizeValueType
220  {
221  SizeValueType product{ 1 };
222 
223  for (const SizeValueType value : m_InternalArray)
224  {
225  product *= value;
226  }
227  return product;
228  }
229 
234  /*
235  * Ask the compiler to align a type to the maximum useful alignment for the target
236  * machine you are compiling for. Whenever you leave out the alignment factor in an
237  * aligned attribute specification, the compiler automatically sets the alignment
238  * for the type to the largest alignment that is ever used for any data type on
239  * the target machine you are compiling for. Doing this can often make copy
240  * operations more efficient, because the compiler can use whatever instructions
241  * copy the biggest chunks of memory when performing copies to or from the variables
242  * that have types that you have aligned this way.
243  */
244  static_assert(VDimension > 0, "Error: Only positive value sized VDimension allowed");
245  alignas(SizeValueType) SizeValueType m_InternalArray[VDimension];
248  // ======================= Mirror the access pattern behavior of the std::array class
256  using const_reference = const value_type &;
257  using iterator = value_type *;
258  using const_iterator = const value_type *;
259  using size_type = unsigned int;
260  using difference_type = ptrdiff_t;
261  using reverse_iterator = std::reverse_iterator<iterator>;
262  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
263 
268  void
269  assign(const value_type & newValue)
270  {
271  std::fill_n(begin(), size(), newValue);
272  }
273 
274  void
275  swap(Size & other) noexcept
276  {
277  std::swap(m_InternalArray, other.m_InternalArray);
278  }
279 
280  constexpr const_iterator
281  cbegin() const
282  {
283  return &m_InternalArray[0];
284  }
285 
286  constexpr iterator
288  {
289  return &m_InternalArray[0];
290  }
291 
292  constexpr const_iterator
293  begin() const
294  {
295  return &m_InternalArray[0];
296  }
297 
298  constexpr const_iterator
299  cend() const
300  {
301  return &m_InternalArray[VDimension];
302  }
303 
304  constexpr iterator
305  end()
306  {
307  return &m_InternalArray[VDimension];
308  }
309 
310  constexpr const_iterator
311  end() const
312  {
313  return &m_InternalArray[VDimension];
314  }
315 
316  reverse_iterator
318  {
319  return reverse_iterator(end());
320  }
321 
322  const_reverse_iterator
323  rbegin() const
324  {
325  return const_reverse_iterator(end());
326  }
327 
328  reverse_iterator
330  {
331  return reverse_iterator(begin());
332  }
333 
334  const_reverse_iterator
335  rend() const
336  {
337  return const_reverse_iterator(begin());
338  }
339 
340  constexpr size_type
341  size() const
342  {
343  return VDimension;
344  }
345 
346  constexpr size_type
347  max_size() const
348  {
349  return VDimension;
350  }
351 
352  constexpr bool
353  empty() const
354  {
355  return false;
356  }
357 
358  constexpr reference
360  {
361  return m_InternalArray[pos];
362  }
363 
364  constexpr const_reference
366  {
367  return m_InternalArray[pos];
368  }
369 
370  reference
372  {
373  ExceptionThrowingBoundsCheck(pos);
374  return m_InternalArray[pos];
375  }
376 
377  const_reference
378  at(size_type pos) const
379  {
380  ExceptionThrowingBoundsCheck(pos);
381  return m_InternalArray[pos];
382  }
383 
384  constexpr reference
386  {
387  return *begin();
388  }
389 
390  constexpr const_reference
391  front() const
392  {
393  return *begin();
394  }
395 
396  constexpr reference
398  {
399  return VDimension ? *(end() - 1) : *end();
400  }
401 
402  constexpr const_reference
403  back() const
404  {
405  return VDimension ? *(end() - 1) : *end();
406  }
407 
408  SizeValueType *
410  {
411  return &m_InternalArray[0];
412  }
413 
414  const SizeValueType *
415  data() const
416  {
417  return &m_InternalArray[0];
418  }
419 
420 private:
421  void
423  {
424  if (pos >= VDimension)
425  {
426  throw std::out_of_range("array::ExceptionThrowingBoundsCheck");
427  }
428  }
429 
430 public:
433  static constexpr Self
434  Filled(const SizeValueType value)
435  {
436  return MakeFilled<Self>(value);
437  }
438 
439 }; //------------ End struct Size
440 
441 
442 template <unsigned int VDimension>
443 std::ostream &
444 operator<<(std::ostream & os, const Size<VDimension> & obj)
445 {
446  os << '[';
447  for (unsigned int i = 0; i + 1 < VDimension; ++i)
448  {
449  os << obj[i] << ", ";
450  }
451  if constexpr (VDimension >= 1)
452  {
453  os << obj[VDimension - 1];
454  }
455  os << ']';
456  return os;
457 }
458 
459 // ======================= Mirror the access pattern behavior of the std::array class
460 // Array comparisons.
461 template <unsigned int VDimension>
462 inline bool
464 {
465  return std::equal(one.begin(), one.end(), two.begin());
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
477 operator<(const Size<VDimension> & one, const Size<VDimension> & two)
478 {
479  return std::lexicographical_compare(one.begin(), one.end(), two.begin(), two.end());
480 }
481 
482 template <unsigned int VDimension>
483 inline bool
484 operator>(const Size<VDimension> & one, const Size<VDimension> & two)
485 {
486  return two < one;
487 }
488 
489 template <unsigned int VDimension>
490 inline bool
492 {
493  return !(one > two);
494 }
495 
496 template <unsigned int VDimension>
497 inline bool
499 {
500  return !(one < two);
501 }
502 
503 // Specialized algorithms [6.2.2.2].
504 template <unsigned int VDimension>
505 inline void
506 swap(Size<VDimension> & one, Size<VDimension> & two) noexcept
507 {
508  std::swap(one.m_InternalArray, two.m_InternalArray);
509 }
510 
511 
513 template <typename... T>
514 auto
515 MakeSize(const T... values)
516 {
517  const auto toValueType = [](const auto value) {
518  static_assert(std::is_integral_v<decltype(value)>, "Each value must have an integral type!");
519  return static_cast<SizeValueType>(value);
520  };
521  return Size<sizeof...(T)>{ { toValueType(values)... } };
522 }
525 } // end namespace itk
526 
527 #endif
itk::Size::front
constexpr const_reference front() const
Definition: itkSize.h:391
itk::Size::CalculateProductOfElements
constexpr SizeValueType CalculateProductOfElements() const
Definition: itkSize.h:219
itk::Size::SetElement
void SetElement(unsigned long element, SizeValueType val)
Definition: itkSize.h:192
itk::Size::rbegin
reverse_iterator rbegin()
Definition: itkSize.h:317
itk::operator<
bool operator<(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:566
itk::Size< Self::OutputImageDimension >::difference_type
ptrdiff_t difference_type
Definition: itkSize.h:260
itk::Size::back
constexpr const_reference back() const
Definition: itkSize.h:403
itk::operator<=
bool operator<=(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:580
itk::Size
Represent a n-dimensional size (bounds) of a n-dimensional image.
Definition: itkSize.h:69
itk::Size< Self::OutputImageDimension >::reference
value_type & reference
Definition: itkSize.h:255
itk::Size::ExceptionThrowingBoundsCheck
void ExceptionThrowingBoundsCheck(size_type pos) const
Definition: itkSize.h:422
itk::Size< Self::OutputImageDimension >::iterator
value_type * iterator
Definition: itkSize.h:257
itk::MakeSize
auto MakeSize(const T... values)
Definition: itkSize.h:515
itk::Size< Self::OutputImageDimension >::SizeValueType
itk::SizeValueType SizeValueType
Definition: itkSize.h:80
itk::Size< Self::OutputImageDimension >::reverse_iterator
std::reverse_iterator< iterator > reverse_iterator
Definition: itkSize.h:261
itk::Size::Filled
static constexpr Self Filled(const SizeValueType value)
Definition: itkSize.h:434
itk::Size::begin
constexpr iterator begin()
Definition: itkSize.h:287
itk::Size::front
constexpr reference front()
Definition: itkSize.h:385
itk::operator<<
ITKCommon_EXPORT std::ostream & operator<<(std::ostream &out, typename AnatomicalOrientation::CoordinateEnum value)
itk::Size< Self::OutputImageDimension >::size_type
unsigned int size_type
Definition: itkSize.h:259
itk::Size::swap
void swap(Size &other) noexcept
Definition: itkSize.h:275
itk::Size::operator+=
const Self & operator+=(const Self &vec)
Definition: itkSize.h:107
itk::Size< Self::OutputImageDimension >::const_reference
const value_type & const_reference
Definition: itkSize.h:256
itk::Size::Fill
void Fill(SizeValueType value)
Definition: itkSize.h:212
itk::Size::end
constexpr iterator end()
Definition: itkSize.h:305
itk::Size::begin
constexpr const_iterator begin() const
Definition: itkSize.h:293
itk::Size::rbegin
const_reverse_iterator rbegin() const
Definition: itkSize.h:323
itk::Size::rend
const_reverse_iterator rend() const
Definition: itkSize.h:335
itk::Size::GetSizeDimension
static constexpr unsigned int GetSizeDimension()
Definition: itkSize.h:87
itk::Size< Self::OutputImageDimension >::const_iterator
const value_type * const_iterator
Definition: itkSize.h:258
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:299
itk::Size< Self::OutputImageDimension >::const_reverse_iterator
std::reverse_iterator< const_iterator > const_reverse_iterator
Definition: itkSize.h:262
itk::Size::operator*=
const Self & operator*=(const Self &vec)
Definition: itkSize.h:157
itk::Size::assign
void assign(const value_type &newValue)
Definition: itkSize.h:269
itk::Size::operator-=
const Self & operator-=(const Self &vec)
Definition: itkSize.h:132
itk::Size::cbegin
constexpr const_iterator cbegin() const
Definition: itkSize.h:281
itk::operator>=
bool operator>=(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:587
itkMakeFilled.h
itk::operator>
bool operator>(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:573
itk::operator==
bool operator==(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:552
itkIntTypes.h
itk::Size::operator-
const Self operator-(const Self &vec) const
Definition: itkSize.h:119
itk::Size::operator[]
constexpr const_reference operator[](size_type pos) const
Definition: itkSize.h:365
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:559
itk::Size::size
constexpr size_type size() const
Definition: itkSize.h:341
itk::Size::m_InternalArray
SizeValueType m_InternalArray[VDimension]
Definition: itkSize.h:244
itk::swap
void swap(Array< T > &a, Array< T > &b) noexcept
Definition: itkArray.h:242
itk
The "itk" namespace contains all Insight Segmentation and Registration Toolkit (ITK) classes....
Definition: itkAnatomicalOrientation.h:29
itk::Size::data
const SizeValueType * data() const
Definition: itkSize.h:415
itk::Size::empty
constexpr bool empty() const
Definition: itkSize.h:353
itk::Size::operator+
const Self operator+(const Self &vec) const
Definition: itkSize.h:94
itk::Size< Self::OutputImageDimension >::value_type
itk::SizeValueType value_type
Definition: itkSize.h:254
itk::Size::at
const_reference at(size_type pos) const
Definition: itkSize.h:378
itk::Size::data
SizeValueType * data()
Definition: itkSize.h:409
AddImageFilter
Definition: itkAddImageFilter.h:81
itk::Size::back
constexpr reference back()
Definition: itkSize.h:397
itk::Size::end
constexpr const_iterator end() const
Definition: itkSize.h:311
itk::Size::rend
reverse_iterator rend()
Definition: itkSize.h:329
itk::swap
void swap(Size< VDimension > &one, Size< VDimension > &two) noexcept
Definition: itkSize.h:506
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:347
itk::Size::at
reference at(size_type pos)
Definition: itkSize.h:371
itk::SizeValueType
unsigned long SizeValueType
Definition: itkIntTypes.h:86
itk::Size::GetSize
const SizeValueType * GetSize() const
Definition: itkSize.h:170