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