CVB++ 15.0
image_plane_linear_iterator.hpp
1#pragma once
2
3#include <iterator>
4#include <cassert>
5
6#include "_decl/decl_linear_access.hpp"
7
8#include "size_2d.hpp"
9
10namespace Cvb
11{
12
13 CVB_BEGIN_INLINE_NS
14
15 template <class Type>
16 class LinearConstIterator
17 {
18 private:
19 using Allocator = std::allocator<Type>;
20 using AllocType = typename std::allocator_traits<Allocator>::template rebind_alloc<Type>;
21 using AllocTraits = std::allocator_traits<AllocType>;
22
23 public:
24 using iterator_category = std::random_access_iterator_tag;
25 using value_type = Type;
26 using pointer = typename AllocTraits::pointer;
27 using reference = const value_type &;
28 using difference_type = typename AllocTraits::difference_type;
29
30 LinearConstIterator() = default;
31
32 explicit LinearConstIterator(LinearAccessData linearAccessData, Size2D<int> size,
33 Point2D<int> pos = Point2D<int>()) noexcept
34 : linearAccessData_(linearAccessData)
35 , size_(size)
36 , currentPos_(pos)
37 {
38 ApplyCurrentPos();
39 }
40
41 reference operator*() const noexcept
42 {
43 return *reinterpret_cast<Type *>(currentPixelPtr_);
44 }
45
46 pointer operator->() const noexcept
47 {
48 return reinterpret_cast<Type *>(currentPixelPtr_);
49 }
50
51 LinearConstIterator<Type> &operator++() noexcept
52 {
53 currentPos_.SetX(currentPos_.X() + 1);
54 currentPixelPtr_ += linearAccessData_.XInc();
55 if (currentPos_.X() < size_.Width())
56 return *this;
57 else
58 {
59 currentPos_.SetX(0);
60 currentPos_.SetY(currentPos_.Y() + 1);
61 currentLinePtr_ += linearAccessData_.YInc();
62 currentPixelPtr_ = currentLinePtr_;
63 return *this;
64 }
65 }
66
67 LinearConstIterator<Type> operator++(int) noexcept // NOLINT(cert-dcl21-cpp)
68 {
69 auto tmp = *this;
70 ++*this;
71 return tmp;
72 }
73
74 LinearConstIterator<Type> &operator--() noexcept
75 {
76 currentPos_.SetX(currentPos_.X() - 1);
77 currentPixelPtr_ -= linearAccessData_.XInc();
78 if (currentPos_.X() >= 0)
79 return *this;
80 else
81 {
82 currentPos_.SetX(size_.Width() - 1);
83 currentPos_.SetY(currentPos_.Y() - 1);
84 currentLinePtr_ -= linearAccessData_.YInc();
85 currentPixelPtr_ = currentLinePtr_ + currentPos_.X() * linearAccessData_.XInc();
86 return *this;
87 }
88 }
89
90 LinearConstIterator<Type> operator--(int) noexcept // NOLINT(cert-dcl21-cpp)
91 {
92 auto tmp = *this;
93 --*this;
94 return tmp;
95 }
96
97 LinearConstIterator<Type> &operator+=(const difference_type offset) noexcept
98 {
99 auto linearPos = Point2DToLinear(currentPos_);
100 linearPos += offset;
101 currentPos_ = LinearToPoint2D(linearPos);
102 ApplyCurrentPos();
103 return *this;
104 }
105
106 LinearConstIterator<Type> operator+(const difference_type offset) const noexcept
107 {
108 auto tmp = *this;
109 return tmp += offset;
110 }
111
112 LinearConstIterator<Type> &operator-=(const difference_type offset) noexcept
113 {
114 return *this += -offset;
115 }
116
117 LinearConstIterator<Type> operator-(const difference_type offset) const noexcept
118 {
119 auto tmp = *this;
120 return tmp -= offset;
121 }
122
123 difference_type operator-(const LinearConstIterator<Type> &rhs) const noexcept
124 {
125 return Point2DToLinear(currentPos_) - Point2DToLinear(rhs.currentPos_);
126 }
127
128 reference operator[](const difference_type offset) const noexcept
129 {
130 return *(*this + offset);
131 }
132
133 bool operator==(const LinearConstIterator<Type> &rhs) const noexcept
134 {
135 return currentPos_ == rhs.currentPos_;
136 }
137
138 bool operator!=(const LinearConstIterator<Type> &rhs) const noexcept
139 {
140 return !(*this == rhs);
141 }
142
143 bool operator<(const LinearConstIterator<Type> &rhs) const noexcept
144 {
145 return Point2DToLinear(currentPos_) < Point2DToLinear(rhs.currentPos_);
146 }
147
148 bool operator>(const LinearConstIterator<Type> &rhs) const noexcept
149 {
150 return rhs < *this;
151 }
152
153 bool operator<=(const LinearConstIterator<Type> &rhs) const noexcept
154 {
155 return !(rhs < *this);
156 }
157
158 bool operator>=(const LinearConstIterator<Type> &rhs) const noexcept
159 {
160 return !(*this < rhs);
161 }
162
163 private:
164 difference_type Point2DToLinear(Point2D<int> pos) const noexcept
165 {
166 return static_cast<difference_type>(pos.Y()) * static_cast<difference_type>(size_.Width())
167 + static_cast<difference_type>(pos.X());
168 }
169
170 Point2D<int> LinearToPoint2D(difference_type pos) const noexcept
171 {
172 return Point2D<int>(static_cast<int>(pos % size_.Width()), static_cast<int>(pos / size_.Width()));
173 }
174
175 void ApplyCurrentPos() noexcept
176 {
177 currentLinePtr_ =
178 reinterpret_cast<std::uint8_t *>(linearAccessData_.BasePtr()) + currentPos_.Y() * linearAccessData_.YInc();
179 currentPixelPtr_ = currentLinePtr_ + currentPos_.X() * linearAccessData_.XInc();
180 }
181
182 LinearAccessData linearAccessData_;
183 Size2D<int> size_;
184 Point2D<int> currentPos_;
185 std::uint8_t *currentLinePtr_ = nullptr;
186 std::uint8_t *currentPixelPtr_ = nullptr;
187 };
188
189 template <class Type>
190 inline LinearConstIterator<Type> operator+(typename LinearConstIterator<Type>::difference_type offset,
191 LinearConstIterator<Type> next) noexcept
192 {
193 return next += offset;
194 }
195
196 template <class Type>
197 class LinearIterator : public LinearConstIterator<Type>
198 {
199 private:
200 using Allocator = std::allocator<Type>;
201 using AllocType = typename std::allocator_traits<Allocator>::template rebind_alloc<Type>;
202 using AllocTraits = std::allocator_traits<AllocType>;
203
204 using Base = LinearConstIterator<Type>;
205
206 public:
207 using iterator_category = std::random_access_iterator_tag;
208 using value_type = Type;
209 using pointer = typename AllocTraits::pointer;
210 using reference = value_type &;
211 using difference_type = typename AllocTraits::difference_type;
212
213 using Base::Base;
214
215 reference operator*() const noexcept
216 {
217 return const_cast<reference>(Base::operator*()); // NOLINT(cppcoreguidelines-pro-type-const-cast)
218 }
219
220 pointer operator->() const noexcept
221 {
222 return const_cast<pointer>(Base::operator->()); // NOLINT(cppcoreguidelines-pro-type-const-cast)
223 }
224
225 LinearIterator<Type> &operator++() noexcept
226 {
227 Base::operator++();
228 return *this;
229 }
230
231 LinearIterator<Type> operator++(int) noexcept // NOLINT(cert-dcl21-cpp)
232 {
233 auto tmp = *this;
234 Base::operator++();
235 return tmp;
236 }
237
238 LinearIterator<Type> &operator--() noexcept
239 {
240 Base::operator--();
241 return *this;
242 }
243
244 LinearIterator<Type> operator--(int) noexcept // NOLINT(cert-dcl21-cpp)
245 {
246 auto tmp = *this;
247 Base::operator--();
248 return tmp;
249 }
250
251 LinearIterator<Type> &operator+=(const difference_type offset) noexcept
252 {
253 Base::operator+=(offset);
254 return *this;
255 }
256
257 LinearIterator<Type> operator+(const difference_type offset) const noexcept
258 {
259 auto tmp = *this;
260 return tmp += offset;
261 }
262
263 LinearIterator<Type> &operator-=(const difference_type offset) noexcept
264 {
265 Base::operator-=(offset);
266 return *this;
267 }
268
269 using Base::operator-;
270
271 LinearIterator<Type> operator-(const difference_type offset) const noexcept
272 {
273 auto tmp = *this;
274 return tmp -= offset;
275 }
276
277 reference operator[](const difference_type offset) const noexcept
278 {
279 return const_cast<reference>(Base::operator[](offset)); // NOLINT(cppcoreguidelines-pro-type-const-cast)
280 }
281 };
282
283 template <class Type>
284 inline LinearIterator<Type> operator+(typename LinearIterator<Type>::difference_type offset,
285 LinearIterator<Type> next) noexcept
286 {
287 return next += offset;
288 }
289
290 CVB_END_INLINE_NS
291
292} // namespace Cvb
Root namespace for the Image Manager interface.
Definition c_bayer_to_rgb.h:17
AffineMatrix2D operator+(const AffineMatrix2D &lhs, const AffineMatrix2D &rhs) noexcept
Add two affine matrices.
Definition affine_matrix_2d.hpp:223
T next(T... args)