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