Embedded Template Library 1.0
Loading...
Searching...
No Matches
circular_iterator.h
Go to the documentation of this file.
1
2
3/******************************************************************************
4The MIT License(MIT)
5
6Embedded Template Library.
7https://github.com/ETLCPP/etl
8https://www.etlcpp.com
9
10Copyright(c) 2022 John Wellbelove
11
12Permission is hereby granted, free of charge, to any person obtaining a copy
13of this software and associated documentation files(the "Software"), to deal
14in the Software without restriction, including without limitation the rights
15to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
16copies of the Software, and to permit persons to whom the Software is
17furnished to do so, subject to the following conditions :
18
19The above copyright notice and this permission notice shall be included in all
20copies or substantial portions of the Software.
21
22THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
25AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28SOFTWARE.
29******************************************************************************/
30
31#ifndef ETL_CIRCULAR_ITERATOR_INCLUDED
32#define ETL_CIRCULAR_ITERATOR_INCLUDED
33
34#include "platform.h"
35#include "iterator.h"
36#include "static_assert.h"
37
39
40namespace etl
41{
42 namespace private_circular_iterator
43 {
44 //***************************************************************************
46 //***************************************************************************
47 template <typename TIterator>
49 : public etl::iterator<typename etl::iterator_traits<TIterator>::iterator_category, typename etl::iterator_traits<TIterator>::value_type>
50 {
51 public:
52
53 typedef typename etl::iterator_traits<TIterator>::value_type value_type;
54 typedef typename etl::iterator_traits<TIterator>::difference_type difference_type;
55 typedef typename etl::iterator_traits<TIterator>::pointer pointer;
56 typedef typename etl::iterator_traits<TIterator>::reference reference;
57 typedef typename etl::iterator_traits<TIterator>::iterator_category iterator_category;
58
59 //***************************************************************************
61 //***************************************************************************
62 ETL_CONSTEXPR14 circular_iterator_common()
65 , itr(TIterator())
66 {
67 }
68
69 //***************************************************************************
71 //***************************************************************************
78
79 //***************************************************************************
81 //***************************************************************************
88
89 //***************************************************************************
91 //***************************************************************************
93 {
94 itr_begin = other.itr_begin;
95 itr_end = other.itr_end;
96 itr = other.itr;
97
98 return *this;
99 }
100
101 //***************************************************************************
103 //***************************************************************************
104 ETL_CONSTEXPR14 TIterator begin() const
105 {
106 return itr_begin;
107 }
108
109 //***************************************************************************
111 //***************************************************************************
112 ETL_CONSTEXPR14 TIterator end() const
113 {
114 return itr_end;
115 }
116
117 //***************************************************************************
119 //***************************************************************************
120 ETL_CONSTEXPR14 size_t size() const
121 {
122 return etl::distance(itr_begin, itr_end);
123 }
124
125 //***************************************************************************
127 //***************************************************************************
128 ETL_CONSTEXPR14 bool empty() const
129 {
130 return (itr_begin == itr_end);
131 }
132
133 //***************************************************************************
135 //***************************************************************************
136 ETL_CONSTEXPR14 value_type operator *()
137 {
138 return *itr;
139 }
140
141 //***************************************************************************
143 //***************************************************************************
144 ETL_CONSTEXPR14 const value_type operator *() const
145 {
146 return *itr;
147 }
148
149 //***************************************************************************
151 //***************************************************************************
152 ETL_CONSTEXPR14 TIterator operator ->()
153 {
154 return itr;
155 }
156
157 //***************************************************************************
159 //***************************************************************************
160 ETL_CONSTEXPR14 const TIterator operator ->() const
161 {
162 return itr;
163 }
164
165 //***************************************************************************
167 //***************************************************************************
168 ETL_CONSTEXPR14 operator TIterator() const
169 {
170 return itr;
171 }
172
173 //***************************************************************************
175 //***************************************************************************
176 ETL_CONSTEXPR14 TIterator current() const
177 {
178 return itr;
179 }
180
181 protected:
182
186 };
187
188 //***************************************************************************
192 //***************************************************************************
195 {
196 ETL_STATIC_ASSERT((etl::is_same<TTag, ETL_OR_STD::input_iterator_tag>::value_type), "input_iterator_catagory is not supported by circular_iterator");
197 ETL_STATIC_ASSERT((etl::is_same<TTag, ETL_OR_STD::output_iterator_tag>::value_type), "output_iterator_catagory is not supported by circular_iterator");
198 };
199
200 //***************************************************************************
205 template <typename TIterator>
207 : public circular_iterator_common<TIterator>
208 {
209 private:
210
212
213 public:
214
215 using common_t::operator=;
216
217 typedef typename common_t::value_type value_type;
218 typedef typename common_t::difference_type difference_type;
219 typedef typename common_t::pointer pointer;
220 typedef typename common_t::reference reference;
221 typedef typename common_t::iterator_category iterator_category;
222
223 //***************************************************************************
225 //***************************************************************************
226 ETL_CONSTEXPR14 circular_iterator_impl()
227 : common_t()
228 {
229 }
230
231 //***************************************************************************
233 //***************************************************************************
238
239 //***************************************************************************
241 //***************************************************************************
246
247 //***************************************************************************
249 //***************************************************************************
251 : common_t(other)
252 {
253 }
254
255 //***************************************************************************
257 //***************************************************************************
259 {
260 common_t::operator=(other);
261
262 return *this;
263 }
264
265 //***************************************************************************
267 //***************************************************************************
269 {
270 if (++this->itr == this->itr_end)
271 {
272 this->itr = this->itr_begin;
273 }
274
275 return *this;
276 }
277
278 //***************************************************************************
280 //***************************************************************************
282 {
284
285 ++(*this);
286
287 return (original);
288 }
289 };
290
291 //***************************************************************************
296 template <typename TIterator>
298 : public circular_iterator_common<TIterator>
299 {
300 private:
301
303
304 public:
305
306 using common_t::operator=;
307
308 typedef typename common_t::value_type value_type;
309 typedef typename common_t::difference_type difference_type;
310 typedef typename common_t::pointer pointer;
311 typedef typename common_t::reference reference;
312 typedef typename common_t::iterator_category iterator_category;
313
314 //***************************************************************************
316 //***************************************************************************
317 ETL_CONSTEXPR14 circular_iterator_impl()
318 : common_t()
319 {
320 }
321
322 //***************************************************************************
324 //***************************************************************************
329
330 //***************************************************************************
332 //***************************************************************************
337
338 //***************************************************************************
340 //***************************************************************************
342 : common_t(other)
343 {
344 }
345
346 //***************************************************************************
348 //***************************************************************************
350 {
351 common_t::operator=(other);
352
353 return *this;
354 }
355
356 //***************************************************************************
358 //***************************************************************************
360 {
361 if (++this->itr == this->itr_end)
362 {
363 this->itr = this->itr_begin;
364 }
365
366 return *this;
367 }
368
369 //***************************************************************************
371 //***************************************************************************
373 {
375
376 ++(*this);
377
378 return (original);
379 }
380
381 //***************************************************************************
383 //***************************************************************************
385 {
386 if (this->itr == this->itr_begin)
387 {
388 typename etl::reverse_iterator<TIterator> ritr(this->itr_end);
389 ++ritr;
390 this->itr = ritr.base();
391 }
392 else
393 {
394 --this->itr;
395 }
396
397 return *this;
398 }
399
400 //***************************************************************************
402 //***************************************************************************
404 {
406
407 --(*this);
408
409 return (original);
410 }
411 };
412
413 //***************************************************************************
417 //***************************************************************************
418 template <typename TIterator>
421 {
422 private:
423
425
426 public:
427
428 using common_t::operator=;
429
430 typedef typename common_t::value_type value_type;
431 typedef typename common_t::difference_type difference_type;
432 typedef typename common_t::pointer pointer;
433 typedef typename common_t::reference reference;
434 typedef typename common_t::iterator_category iterator_category;
435
436 //***************************************************************************
438 //***************************************************************************
439 ETL_CONSTEXPR14 circular_iterator_impl()
440 : common_t()
441 {
442 }
443
444 //***************************************************************************
446 //***************************************************************************
451
452 //***************************************************************************
454 //***************************************************************************
459
460 //***************************************************************************
462 //***************************************************************************
464 : common_t(other)
465 {
466 }
467
468 //***************************************************************************
470 //***************************************************************************
472 {
473 common_t::operator=(other);
474
475 return *this;
476 }
477
478 //***************************************************************************
480 //***************************************************************************
482 {
483 if (++this->itr == this->itr_end)
484 {
485 this->itr = this->itr_begin;
486 }
487
488 return *this;
489 }
490
491 //***************************************************************************
493 //***************************************************************************
495 {
497
498 ++(*this);
499
500 return (original);
501 }
502
503 //***************************************************************************
505 //***************************************************************************
507 {
508 if (this->itr == this->itr_begin)
509 {
510 typename etl::reverse_iterator<TIterator> ritr(this->itr_end);
511 ++ritr;
512 this->itr = ritr.base();
513 }
514 else
515 {
516 --this->itr;
517 }
518
519 return *this;
520 }
521
522 //***************************************************************************
524 //***************************************************************************
526 {
528
529 --(*this);
530
531 return (original);
532 }
533
534 //***************************************************************************
536 //***************************************************************************
537 ETL_CONSTEXPR14 circular_iterator_impl& operator +=(difference_type offset)
538 {
539 const difference_type length = difference_type(this->size());
540 offset %= length;
541
542 if (offset != 0)
543 {
544 const difference_type distance_from_begin = etl::distance(this->itr_begin, this->itr);
545 const difference_type distance_to_end = etl::distance(this->itr, this->itr_end);
546
547 if (offset > 0)
548 {
549 if (distance_to_end > offset)
550 {
551 offset = distance_from_begin + offset;
552 }
553 else
554 {
555 offset = offset - distance_to_end;
556 }
557 }
558 else
559 {
560 offset = -offset;
561
562 if (distance_from_begin >= offset)
563 {
564 offset = distance_from_begin - offset;
565 }
566 else
567 {
568 offset = offset - distance_from_begin;
569 offset = length - offset;
570 }
571 }
572
573 this->itr = this->itr_begin + offset;
574 }
575
576 return *this;
577 }
578
579 //***************************************************************************
581 //***************************************************************************
582 ETL_CONSTEXPR14 circular_iterator_impl& operator -=(typename etl::iterator_traits<TIterator>::difference_type offset)
583 {
584 return operator +=(-offset);
585 }
586 };
587 }
588
589 //***************************************************************************
593 //**************************************************************************
594 template <typename TIterator>
595 class circular_iterator ETL_FINAL
596 : public etl::private_circular_iterator::circular_iterator_impl<TIterator, typename etl::iterator_traits<TIterator>::iterator_category>
597 {
598 private:
599
601
602 public:
603
604 using impl_t::operator=;
605
606 typedef typename impl_t::value_type value_type;
607 typedef typename impl_t::difference_type difference_type;
608 typedef typename impl_t::pointer pointer;
609 typedef typename impl_t::reference reference;
610 typedef typename impl_t::iterator_category iterator_category;
611
612 //***************************************************************************
614 //***************************************************************************
615 ETL_CONSTEXPR14 circular_iterator()
616 : impl_t()
617 {
618 }
619
620 //***************************************************************************
622 //***************************************************************************
627
628 //***************************************************************************
630 //***************************************************************************
635
636 //***************************************************************************
638 //***************************************************************************
639 ETL_CONSTEXPR14 circular_iterator(const circular_iterator& other)
640 : impl_t(other)
641 {
642 }
643
644 //***************************************************************************
646 //***************************************************************************
647 ETL_CONSTEXPR14 circular_iterator& operator =(const circular_iterator& other)
648 {
649 impl_t::operator=(other);
650
651 return *this;
652 }
653 };
654
655 //*****************************************************************************
657 //*****************************************************************************
658 template <typename TIterator>
660 typename etl::iterator_traits<TIterator>::difference_type offset)
661 {
663 result += offset;
664
665 return result;
666 }
667
668 //*****************************************************************************
670 //*****************************************************************************
671 template <typename TIterator>
673 typename etl::iterator_traits<TIterator>::difference_type offset)
674 {
676 result -= offset;
677
678 return result;
679 }
680
681 //*****************************************************************************
683 //*****************************************************************************
684 template <typename TIterator>
685 ETL_CONSTEXPR14 typename etl::iterator_traits<TIterator>::difference_type operator -(etl::circular_iterator<TIterator>& lhs,
687 {
688 return TIterator(lhs) - TIterator(rhs);
689 }
690
691 //*****************************************************************************
693 //*****************************************************************************
694 template <typename TIterator>
697 {
698 return TIterator(lhs) == TIterator(rhs);
699 }
700
701 //*****************************************************************************
703 //*****************************************************************************
704 template <typename TIterator>
707 {
708 return TIterator(lhs) == rhs;
709 }
710
711 //*****************************************************************************
713 //*****************************************************************************
714 template <typename TIterator>
715 ETL_CONSTEXPR14 bool operator ==(TIterator lhs,
717 {
718 return lhs == TIterator(rhs);
719 }
720
721
722 //*****************************************************************************
724 //*****************************************************************************
725 template <typename TIterator>
728 {
729 return !(lhs == rhs);
730 }
731
732 //*****************************************************************************
734 //*****************************************************************************
735 template <typename TIterator>
738 {
739 return !(lhs == rhs);
740 }
741
742 //*****************************************************************************
744 //*****************************************************************************
745 template <typename TIterator>
746 ETL_CONSTEXPR14 bool operator !=(TIterator& lhs,
748 {
749 return !(lhs == rhs);
750 }
751}
752
753#endif
Common circular iterator implementation.
Definition circular_iterator.h:50
ETL_CONSTEXPR14 TIterator current() const
Conversion to base iterator type.
Definition circular_iterator.h:176
ETL_CONSTEXPR14 value_type operator*()
Dereference operator.
Definition circular_iterator.h:136
TIterator itr_end
The underlying end iterator.
Definition circular_iterator.h:184
ETL_CONSTEXPR14 bool empty() const
Is there nothing to iterate over?
Definition circular_iterator.h:128
ETL_CONSTEXPR14 TIterator operator->()
-> operator.
Definition circular_iterator.h:152
ETL_CONSTEXPR14 circular_iterator_common(const circular_iterator_common &other)
Copy constructor.
Definition circular_iterator.h:82
ETL_CONSTEXPR14 circular_iterator_common()
Default constructor.
Definition circular_iterator.h:62
ETL_CONSTEXPR14 TIterator begin() const
Beginning of the range.
Definition circular_iterator.h:104
ETL_CONSTEXPR14 circular_iterator_common(TIterator itr_begin_, TIterator itr_end_, TIterator start_)
Construct from iterators.
Definition circular_iterator.h:72
TIterator itr_begin
The underlying begin iterator.
Definition circular_iterator.h:183
ETL_CONSTEXPR14 TIterator end() const
End of the range.
Definition circular_iterator.h:112
ETL_CONSTEXPR14 size_t size() const
How long is the range?
Definition circular_iterator.h:120
TIterator itr
The underlying iterator.
Definition circular_iterator.h:185
ETL_CONSTEXPR14 circular_iterator_common & operator=(const circular_iterator_common &other)
Assignment.
Definition circular_iterator.h:92
ETL_CONSTEXPR14 circular_iterator_impl(const circular_iterator_impl &other)
Copy constructor.
Definition circular_iterator.h:463
ETL_CONSTEXPR14 circular_iterator()
Default constructor.
Definition circular_iterator.h:615
ETL_CONSTEXPR14 circular_iterator_impl(TIterator itr_begin_, TIterator itr_end_, TIterator start_)
Construct from start + iterators.
Definition circular_iterator.h:333
ETL_CONSTEXPR14 circular_iterator_impl(const circular_iterator_impl &other)
Copy constructor.
Definition circular_iterator.h:341
ETL_CONSTEXPR14 circular_iterator_impl(TIterator itr_begin_, TIterator itr_end_, TIterator start_)
Construct from start + iterators.
Definition circular_iterator.h:242
ETL_CONSTEXPR14 circular_iterator(const circular_iterator &other)
Copy constructor.
Definition circular_iterator.h:639
ETL_CONSTEXPR14 circular_iterator_impl(TIterator itr_begin_, TIterator itr_end_, TIterator start_)
Construct from start + iterators.
Definition circular_iterator.h:455
ETL_CONSTEXPR14 circular_iterator(TIterator itr_begin_, TIterator itr_end_)
Construct from iterators.
Definition circular_iterator.h:623
ETL_CONSTEXPR14 circular_iterator_impl(const circular_iterator_impl &other)
Copy constructor.
Definition circular_iterator.h:250
ETL_CONSTEXPR14 circular_iterator_impl()
Default constructor.
Definition circular_iterator.h:317
ETL_CONSTEXPR14 circular_iterator_impl()
Default constructor.
Definition circular_iterator.h:226
ETL_CONSTEXPR14 circular_iterator_impl(TIterator itr_begin_, TIterator itr_end_)
Construct from iterators.
Definition circular_iterator.h:234
ETL_CONSTEXPR14 circular_iterator_impl(TIterator itr_begin_, TIterator itr_end_)
Construct from iterators.
Definition circular_iterator.h:325
ETL_CONSTEXPR14 circular_iterator_impl(TIterator itr_begin_, TIterator itr_end_)
Construct from iterators.
Definition circular_iterator.h:447
ETL_CONSTEXPR14 circular_iterator(TIterator itr_begin_, TIterator itr_end_, TIterator start_)
Construct from start + iterators.
Definition circular_iterator.h:631
ETL_CONSTEXPR14 circular_iterator_impl()
Default constructor.
Definition circular_iterator.h:439
Definition circular_iterator.h:597
is_same
Definition type_traits_generator.h:1036
bitset_ext
Definition absolute.h:38
ETL_CONSTEXPR14 etl::circular_iterator< TIterator > operator-(etl::circular_iterator< TIterator > &lhs, typename etl::iterator_traits< TIterator >::difference_type offset)
Definition circular_iterator.h:672
bool operator!=(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition array.h:654
ETL_CONSTEXPR TContainer::size_type size(const TContainer &container)
Definition iterator.h:1187
bool operator==(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition array.h:642
ETL_CONSTEXPR14 etl::circular_iterator< TIterator > operator+(etl::circular_iterator< TIterator > &lhs, typename etl::iterator_traits< TIterator >::difference_type offset)
Definition circular_iterator.h:659
Definition iterator.h:53
Definition iterator.h:52
iterator
Definition iterator.h:399
pair holds two objects of arbitrary type
Definition utility.h:164
Definition iterator.h:54