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
29namespace itk
30{
31
68template <unsigned int VDimension = 2>
69struct ITK_TEMPLATE_EXPORT Size final
70{
71public:
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
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
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
401 {
402 return &m_InternalArray[0];
403 }
404
405 const SizeValueType *
406 data() const
407 {
408 return &m_InternalArray[0];
409 }
410
411private:
412 void
414 {
415 if (pos >= VDimension)
416 {
417 throw std::out_of_range("array::ExceptionThrowingBoundsCheck");
418 }
419 }
420
421public:
424 static constexpr Self
426 {
427 return MakeFilled<Self>(value);
428 }
429
430}; //------------ End struct Size
431
432
433template <unsigned int VDimension>
434std::ostream &
435operator<<(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.
452template <unsigned int VDimension>
453inline bool
455{
456 return std::equal(one.begin(), one.end(), two.begin());
457}
458
459template <unsigned int VDimension>
460inline bool
462{
463 return !(one == two);
464}
465
466template <unsigned int VDimension>
467inline bool
468operator<(const Size<VDimension> & one, const Size<VDimension> & two)
469{
470 return std::lexicographical_compare(one.begin(), one.end(), two.begin(), two.end());
471}
472
473template <unsigned int VDimension>
474inline bool
476{
477 return two < one;
478}
479
480template <unsigned int VDimension>
481inline bool
482operator<=(const Size<VDimension> & one, const Size<VDimension> & two)
483{
484 return !(one > two);
485}
486
487template <unsigned int VDimension>
488inline bool
490{
491 return !(one < two);
492}
493
494// Specialized algorithms [6.2.2.2].
495template <unsigned int VDimension>
496inline void
498{
500}
501
502
504template <typename... T>
505auto
506MakeSize(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
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:497
void swap(Array< T > &a, Array< T > &b) noexcept
Definition: itkArray.h:242
bool operator>(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:564
ITKCommon_EXPORT std::ostream & operator<<(std::ostream &out, typename AnatomicalOrientation::CoordinateEnum value)
bool operator<=(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:571
bool operator==(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:543
auto MakeSize(const T... values)
Definition: itkSize.h:506
bool operator!=(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:550
unsigned long SizeValueType
Definition: itkIntTypes.h:86
bool operator<(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:557
bool operator>=(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:578
Represent a n-dimensional size (bounds) of a n-dimensional image.
Definition: itkSize.h:70
constexpr const_iterator end() const
Definition: itkSize.h:310
const value_type * const_iterator
Definition: itkSize.h:257
constexpr iterator begin()
Definition: itkSize.h:286
std::reverse_iterator< const_iterator > const_reverse_iterator
Definition: itkSize.h:261
constexpr const_reference back() const
Definition: itkSize.h:394
const Self operator-(const Self &vec) const
Definition: itkSize.h:119
unsigned int size_type
Definition: itkSize.h:258
constexpr size_type max_size() const
Definition: itkSize.h:346
constexpr size_type size() const
Definition: itkSize.h:340
SizeValueType * data()
Definition: itkSize.h:400
const_reference at(size_type pos) const
Definition: itkSize.h:369
constexpr const_iterator cend() const
Definition: itkSize.h:298
itk::SizeValueType SizeValueType
Definition: itkSize.h:80
const SizeValueType * GetSize() const
Definition: itkSize.h:169
const Self & operator-=(const Self &vec)
Definition: itkSize.h:132
void SetSize(const SizeValueType val[VDimension])
Definition: itkSize.h:179
SizeValueType GetElement(unsigned long element) const
Definition: itkSize.h:203
constexpr const_reference front() const
Definition: itkSize.h:382
const SizeValueType * data() const
Definition: itkSize.h:406
constexpr iterator end()
Definition: itkSize.h:304
constexpr reference operator[](size_type pos)
Definition: itkSize.h:357
constexpr const_iterator begin() const
Definition: itkSize.h:292
const Self & operator*=(const Self &vec)
Definition: itkSize.h:156
void Fill(SizeValueType value)
Definition: itkSize.h:211
const Self operator*(const Self &vec) const
Definition: itkSize.h:143
value_type * iterator
Definition: itkSize.h:256
reverse_iterator rend()
Definition: itkSize.h:328
void assign(const value_type &newValue)
Definition: itkSize.h:268
constexpr reference back()
Definition: itkSize.h:388
const Self operator+(const Self &vec) const
Definition: itkSize.h:94
void SetElement(unsigned long element, SizeValueType val)
Definition: itkSize.h:191
constexpr const_iterator cbegin() const
Definition: itkSize.h:280
static constexpr unsigned int GetSizeDimension()
Definition: itkSize.h:87
std::reverse_iterator< iterator > reverse_iterator
Definition: itkSize.h:260
constexpr SizeValueType CalculateProductOfElements() const
Definition: itkSize.h:218
constexpr const_reference operator[](size_type pos) const
Definition: itkSize.h:359
constexpr bool empty() const
Definition: itkSize.h:352
constexpr reference front()
Definition: itkSize.h:376
const value_type & const_reference
Definition: itkSize.h:255
itk::SizeValueType value_type
Definition: itkSize.h:253
void ExceptionThrowingBoundsCheck(size_type pos) const
Definition: itkSize.h:413
ptrdiff_t difference_type
Definition: itkSize.h:259
const Self & operator+=(const Self &vec)
Definition: itkSize.h:107
SizeValueType m_InternalArray[VDimension]
Definition: itkSize.h:243
void swap(Size &other)
Definition: itkSize.h:274
reference at(size_type pos)
Definition: itkSize.h:362
static constexpr Self Filled(const SizeValueType value)
Definition: itkSize.h:425
const_reverse_iterator rbegin() const
Definition: itkSize.h:322
value_type & reference
Definition: itkSize.h:254
reverse_iterator rbegin()
Definition: itkSize.h:316
const_reverse_iterator rend() const
Definition: itkSize.h:334