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