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