NDEVR
API Documentation
BitIterator.hpp
1/*--------------------------------------------------------------------------------------------
2Copyright (c) 2019, NDEVR LLC
3tyler.parke@ndevr.org
4 __ __ ____ _____ __ __ _______
5 | \ | | | __ \ | ___|\ \ / / | __ \
6 | \ | | | | \ \ | |___ \ \ / / | |__) |
7 | . \| | | |__/ / | |___ \ V / | _ /
8 | |\ |_|_____/__|_____|___\_/____| | \ \
9 |__| \__________________________________| \__\
10
11Subject to the terms of the Enterprise+ Agreement, NDEVR hereby grants
12Licensee a limited, non-exclusive, non-transferable, royalty-free license
13(without the right to sublicense) to use the API solely for the purpose of
14Licensee's internal development efforts to develop applications for which
15the API was provided.
16
17The above copyright notice and this permission notice shall be included in all
18copies or substantial portions of the Software.
19
20THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
21INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
22PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
23FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
24OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25DEALINGS IN THE SOFTWARE.
26
27Library: Base
28File: BitIterator
29Included in API: True
30Author(s): Tyler Parke
31 *-----------------------------------------------------------------------------------------**/
32#pragma once
33#include "DLLInfo.h"
34#include <NDEVR/BaseValues.h>
35#include <NDEVR/BitFlag.h>
36#include <NDEVR/BitReference.h>
37#include <iterator>
38namespace NDEVR
39{
44 class BitIterator
45 {
46 public:
47 friend class ConstBitIterator;
48 BitIterator(BitFlag* flag, const sint04 offset)
49 : m_flag(flag)
50 {
51 checkBitLocationPositive(offset);
52 }
53 BitIterator(const BitIterator& iter) = default;
54
55 bool operator!() const
56 {
57 return !(*m_flag)[m_bit_ref];
58 }
59 constexpr operator bool() const
60 {
61 return (*m_flag)[m_bit_ref];
62 }
63 BitReference operator*()
64 {
65 return BitReference(*m_flag, m_bit_ref);
66 }
67 const BitReference operator*() const
68 {
69 return BitReference(*m_flag, m_bit_ref);
70 }
71 bool byteAligned() const
72 {
73 return m_bit_ref == 0;
74 }
75 void jumpByte()
76 {
77 m_flag++;
78 }
79 const BitFlag& byteFlag() const
80 {
81 return *m_flag;
82 }
83 const BitFlag& byteFlag(uint04 offset) const
84 {
85 return *(m_flag + offset);
86 }
87 BitIterator& operator++()
88 {
89 if (m_bit_ref == 7)
90 {
91 m_flag++;
92 m_bit_ref = 0;
93 }
94 else
95 {
96 m_bit_ref++;
97 }
98 return *this;
99 }
100 BitIterator& operator--()
101 {
102 if (m_bit_ref == 0)
103 {
104 m_bit_ref = 7;
105 m_flag--;
106 }
107 else
108 {
109 m_bit_ref--;
110 }
111 return *this;
112 }
113 BitIterator operator++(int)
114 {
115 BitIterator old_value(*this);
116 if (m_bit_ref == 7)
117 {
118 m_flag++;
119 m_bit_ref = 0;
120 }
121 else
122 {
123 m_bit_ref++;
124 }
125 return old_value;
126 }
127 BitIterator operator--(int)
128 {
129 BitIterator old_value(*this);
130 if (m_bit_ref == 0)
131 {
132 m_bit_ref = 7;
133 m_flag--;
134 }
135 else
136 {
137 m_bit_ref--;
138 }
139 return old_value;
140 }
141 template<class t_type>
142 BitIterator& operator+=(const t_type& movement)
143 {
144 checkBitLocationPositive(cast<sint04>(m_bit_ref) + cast<sint04>(movement));
145 return (*this);
146 }
147 template<class t_type>
148 BitIterator& operator-=(const t_type& movement)
149 {
150 checkBitLocationNegative(cast<sint04>(m_bit_ref) - cast<sint04>(movement));
151 return (*this);
152 }
153#ifdef _DEBUG
154 bool operator>=(const bool*) const { return false; };//needed for buffer compat
155 bool operator<=(const bool*) const { return true; };//needed for buffer compat
156 bool operator<(const bool*) const { return true; };//needed for buffer compat
157 bool operator>(const bool*) const { return false; };//needed for buffer compat
158#endif
159 bool operator>(const BitIterator& other) const
160 {
161 if (m_flag == other.m_flag)
162 return m_bit_ref > other.m_bit_ref;
163 else
164 return m_flag > other.m_flag;
165 }
166 bool operator<(const BitIterator& other) const
167 {
168 if (m_flag == other.m_flag)
169 return m_bit_ref < other.m_bit_ref;
170 else
171 return m_flag < other.m_flag;
172 }
173 ptrdiff_t operator-(const BitIterator& rhs)
174 {
175 ptrdiff_t byte_diff = this->m_flag - rhs.m_flag;
176 ptrdiff_t bit_diff = this->m_bit_ref - rhs.m_bit_ref;
177 return byte_diff * 8 + bit_diff;
178 }
179 template<class t_type>
180 BitIterator operator+(t_type distance) const
181 {
182 BitIterator sum = *this;
183 sum.checkBitLocationPositive(cast<sint04>(sum.m_bit_ref) + cast<sint04>(distance));
184 return sum;
185 }
186 template<class t_type>
187 BitIterator operator-(t_type distance) const
188 {
189 BitIterator sum = *this;
190 sum.checkBitLocationNegative(cast<sint04>(sum.m_bit_ref) - cast<sint04>(distance));
191 return sum;
192 }
193 public:
194 BitIterator& operator=(const BitIterator& rawIterator) = default;
195
196 bool operator==(const BitIterator& rawIterator) const { return (m_bit_ref == rawIterator.m_bit_ref && m_flag == rawIterator.m_flag); }
197 bool operator!=(const BitIterator& rawIterator) const { return (m_bit_ref != rawIterator.m_bit_ref || m_flag != rawIterator.m_flag); }
198
199 private:
200 void checkBitLocationPositive(sint04 bit) const
201 {
202 if (bit >= 8)
203 {
204 m_flag += (bit / 8);
205 bit = bit % 8;
206 }
207 m_bit_ref = cast<uint01>(bit);
208 }
209 void checkBitLocationNegative(sint04 bit) const
210 {
211 if (bit <= 0)
212 {
213 bit = -bit + 8;
214 m_flag -= (bit / 8);
215 bit = bit % 8;
216 }
217 m_bit_ref = cast<uint01>(bit);
218 }
219 mutable BitFlag* m_flag;
220 mutable uint01 m_bit_ref = Constant<uint01>::Invalid;
221 };
222
226 class ConstBitIterator
227 {
228 public:
229 friend class BitIterator;
230 ConstBitIterator(const BitIterator& iter)
231 : m_flag(iter.m_flag)
232 , m_bit_ref(iter.m_bit_ref)
233 {}
234 ConstBitIterator(const BitFlag* flag, sint04 offset)
235 : m_flag(flag)
236 {
237 checkBitLocationPositive(offset);
238 }
239 ConstBitIterator(const BitFlag* flag, uint04 offset)
240 : m_flag(flag)
241 {
242 checkBitLocationPositive(cast<sint04>(offset));
243 }
244 ConstBitIterator(const ConstBitIterator& iter) = default;
245
246 bool operator*()
247 {
248 return (*m_flag)[m_bit_ref];
249 }
250 bool operator*() const
251 {
252 return (*m_flag)[m_bit_ref];
253 }
254 bool operator==(bool ref) const
255 {
256 return (*m_flag)[m_bit_ref] == ref;
257 }
258 bool operator!() const
259 {
260 return !(*m_flag)[m_bit_ref];
261 }
262 constexpr operator bool() const
263 {
264 return (*m_flag)[m_bit_ref];
265 }
266 bool operator>(const BitIterator& other) const
267 {
268 if (m_flag == other.m_flag)
269 return m_bit_ref > other.m_bit_ref;
270 else
271 return m_flag > other.m_flag;
272 }
273 bool operator<(const BitIterator& other) const
274 {
275 if (m_flag == other.m_flag)
276 return m_bit_ref < other.m_bit_ref;
277 else
278 return m_flag < other.m_flag;
279 }
280 bool operator>(const ConstBitIterator& other) const
281 {
282 if (m_flag == other.m_flag)
283 return m_bit_ref > other.m_bit_ref;
284 else
285 return m_flag > other.m_flag;
286 }
287 bool operator<(const ConstBitIterator& other) const
288 {
289 if (m_flag == other.m_flag)
290 return m_bit_ref < other.m_bit_ref;
291 else
292 return m_flag < other.m_flag;
293 }
294 bool byteAligned() const
295 {
296 return m_bit_ref == 0;
297 }
298 void jumpByte()
299 {
300 m_flag++;
301 }
302 const BitFlag& byteFlag() const
303 {
304 return *m_flag;
305 }
306 const BitFlag& byteFlag(uint04 offset) const
307 {
308 return *(m_flag + offset);
309 }
310 ConstBitIterator& operator++()
311 {
312 if (m_bit_ref == 7)
313 {
314 m_flag++;
315 m_bit_ref = 0;
316 }
317 else
318 {
319 m_bit_ref++;
320 }
321 return *this;
322 }
323 ConstBitIterator& operator--()
324 {
325 if (m_bit_ref == 0)
326 {
327 m_bit_ref = 7;
328 m_flag--;
329 }
330 else
331 {
332 m_bit_ref--;
333 }
334 return *this;
335 }
336 ConstBitIterator operator++(int)
337 {
338 ConstBitIterator old_value(*this);
339 if (m_bit_ref == 7)
340 {
341 m_flag++;
342 m_bit_ref = 0;
343 }
344 else
345 {
346 m_bit_ref++;
347 }
348 return old_value;
349 }
350 ConstBitIterator operator--(int)
351 {
352 ConstBitIterator old_value(*this);
353 if (m_bit_ref == 0)
354 {
355 m_bit_ref = 7;
356 m_flag--;
357 }
358 else
359 {
360 m_bit_ref--;
361 }
362 return old_value;
363 }
364 template<class t_type>
365 ConstBitIterator& operator+=(const t_type& movement)
366 {
367 checkBitLocationPositive(cast<sint04>(m_bit_ref) + cast<sint04>(movement));
368 return (*this);
369 }
370 template<class t_type>
371 ConstBitIterator& operator-=(const t_type& movement)
372 {
373 checkBitLocationNegative(cast<sint04>(m_bit_ref) - cast<sint04>(movement));
374 return (*this);
375 }
376
377 ptrdiff_t operator-(const ConstBitIterator& rhs)
378 {
379 ptrdiff_t byte_diff = this->m_flag - rhs.m_flag;
380 ptrdiff_t bit_diff = this->m_bit_ref - rhs.m_bit_ref;
381 return byte_diff * 8 + bit_diff;
382 }
383
384 public:
385 ConstBitIterator& operator=(const ConstBitIterator& rawIterator) = default;
386
387 bool operator==(const ConstBitIterator& rawIterator) const { return (m_bit_ref == rawIterator.m_bit_ref && m_flag == rawIterator.m_flag); }
388 bool operator!=(const ConstBitIterator& rawIterator) const { return (m_bit_ref != rawIterator.m_bit_ref || m_flag != rawIterator.m_flag); }
389 bool operator==(const BitIterator& rawIterator) const { return (m_bit_ref == rawIterator.m_bit_ref && m_flag == rawIterator.m_flag); }
390 bool operator!=(const BitIterator& rawIterator) const { return (m_bit_ref != rawIterator.m_bit_ref || m_flag != rawIterator.m_flag); }
391 template<class t_type>
392 ConstBitIterator operator+(const t_type& movement)
393 {
394 ConstBitIterator sum(*this);
395 sum += movement;
396 return sum;
397 }
398 template<class t_type>
399 ConstBitIterator operator-(const t_type& movement)
400 {
401 ConstBitIterator sum(*this);
402 sum -= movement;
403 return sum;
404 }
405 private:
406 void checkBitLocationPositive(sint04 bit) const
407 {
408 if (bit >= 8)
409 {
410 m_flag += (bit / 8);
411 bit = bit % 8;
412 }
413 m_bit_ref = cast<uint01>(bit);
414 }
415 void checkBitLocationNegative(sint04 bit) const
416 {
417 if (bit <= 0)
418 {
419 bit = -bit + 8;
420 m_flag -= (bit / 8);
421 bit = bit % 8;
422 }
423 m_bit_ref = cast<uint01>(bit);
424 }
425 mutable const BitFlag* m_flag;
426 mutable uint01 m_bit_ref = Constant<uint01>::Invalid;
427 };
428}
429
A bitset that stores 8 bits (elements with only two possible values: 0 or 1, true or false,...
Definition BitFlag.hpp:55
A convenience class used with Buffers or Vectors of bools for referencing or acting on a single bit.
The primary namespace for the NDEVR SDK.
static constexpr bool operator<=(const Angle< t_type_a > &angle_a, const Angle< t_type_b > &angle_b)
Less-than-or-equal comparison operator.
uint32_t uint04
-Defines an alias representing a 4 byte, unsigned integer -Can represent exact integer values 0 throu...
int32_t sint04
-Defines an alias representing a 4 byte, signed integer.
static constexpr bool operator>=(const Angle< t_type_a > &angle_a, const Angle< t_type_b > &angle_b)
Greater-than-or-equal comparison operator.
uint8_t uint01
-Defines an alias representing a 1 byte, unsigned integer -Can represent exact integer values 0 throu...
constexpr t_to cast(const Angle< t_from > &value)
Casts an Angle from one backing type to another.
Definition Angle.h:408