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
29namespace itk
30{
31
70template <unsigned int VDimension = 2>
71struct ITK_TEMPLATE_EXPORT Size final
72{
73public:
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
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
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
403 {
404 return &m_InternalArray[0];
405 }
406
407 const SizeValueType *
408 data() const
409 {
410 return &m_InternalArray[0];
411 }
412
413private:
414 void
416 {
417 if (pos >= VDimension)
418 {
419 throw std::out_of_range("array::ExceptionThrowingBoundsCheck");
420 }
421 }
422
423public:
426 static constexpr Self
428 {
429 return MakeFilled<Self>(value);
430 }
431
432}; //------------ End struct Size
433
434
435template <unsigned int VDimension>
436std::ostream &
437operator<<(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.
454template <unsigned int VDimension>
455inline bool
457{
458 return std::equal(one.begin(), one.end(), two.begin());
459}
460
461template <unsigned int VDimension>
462inline bool
464{
465 return !(one == two);
466}
467
468template <unsigned int VDimension>
469inline bool
470operator<(const Size<VDimension> & one, const Size<VDimension> & two)
471{
472 return std::lexicographical_compare(one.begin(), one.end(), two.begin(), two.end());
473}
474
475template <unsigned int VDimension>
476inline bool
478{
479 return two < one;
480}
481
482template <unsigned int VDimension>
483inline bool
484operator<=(const Size<VDimension> & one, const Size<VDimension> & two)
485{
486 return !(one > two);
487}
488
489template <unsigned int VDimension>
490inline bool
492{
493 return !(one < two);
494}
495
496// Specialized algorithms [6.2.2.2].
497template <unsigned int VDimension>
498inline void
500{
502}
503
504
506template <typename... T>
507auto
508MakeSize(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
Pixel-wise addition of two images.
The "itk" namespace contains all Insight Segmentation and Registration Toolkit (ITK) classes....
void swap(Size< VDimension > &one, Size< VDimension > &two)
Definition: itkSize.h:499
bool operator>(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:566
void swap(Array< T > &a, Array< T > &b)
Definition: itkArray.h:242
bool operator<=(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:573
bool operator==(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:545
std::ostream & operator<<(std::ostream &os, const Array< TValue > &arr)
Definition: itkArray.h:216
auto MakeSize(const T... values)
Definition: itkSize.h:508
bool operator!=(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:552
unsigned long SizeValueType
Definition: itkIntTypes.h:83
bool operator<(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:559
bool operator>=(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:580
Represent a n-dimensional size (bounds) of a n-dimensional image.
Definition: itkSize.h:72
constexpr const_iterator end() const
Definition: itkSize.h:312
const value_type * const_iterator
Definition: itkSize.h:259
constexpr iterator begin()
Definition: itkSize.h:288
std::reverse_iterator< const_iterator > const_reverse_iterator
Definition: itkSize.h:263
const Self operator-(const Self &vec) const
Definition: itkSize.h:121
const_reference front() const
Definition: itkSize.h:384
unsigned int size_type
Definition: itkSize.h:260
constexpr size_type max_size() const
Definition: itkSize.h:348
const_reference back() const
Definition: itkSize.h:396
constexpr size_type size() const
Definition: itkSize.h:342
SizeValueType * data()
Definition: itkSize.h:402
const_reference at(size_type pos) const
Definition: itkSize.h:371
constexpr const_iterator cend() const
Definition: itkSize.h:300
itk::SizeValueType SizeValueType
Definition: itkSize.h:82
const SizeValueType * GetSize() const
Definition: itkSize.h:171
const Self & operator-=(const Self &vec)
Definition: itkSize.h:134
void SetSize(const SizeValueType val[VDimension])
Definition: itkSize.h:181
SizeValueType GetElement(unsigned long element) const
Definition: itkSize.h:205
const SizeValueType * data() const
Definition: itkSize.h:408
constexpr iterator end()
Definition: itkSize.h:306
constexpr reference operator[](size_type pos)
Definition: itkSize.h:359
constexpr const_iterator begin() const
Definition: itkSize.h:294
const Self & operator*=(const Self &vec)
Definition: itkSize.h:158
void Fill(SizeValueType value)
Definition: itkSize.h:213
const Self operator*(const Self &vec) const
Definition: itkSize.h:145
reference back()
Definition: itkSize.h:390
value_type * iterator
Definition: itkSize.h:258
reverse_iterator rend()
Definition: itkSize.h:330
void assign(const value_type &newValue)
Definition: itkSize.h:270
const Self operator+(const Self &vec) const
Definition: itkSize.h:96
void SetElement(unsigned long element, SizeValueType val)
Definition: itkSize.h:193
constexpr const_iterator cbegin() const
Definition: itkSize.h:282
static constexpr unsigned int GetSizeDimension()
Definition: itkSize.h:89
std::reverse_iterator< iterator > reverse_iterator
Definition: itkSize.h:262
constexpr SizeValueType CalculateProductOfElements() const
Definition: itkSize.h:220
constexpr const_reference operator[](size_type pos) const
Definition: itkSize.h:361
constexpr bool empty() const
Definition: itkSize.h:354
reference front()
Definition: itkSize.h:378
const value_type & const_reference
Definition: itkSize.h:257
itk::SizeValueType value_type
Definition: itkSize.h:255
void ExceptionThrowingBoundsCheck(size_type pos) const
Definition: itkSize.h:415
ptrdiff_t difference_type
Definition: itkSize.h:261
const Self & operator+=(const Self &vec)
Definition: itkSize.h:109
SizeValueType m_InternalArray[VDimension]
Definition: itkSize.h:245
void swap(Size &other)
Definition: itkSize.h:276
reference at(size_type pos)
Definition: itkSize.h:364
static constexpr Self Filled(const SizeValueType value)
Definition: itkSize.h:427
const_reverse_iterator rbegin() const
Definition: itkSize.h:324
value_type & reference
Definition: itkSize.h:256
reverse_iterator rbegin()
Definition: itkSize.h:318
const_reverse_iterator rend() const
Definition: itkSize.h:336