ITK  5.4.0
Insight Toolkit
itkOffset.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 itkOffset_h
19#define itkOffset_h
20
21#include "itkSize.h"
22#include "itkMath.h"
23
24#include <cstddef> // For ptrdiff_t.
25
26namespace itk
27{
28
68template <unsigned int VDimension = 2>
69struct ITK_TEMPLATE_EXPORT Offset 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 = Offset;
77
81
83 static constexpr unsigned int Dimension = VDimension;
84
86 static constexpr unsigned int
88 {
89 return VDimension;
90 }
91
92
94 const Self
95 operator+(const Self & vec) const
96 {
97 Self result;
98
99 for (unsigned int i = 0; i < VDimension; ++i)
100 {
101 result[i] = m_InternalArray[i] + vec.m_InternalArray[i];
102 }
103 return result;
104 }
105
107 const Self
108 operator+(const Size<VDimension> & sz) const
109 {
110 Self result;
111
112 for (unsigned int i = 0; i < VDimension; ++i)
113 {
114 result[i] = m_InternalArray[i] + sz[i];
115 }
116 return result;
117 }
118
120 const Self &
122 {
123 for (unsigned int i = 0; i < VDimension; ++i)
124 {
125 m_InternalArray[i] += sz[i];
126 }
127 return *this;
128 }
132 const Self &
134 {
135 for (unsigned int i = 0; i < VDimension; ++i)
136 {
137 m_InternalArray[i] -= sz[i];
138 }
139 return *this;
140 }
144 const Self
145 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 }
169 const Self &
170 operator-=(const Self & vec)
171 {
172 for (unsigned int i = 0; i < VDimension; ++i)
173 {
174 m_InternalArray[i] -= vec.m_InternalArray[i];
175 }
176 return *this;
177 }
183 const OffsetValueType *
184 GetOffset() const
185 {
186 return m_InternalArray;
187 }
188
193 void
194 SetOffset(const OffsetValueType val[VDimension])
195 {
196 std::copy_n(val, VDimension, m_InternalArray);
197 }
198
205 void
206 SetElement(unsigned long element, OffsetValueType val)
207 {
208 m_InternalArray[element] = val;
209 }
210
218 GetElement(unsigned long element) const
219 {
220 return m_InternalArray[element];
221 }
222
225 void
227 {
228 std::fill_n(begin(), size(), value);
229 } // MATCH std::array assign, ITK Fill
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(OffsetValueType) OffsetValueType m_InternalArray[VDimension];
250 template <typename TCoordRep>
251 inline void
253 {
254 for (unsigned int i = 0; i < VDimension; ++i)
255 {
256 m_InternalArray[i] = Math::Round<OffsetValueType>(point[i]);
257 }
258 }
262 template <typename TCoordRep>
263 inline void
265 {
266 for (unsigned int i = 0; i < VDimension; ++i)
267 {
268 m_InternalArray[i] = static_cast<OffsetValueType>(point[i]);
269 }
270 }
276 static Self
277 GetBasisOffset(unsigned int dim);
278
279
280 // ======================= Mirror the access pattern behavior of the std::array class
290 using const_iterator = const value_type *;
291 using size_type = unsigned int;
292 using difference_type = ptrdiff_t;
293 using reverse_iterator = std::reverse_iterator<iterator>;
294 using const_reverse_iterator = std::reverse_iterator<const_iterator>;
295
300 void
301 assign(const value_type & newValue)
302 {
303 std::fill_n(begin(), size(), newValue);
304 }
305
306 void
307 swap(Offset & other)
308 {
309 std::swap(m_InternalArray, other.m_InternalArray);
310 }
311
312 constexpr const_iterator
313 cbegin() const
314 {
315 return &m_InternalArray[0];
316 }
317
318 constexpr iterator
320 {
321 return &m_InternalArray[0];
322 }
323
324 constexpr const_iterator
325 begin() const
326 {
327 return &m_InternalArray[0];
328 }
329
330 constexpr const_iterator
331 cend() const
332 {
333 return &m_InternalArray[VDimension];
334 }
335
336 constexpr iterator
338 {
339 return &m_InternalArray[VDimension];
340 }
341
342 constexpr const_iterator
343 end() const
344 {
345 return &m_InternalArray[VDimension];
346 }
347
348 reverse_iterator
350 {
351 return reverse_iterator(end());
352 }
353
354 const_reverse_iterator
355 rbegin() const
356 {
357 return const_reverse_iterator(end());
358 }
359
360 reverse_iterator
362 {
363 return reverse_iterator(begin());
364 }
365
366 const_reverse_iterator
367 rend() const
368 {
369 return const_reverse_iterator(begin());
370 }
371
372 constexpr size_type
373 size() const
374 {
375 return VDimension;
376 }
377
378 constexpr size_type
379 max_size() const
380 {
381 return VDimension;
382 }
383
384 constexpr bool
385 empty() const
386 {
387 return false;
388 }
389
390 reference operator[](size_type pos) { return m_InternalArray[pos]; }
391
392 const_reference operator[](size_type pos) const { return m_InternalArray[pos]; }
393
394 reference
396 {
397 ExceptionThrowingBoundsCheck(pos);
398 return m_InternalArray[pos];
399 }
400
401 const_reference
402 at(size_type pos) const
403 {
404 ExceptionThrowingBoundsCheck(pos);
405 return m_InternalArray[pos];
406 }
407
408 reference
410 {
411 return *begin();
412 }
413
414 const_reference
415 front() const
416 {
417 return *begin();
418 }
419
420 reference
422 {
423 return VDimension ? *(end() - 1) : *end();
424 }
425
426 const_reference
427 back() const
428 {
429 return VDimension ? *(end() - 1) : *end();
430 }
431
434 {
435 return &m_InternalArray[0];
436 }
437
438 const OffsetValueType *
439 data() const
440 {
441 return &m_InternalArray[0];
442 }
443
444private:
445 void
447 {
448 if (pos >= VDimension)
449 {
450 throw std::out_of_range("array::ExceptionThrowingBoundsCheck");
451 }
452 }
453
454}; //------------ End struct Offset
455
456template <unsigned int VDimension>
457Offset<VDimension>
459{
460 Self ind;
461
462 memset(ind.m_InternalArray, 0, sizeof(OffsetValueType) * VDimension);
463 ind.m_InternalArray[dim] = 1;
464 return ind;
465}
466
467template <unsigned int VDimension>
468std::ostream &
469operator<<(std::ostream & os, const Offset<VDimension> & ind)
470{
471 os << '[';
472 unsigned int dimlim = VDimension - 1;
473 for (unsigned int i = 0; i < dimlim; ++i)
474 {
475 os << ind[i] << ", ";
476 }
477 if (VDimension >= 1)
478 {
479 os << ind[VDimension - 1];
480 }
481 os << ']';
482 return os;
483}
484
485// ======================= Mirror the access pattern behavior of the std::array class
486// Array comparisons.
487template <unsigned int VDimension>
488inline bool
490{
491 return std::equal(one.begin(), one.end(), two.begin());
492}
493
494template <unsigned int VDimension>
495inline bool
497{
498 return !(one == two);
499}
500
501template <unsigned int VDimension>
502inline bool
503operator<(const Offset<VDimension> & one, const Offset<VDimension> & two)
504{
505 return std::lexicographical_compare(one.begin(), one.end(), two.begin(), two.end());
506}
507
508template <unsigned int VDimension>
509inline bool
511{
512 return two < one;
513}
514
515template <unsigned int VDimension>
516inline bool
517operator<=(const Offset<VDimension> & one, const Offset<VDimension> & two)
518{
519 return !(one > two);
520}
521
522template <unsigned int VDimension>
523inline bool
525{
526 return !(one < two);
527}
528
529// Specialized algorithms [6.2.2.2].
530template <unsigned int VDimension>
531inline void
533{
535}
536
537} // end namespace itk
538
539#endif
Pixel-wise addition of two images.
Simulate a standard C array with copy semantics.
Definition: itkFixedArray.h:54
std::ostream & operator<<(std::ostream &os, const itk::DOMNode &object)
The "itk" namespace contains all Insight Segmentation and Registration Toolkit (ITK) classes....
bool operator!=(const Offset< VDimension > &one, const Offset< VDimension > &two)
Definition: itkOffset.h:496
*par Constraints *The filter image with at least two dimensions and a vector *length of at least The theory supports extension to scalar but *the implementation of the itk vector classes do not **The template parameter TRealType must be floating point(float or double) or *a user-defined "real" numerical type with arithmetic operations defined *sufficient to compute derivatives. **\par Performance *This filter will automatically multithread if run with *SetUsePrincipleComponents
bool operator==(const Offset< VDimension > &one, const Offset< VDimension > &two)
Definition: itkOffset.h:489
bool operator>(const Offset< VDimension > &one, const Offset< VDimension > &two)
Definition: itkOffset.h:510
bool operator>=(const Offset< VDimension > &one, const Offset< VDimension > &two)
Definition: itkOffset.h:524
void swap(Offset< VDimension > &one, Offset< VDimension > &two)
Definition: itkOffset.h:532
long OffsetValueType
Definition: itkIntTypes.h:94
bool operator<=(const Offset< VDimension > &one, const Offset< VDimension > &two)
Definition: itkOffset.h:517
bool operator<(const Offset< VDimension > &one, const Offset< VDimension > &two)
Definition: itkOffset.h:503
Represent a n-dimensional offset between two n-dimensional indexes of n-dimensional image.
Definition: itkOffset.h:70
unsigned int size_type
Definition: itkOffset.h:291
ptrdiff_t difference_type
Definition: itkOffset.h:292
reference front()
Definition: itkOffset.h:409
const Self operator-(const Self &vec) const
Definition: itkOffset.h:145
void CopyWithRound(const FixedArray< TCoordRep, VDimension > &point)
Definition: itkOffset.h:252
const value_type & const_reference
Definition: itkOffset.h:288
reverse_iterator rbegin()
Definition: itkOffset.h:349
constexpr bool empty() const
Definition: itkOffset.h:385
constexpr iterator begin()
Definition: itkOffset.h:319
const_reference front() const
Definition: itkOffset.h:415
static constexpr unsigned int GetOffsetDimension()
Definition: itkOffset.h:87
const Self & operator+=(const Self &vec)
Definition: itkOffset.h:158
value_type * iterator
Definition: itkOffset.h:289
std::reverse_iterator< const_iterator > const_reverse_iterator
Definition: itkOffset.h:294
void SetElement(unsigned long element, OffsetValueType val)
Definition: itkOffset.h:206
const_reference operator[](size_type pos) const
Definition: itkOffset.h:392
const Self operator+(const Size< VDimension > &sz) const
Definition: itkOffset.h:108
const_reverse_iterator rbegin() const
Definition: itkOffset.h:355
static Self GetBasisOffset(unsigned int dim)
Definition: itkOffset.h:458
void SetOffset(const OffsetValueType val[VDimension])
Definition: itkOffset.h:194
itk::OffsetValueType OffsetValueType
Definition: itkOffset.h:80
constexpr iterator end()
Definition: itkOffset.h:337
const_reference at(size_type pos) const
Definition: itkOffset.h:402
const Self & operator-=(const Self &vec)
Definition: itkOffset.h:170
const value_type * const_iterator
Definition: itkOffset.h:290
OffsetValueType * data()
Definition: itkOffset.h:433
constexpr const_iterator end() const
Definition: itkOffset.h:343
value_type & reference
Definition: itkOffset.h:287
constexpr size_type max_size() const
Definition: itkOffset.h:379
void assign(const value_type &newValue)
Definition: itkOffset.h:301
reverse_iterator rend()
Definition: itkOffset.h:361
const Self operator+(const Self &vec) const
Definition: itkOffset.h:95
void ExceptionThrowingBoundsCheck(size_type pos) const
Definition: itkOffset.h:446
constexpr const_iterator cbegin() const
Definition: itkOffset.h:313
const OffsetValueType * data() const
Definition: itkOffset.h:439
const Self & operator-=(const Size< VDimension > &sz)
Definition: itkOffset.h:133
const_reference back() const
Definition: itkOffset.h:427
void Fill(OffsetValueType value)
Definition: itkOffset.h:226
itk::OffsetValueType value_type
Definition: itkOffset.h:286
void CopyWithCast(const FixedArray< TCoordRep, VDimension > &point)
Definition: itkOffset.h:264
const_reverse_iterator rend() const
Definition: itkOffset.h:367
reference operator[](size_type pos)
Definition: itkOffset.h:390
reference at(size_type pos)
Definition: itkOffset.h:395
void swap(Offset &other)
Definition: itkOffset.h:307
constexpr size_type size() const
Definition: itkOffset.h:373
OffsetValueType m_InternalArray[VDimension]
Definition: itkOffset.h:245
const OffsetValueType * GetOffset() const
Definition: itkOffset.h:184
constexpr const_iterator begin() const
Definition: itkOffset.h:325
reference back()
Definition: itkOffset.h:421
constexpr const_iterator cend() const
Definition: itkOffset.h:331
OffsetValueType GetElement(unsigned long element) const
Definition: itkOffset.h:218
std::reverse_iterator< iterator > reverse_iterator
Definition: itkOffset.h:293
const Self & operator+=(const Size< VDimension > &sz)
Definition: itkOffset.h:121