ITK  5.0.0
Insight Segmentation and Registration Toolkit
itkSize.h
Go to the documentation of this file.
1 /*=========================================================================
2  *
3  * Copyright Insight Software Consortium
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  * http://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 <type_traits>
24 #include <memory>
25 
26 namespace itk
27 {
28 
66 
67 template <unsigned int VDimension = 2>
68 struct ITK_TEMPLATE_EXPORT Size final
69 {
70 public:
71  // Using the `rule of zero` to this aggregate type
72  // C++20 changes the definition of aggregate such that classes with any user-declared ctors are no longer aggregates.
73 
75  using Self = Size;
76 
80 
82  static constexpr unsigned int Dimension = VDimension;
83 
85  static constexpr unsigned int GetSizeDimension()
86  {
87  return VDimension;
88  }
89 
91  const Self operator+(const Self & vec) const
92  {
93  Self result;
94 
95  for( unsigned int i = 0; i < VDimension; i++ )
96  {
97  result[i] = m_InternalArray[i] + vec.m_InternalArray[i];
98  }
99  return result;
100  }
101 
103  const Self & operator+=(const Self & vec)
104  {
105  for( unsigned int i = 0; i < VDimension; i++ )
106  {
107  m_InternalArray[i] += vec.m_InternalArray[i];
108  }
109  return *this;
110  }
112 
114  const Self operator-(const Self & vec) const
115  {
116  Self result;
117 
118  for( unsigned int i = 0; i < VDimension; i++ )
119  {
120  result[i] = m_InternalArray[i] - vec.m_InternalArray[i];
121  }
122  return result;
123  }
124 
126  const Self & operator-=(const Self & vec)
127  {
128  for( unsigned int i = 0; i < VDimension; i++ )
129  {
130  m_InternalArray[i] -= vec.m_InternalArray[i];
131  }
132  return *this;
133  }
135 
137  const Self operator*(const Self & vec) const
138  {
139  Self result;
140 
141  for( unsigned int i = 0; i < VDimension; i++ )
142  {
143  result[i] = m_InternalArray[i] * vec.m_InternalArray[i];
144  }
145  return result;
146  }
147 
149  const Self & operator*=(const Self & vec)
150  {
151  for( unsigned int i = 0; i < VDimension; i++ )
152  {
153  m_InternalArray[i] *= vec.m_InternalArray[i];
154  }
155  return *this;
156  }
158 
161  const SizeValueType * GetSize() const
162  {
163  return m_InternalArray;
164  }
165 
170  void SetSize(const SizeValueType val[VDimension])
171  {
172  std::copy(val,
173  val + VDimension,
174  m_InternalArray);
175  }
176 
183  void SetElement(unsigned long element, SizeValueType val)
184  {
185  m_InternalArray[element] = val;
186  }
187 
194  SizeValueType GetElement(unsigned long element) const
195  {
196  return m_InternalArray[element];
197  }
198 
201  void Fill(SizeValueType value)
202  {
203  std::fill_n(begin(), size(), value);
204  } // MATCH std::array assign, ITK Fill
205 
210  /*
211  * Ask the compiler to align a type to the maximum useful alignment for the target
212  * machine you are compiling for. Whenever you leave out the alignment factor in an
213  * aligned attribute specification, the compiler automatically sets the alignment
214  * for the type to the largest alignment that is ever used for any data type on
215  * the target machine you are compiling for. Doing this can often make copy
216  * operations more efficient, because the compiler can use whatever instructions
217  * copy the biggest chunks of memory when performing copies to or from the variables
218  * that have types that you have aligned this way.
219  */
220  static_assert( VDimension > 0, "Error: Only positive value sized VDimension allowed" );
221  alignas(SizeValueType) SizeValueType m_InternalArray[VDimension];
223 
224  // ======================= Mirror the access pattern behavior of the std::array class
232  using const_reference = const value_type &;
233  using iterator = value_type *;
234  using const_iterator = const value_type *;
235  using size_type = unsigned int;
236  using difference_type = std::ptrdiff_t;
237  using reverse_iterator = std::reverse_iterator<iterator>;
238  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
239 
244  void assign(const value_type & newValue)
245  {
246  std::fill_n(begin(), size(), newValue);
247  }
248 
249  void swap(Size & other)
250  {
251  std::swap_ranges(begin(), end(), other.begin() );
252  }
253 
255  {
256  return iterator(&m_InternalArray[0]);
257  }
258 
260  {
261  return const_iterator(&m_InternalArray[0]);
262  }
263 
265  {
266  return iterator(&m_InternalArray[VDimension]);
267  }
268 
270  {
271  return const_iterator(&m_InternalArray[VDimension]);
272  }
273 
275  {
276  return reverse_iterator(end() );
277  }
278 
280  {
281  return const_reverse_iterator(end() );
282  }
283 
285  {
286  return reverse_iterator(begin() );
287  }
288 
290  {
291  return const_reverse_iterator(begin() );
292  }
293 
294  constexpr size_type size() const
295  {
296  return VDimension;
297  }
298 
299  constexpr size_type max_size() const
300  {
301  return VDimension;
302  }
303 
304  constexpr bool empty() const
305  {
306  return false;
307  }
308 
310  {
311  return m_InternalArray[pos];
312  }
313 
315  {
316  return m_InternalArray[pos];
317  }
318 
320  {
321  ExceptionThrowingBoundsCheck(pos); return m_InternalArray[pos];
322  }
323 
325  {
326  ExceptionThrowingBoundsCheck(pos); return m_InternalArray[pos];
327  }
328 
330  {
331  return *begin();
332  }
333 
335  {
336  return *begin();
337  }
338 
340  {
341  return VDimension ? *(end() - 1) : *end();
342  }
343 
345  {
346  return VDimension ? *(end() - 1) : *end();
347  }
348 
350  {
351  return &m_InternalArray[0];
352  }
353 
354  const SizeValueType * data() const
355  {
356  return &m_InternalArray[0];
357  }
358 
359 private:
361  {
362  if( pos >= VDimension )
363  {
364  throw std::out_of_range("array::ExceptionThrowingBoundsCheck");
365  }
366  }
367 
368 }; //------------ End struct Size
369 
370 
371 template <unsigned int VDimension>
372 std::ostream & operator<<(std::ostream & os, const Size<VDimension> & obj)
373 {
374  os << "[";
375  for( unsigned int i = 0; i + 1 < VDimension; ++i )
376  {
377  os << obj[i] << ", ";
378  }
379  if( VDimension >= 1 )
380  {
381  os << obj[VDimension - 1];
382  }
383  os << "]";
384  return os;
385 }
386 
387 // ======================= Mirror the access pattern behavior of the std::array class
388 // Array comparisons.
389 template <unsigned int VDimension>
390 inline bool
392 {
393  return std::equal(one.begin(), one.end(), two.begin() );
394 }
395 
396 template <unsigned int VDimension>
397 inline bool
399 {
400  return !(one == two);
401 }
402 
403 template <unsigned int VDimension>
404 inline bool
405 operator<(const Size<VDimension> & one, const Size<VDimension> & two)
406 {
407  return std::lexicographical_compare(one.begin(), one.end(),
408  two.begin(), two.end() );
409 }
410 
411 template <unsigned int VDimension>
412 inline bool
413 operator>(const Size<VDimension> & one, const Size<VDimension> & two)
414 {
415  return two < one;
416 }
417 
418 template <unsigned int VDimension>
419 inline bool
420 operator<=(const Size<VDimension> & one, const Size<VDimension> & two)
421 {
422  return !(one > two);
423 }
424 
425 template <unsigned int VDimension>
426 inline bool
428 {
429  return !(one < two);
430 }
431 
432 // Specialized algorithms [6.2.2.2].
433 template <unsigned int VDimension>
434 inline void
436 {
437  std::swap_ranges(one.begin(), one.end(), two.begin() );
438 }
439 
440 // static constexpr definition explicitly needed in C++11
441 template< unsigned int VDimension >
442 constexpr unsigned int Size<VDimension>::Dimension;
443 
444 } // end namespace itk
445 
446 #endif
void assign(const value_type &newValue)
Definition: itkSize.h:244
::itk::SizeValueType value_type
Definition: itkSize.h:230
bool operator==(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:485
constexpr size_type size() const
Definition: itkSize.h:294
constexpr size_type max_size() const
Definition: itkSize.h:299
const Self & operator*=(const Self &vec)
Definition: itkSize.h:149
void swap(Size &other)
Definition: itkSize.h:249
static constexpr unsigned int GetSizeDimension()
Definition: itkSize.h:85
reference operator[](size_type pos)
Definition: itkSize.h:309
unsigned long SizeValueType
Definition: itkIntTypes.h:83
reference at(size_type pos)
Definition: itkSize.h:319
const Self & operator-=(const Self &vec)
Definition: itkSize.h:126
const_reverse_iterator rend() const
Definition: itkSize.h:289
const_iterator end() const
Definition: itkSize.h:269
const Self operator+(const Self &vec) const
Definition: itkSize.h:91
const Self & operator+=(const Self &vec)
Definition: itkSize.h:103
SizeValueType m_InternalArray[VDimension]
Definition: itkSize.h:220
bool operator>(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:507
const value_type * const_iterator
Definition: itkSize.h:234
iterator end()
Definition: itkSize.h:264
const_reference at(size_type pos) const
Definition: itkSize.h:324
const_iterator begin() const
Definition: itkSize.h:259
const SizeValueType * data() const
Definition: itkSize.h:354
void swap(Array< T > &a, Array< T > &b)
Definition: itkArray.h:211
SizeValueType * data()
Definition: itkSize.h:349
reverse_iterator rbegin()
Definition: itkSize.h:274
bool operator!=(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:492
const_reference back() const
Definition: itkSize.h:344
reference front()
Definition: itkSize.h:329
const SizeValueType * GetSize() const
Definition: itkSize.h:161
void ExceptionThrowingBoundsCheck(size_type pos) const
Definition: itkSize.h:360
std::ptrdiff_t difference_type
Definition: itkSize.h:236
Represent a n-dimensional size (bounds) of a n-dimensional image.
Definition: itkSize.h:68
const value_type & const_reference
Definition: itkSize.h:232
const Self operator*(const Self &vec) const
Definition: itkSize.h:137
std::reverse_iterator< iterator > reverse_iterator
Definition: itkSize.h:237
const_reference front() const
Definition: itkSize.h:334
const_reference operator[](size_type pos) const
Definition: itkSize.h:314
std::reverse_iterator< const_iterator > const_reverse_iterator
Definition: itkSize.h:238
::itk::SizeValueType SizeValueType
Definition: itkSize.h:79
reference back()
Definition: itkSize.h:339
void SetElement(unsigned long element, SizeValueType val)
Definition: itkSize.h:183
iterator begin()
Definition: itkSize.h:254
const Self operator-(const Self &vec) const
Definition: itkSize.h:114
void SetSize(const SizeValueType val[VDimension])
Definition: itkSize.h:170
void Fill(SizeValueType value)
Definition: itkSize.h:201
reverse_iterator rend()
Definition: itkSize.h:284
bool operator>=(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:521
constexpr bool empty() const
Definition: itkSize.h:304
SizeValueType GetElement(unsigned long element) const
Definition: itkSize.h:194
const_reverse_iterator rbegin() const
Definition: itkSize.h:279