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