Embedded Template Library 1.0
Loading...
Searching...
No Matches
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) 2017 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_ITERATOR_INCLUDED
32#define ETL_ITERATOR_INCLUDED
33
34#include "platform.h"
35#include "invoke.h"
36#include "type_traits.h"
37#include "utility.h"
38#include "private/addressof.h"
39
40#if ETL_USING_STL || defined(ETL_IN_UNIT_TEST)
41 #include <iterator>
42#endif
43
46
47namespace etl
48{
49 //***************************************************************************
50 // iterator tags
52 {
53 };
55 {
56 };
58 {
59 };
66 // struct contiguous_iterator_tag : public random_access_iterator_tag {};
67
68 //***************************************************************************
69 // iterator_traits
70
71 // For anything not a fundamental type.
72 template <typename TIterator, typename = typename etl::enable_if< !etl::is_fundamental<TIterator>::value, void>::type>
74 {
75 typedef typename TIterator::iterator_category iterator_category;
76 typedef typename TIterator::value_type value_type;
77 typedef typename TIterator::difference_type difference_type;
78 typedef typename TIterator::pointer pointer;
79 typedef typename TIterator::reference reference;
80 };
81
82 // For pointers.
83 template <typename T>
84 struct iterator_traits<T*, void>
85 {
86 typedef ETL_OR_STD::random_access_iterator_tag iterator_category;
87 typedef T value_type;
88 typedef ptrdiff_t difference_type;
89 typedef typename etl::remove_cv<T>::type* pointer;
90 typedef T& reference;
91 };
92
93 // For const pointers.
94 template <typename T>
95 struct iterator_traits<const T*, void>
96 {
97 typedef ETL_OR_STD::random_access_iterator_tag iterator_category;
98 typedef T value_type;
99 typedef ptrdiff_t difference_type;
100 typedef const typename etl::remove_cv<T>::type* pointer;
101 typedef const T& reference;
102 };
103
104 //***************************************************************************
105 // advance
106 template <typename TIterator, typename TDistance>
107 ETL_CONSTEXPR14 void advance_helper(TIterator& itr, TDistance n, ETL_OR_STD::input_iterator_tag)
108 {
109 while (n-- > 0)
110 {
111 ++itr;
112 }
113 }
114
115 template <typename TIterator, typename TDistance>
116 ETL_CONSTEXPR14 void advance_helper(TIterator& itr, TDistance n, ETL_OR_STD::output_iterator_tag)
117 {
118 while (n-- > 0)
119 {
120 ++itr;
121 }
122 }
123
124 template <typename TIterator, typename TDistance>
125 ETL_CONSTEXPR14 void advance_helper(TIterator& itr, TDistance n, ETL_OR_STD::forward_iterator_tag)
126 {
127 while (n-- > 0)
128 {
129 ++itr;
130 }
131 }
132
133 template <typename TIterator, typename TDistance>
134 ETL_CONSTEXPR14 void advance_helper(TIterator& itr, TDistance n, ETL_OR_STD::bidirectional_iterator_tag)
135 {
136 if (n > 0)
137 {
138 while (n--)
139 {
140 ++itr;
141 }
142 }
143 else
144 {
145 while (n++)
146 {
147 --itr;
148 }
149 }
150 }
151
152 template <typename TIterator, typename TDistance>
153 ETL_CONSTEXPR14 void advance_helper(TIterator& itr, TDistance n, ETL_OR_STD::random_access_iterator_tag)
154 {
155 typedef typename etl::iterator_traits<TIterator>::difference_type diff_t;
156 itr += static_cast<diff_t>(n);
157 }
158
159 template <typename TIterator, typename TDistance>
160 ETL_CONSTEXPR14 void advance(TIterator& itr, TDistance n)
161 {
162 typedef typename etl::iterator_traits<TIterator>::iterator_category tag;
163
164 advance_helper(itr, n, tag());
165 }
166
167 //***************************************************************************
168 // distance
169 template <typename TIterator>
170 ETL_CONSTEXPR14 typename etl::iterator_traits<TIterator>::difference_type distance_helper(TIterator first, TIterator last, ETL_OR_STD::input_iterator_tag)
171 {
172 typename etl::iterator_traits<TIterator>::difference_type d = 0;
173
174 while (first != last)
175 {
176 ++d;
177 ++first;
178 }
179
180 return d;
181 }
182
183 template <typename TIterator>
184 ETL_CONSTEXPR14 typename etl::iterator_traits<TIterator>::difference_type distance_helper(TIterator first, TIterator last,
185 ETL_OR_STD::forward_iterator_tag)
186 {
187 typename etl::iterator_traits<TIterator>::difference_type d = 0;
188
189 while (first != last)
190 {
191 ++d;
192 ++first;
193 }
194
195 return d;
196 }
197
198 template <typename TIterator>
199 ETL_CONSTEXPR14 typename etl::iterator_traits<TIterator>::difference_type distance_helper(TIterator first, TIterator last,
200 ETL_OR_STD::bidirectional_iterator_tag)
201 {
202 typename etl::iterator_traits<TIterator>::difference_type d = 0;
203
204 while (first != last)
205 {
206 ++d;
207 ++first;
208 }
209
210 return d;
211 }
212
213 template <typename TIterator>
214 ETL_CONSTEXPR14 typename etl::iterator_traits<TIterator>::difference_type distance_helper(TIterator first, TIterator last,
215 ETL_OR_STD::random_access_iterator_tag)
216 {
217 return last - first;
218 }
219
220 template <typename TIterator>
221 ETL_CONSTEXPR14 typename etl::iterator_traits<TIterator>::difference_type distance(TIterator first, TIterator last)
222 {
223 typedef typename etl::iterator_traits<TIterator>::iterator_category tag;
224
225 return distance_helper(first, last, tag());
226 }
227
228 //***************************************************************************
229 // Previous
230 template <typename TIterator>
231 ETL_CONSTEXPR14 TIterator prev(TIterator itr, typename etl::iterator_traits<TIterator>::difference_type n = 1)
232 {
233 etl::advance(itr, -n);
234
235 return itr;
236 }
237
238 //***************************************************************************
239 // Next
240 template <typename TIterator>
241 ETL_CONSTEXPR14 TIterator next(TIterator itr, typename etl::iterator_traits<TIterator>::difference_type n = 1)
242 {
243 etl::advance(itr, n);
244
245 return itr;
246 }
247
248 //***************************************************************************
249 // reverse_iterator
250 template <typename TIterator>
251 class reverse_iterator
252 {
253 public:
254
255 typedef typename iterator_traits<TIterator>::iterator_category iterator_category;
256 typedef typename iterator_traits<TIterator>::value_type value_type;
257 typedef typename iterator_traits<TIterator>::difference_type difference_type;
258 typedef typename iterator_traits<TIterator>::pointer pointer;
259 typedef typename iterator_traits<TIterator>::reference reference;
260
261 typedef TIterator iterator_type;
262
263 ETL_CONSTEXPR14 reverse_iterator()
264 : current()
265 {
266 }
267
268 ETL_CONSTEXPR14 explicit reverse_iterator(TIterator itr)
269 : current(itr)
270 {
271 }
272
273 template <typename TOther>
274 ETL_CONSTEXPR14 reverse_iterator(const reverse_iterator<TOther>& other)
275 : current(other.base())
276 {
277 }
278
279 template <class TOther>
280 ETL_CONSTEXPR14 reverse_iterator& operator=(const reverse_iterator<TOther>& other)
281 {
282 current = other.base();
283
284 return (*this);
285 }
286
287 ETL_CONSTEXPR14 TIterator base() const
288 {
289 return current;
290 }
291
292 ETL_NODISCARD ETL_CONSTEXPR14 reference operator*() const
293 {
294 TIterator temp = current;
295
296 return *(--temp);
297 }
298
299 ETL_NODISCARD ETL_CONSTEXPR14 pointer operator->() const
300 {
301 TIterator temp = current;
302
303 return &(*--temp);
304 }
305
306 ETL_CONSTEXPR14 reverse_iterator& operator++()
307 {
308 --current;
309
310 return *this;
311 }
312
313 ETL_CONSTEXPR14 reverse_iterator operator++(int)
314 {
315 reverse_iterator temp = *this;
316 --current;
317
318 return temp;
319 }
320
321 ETL_CONSTEXPR14 reverse_iterator& operator--()
322 {
323 ++current;
324
325 return (*this);
326 }
327
328 ETL_CONSTEXPR14 reverse_iterator operator--(int)
329 {
330 reverse_iterator temp = *this;
331 ++current;
332
333 return temp;
334 }
335
336 ETL_CONSTEXPR14 reverse_iterator& operator+=(const difference_type offset)
337 {
338 current -= offset;
339
340 return (*this);
341 }
342
343 ETL_CONSTEXPR14 reverse_iterator& operator-=(const difference_type offset)
344 {
345 current += offset;
346
347 return (*this);
348 }
349
350 ETL_NODISCARD ETL_CONSTEXPR14 reverse_iterator operator+(const difference_type offset) const
351 {
352 return reverse_iterator(current - offset);
353 }
354
355 ETL_NODISCARD ETL_CONSTEXPR14 reverse_iterator operator-(const difference_type offset) const
356 {
357 return (reverse_iterator(current + offset));
358 }
359
360 ETL_NODISCARD ETL_CONSTEXPR14 reference operator[](const difference_type offset) const
361 {
362 return (*(*this + offset));
363 }
364
365 protected:
366
367 TIterator current;
368 };
369
370 template <typename TIterator>
371 ETL_CONSTEXPR14 bool operator==(const reverse_iterator<TIterator>& lhs, const reverse_iterator<TIterator>& rhs)
372 {
373 return lhs.base() == rhs.base();
374 }
375
376 template <typename TIterator>
377 ETL_CONSTEXPR14 bool operator!=(const reverse_iterator<TIterator>& lhs, const reverse_iterator<TIterator>& rhs)
378 {
379 return !(lhs == rhs);
380 }
381
382 template <typename TIterator>
383 ETL_CONSTEXPR14 bool operator<(const reverse_iterator<TIterator>& lhs, const reverse_iterator<TIterator>& rhs)
384 {
385 return rhs.base() < lhs.base();
386 }
387
388 template <typename TIterator>
389 ETL_CONSTEXPR14 bool operator>(const reverse_iterator<TIterator>& lhs, const reverse_iterator<TIterator>& rhs)
390 {
391 return rhs < lhs;
392 }
393
394 template <typename TIterator>
395 ETL_CONSTEXPR14 bool operator<=(const reverse_iterator<TIterator>& lhs, const reverse_iterator<TIterator>& rhs)
396 {
397 return !(rhs < lhs);
398 }
399
400 template <typename TIterator>
401 ETL_CONSTEXPR14 bool operator>=(const reverse_iterator<TIterator>& lhs, const reverse_iterator<TIterator>& rhs)
402 {
403 return !(lhs < rhs);
404 }
405
406 template <typename TIterator>
407 ETL_CONSTEXPR14 typename reverse_iterator<TIterator>::difference_type operator-(const reverse_iterator<TIterator>& lhs,
409 {
410 return rhs.base() - lhs.base();
411 }
412
413 template <typename TIterator, class TDifference>
414 ETL_CONSTEXPR14 reverse_iterator<TIterator> operator+(TDifference n, const reverse_iterator<TIterator>& itr)
415 {
416 return itr.operator+(n);
417 }
418
419 //***************************************************************************
421 //***************************************************************************
422 template <typename TCategory, typename T, typename TDistance = ptrdiff_t, typename TPointer = T*, typename TReference = T& >
423 struct iterator
424 {
425 typedef T value_type;
426 typedef TDistance difference_type;
427 typedef TPointer pointer;
428 typedef TReference reference;
429 typedef TCategory iterator_category;
430 };
431
432#if ETL_USING_CPP11
433 //***************************************************************************
434 // move_iterator
435 template <typename TIterator>
436 class move_iterator
437 {
438 public:
439
440 typedef typename iterator_traits<TIterator>::iterator_category iterator_category;
441 typedef typename iterator_traits<TIterator>::value_type value_type;
442 typedef typename iterator_traits<TIterator>::difference_type difference_type;
443 typedef TIterator iterator_type;
444 typedef TIterator pointer;
445 typedef value_type&& reference;
446
447 move_iterator() {}
448
449 explicit move_iterator(TIterator itr)
450 : current(itr)
451 {
452 }
453
454 template <typename U>
455 move_iterator(const move_iterator<U>& itr)
456 : current(itr.base())
457 {
458 }
459
460 template <typename U>
461 move_iterator& operator=(const move_iterator<U>& itr)
462 {
463 current = itr.current;
464 return *this;
465 }
466
467 iterator_type base() const
468 {
469 return current;
470 }
471
472 pointer operator->() const
473 {
474 return current;
475 }
476
477 reference operator*() const
478 {
479 return etl::move(*current);
480 }
481
482 move_iterator& operator++()
483 {
484 ++current;
485 return *this;
486 }
487
488 move_iterator& operator--()
489 {
490 --current;
491 return *this;
492 }
493
494 move_iterator operator++(int)
495 {
496 move_iterator temp = *this;
497 ++current;
498 return temp;
499 }
500
501 move_iterator operator--(int)
502 {
503 move_iterator temp = *this;
504 --current;
505 return temp;
506 }
507
508 move_iterator operator+(difference_type n) const
509 {
510 return move_iterator(current + n);
511 }
512
513 move_iterator operator-(difference_type n) const
514 {
515 return move_iterator(current - n);
516 }
517
518 move_iterator operator+=(difference_type n)
519 {
520 current += n;
521 return *this;
522 }
523
524 move_iterator operator-=(difference_type n)
525 {
526 current -= n;
527 return *this;
528 }
529
530 reference operator[](difference_type n) const
531 {
532 return etl::move(current[n]);
533 }
534
535 private:
536
537 TIterator current;
538 };
539
540 template <typename TIterator>
541 bool operator==(const etl::move_iterator<TIterator>& lhs, const etl::move_iterator<TIterator>& rhs)
542 {
543 return lhs.base() == rhs.base();
544 }
545
546 template <typename TIterator>
547 bool operator!=(const etl::move_iterator<TIterator>& lhs, const etl::move_iterator<TIterator>& rhs)
548 {
549 return !(lhs == rhs);
550 }
551
552 template <typename TIterator>
553 bool operator<(const etl::move_iterator<TIterator>& lhs, const etl::move_iterator<TIterator>& rhs)
554 {
555 return lhs.base() < rhs.base();
556 }
557
558 template <typename TIterator>
559 bool operator<=(const etl::move_iterator<TIterator>& lhs, const etl::move_iterator<TIterator>& rhs)
560 {
561 return !(rhs < lhs);
562 }
563
564 template <typename TIterator>
565 bool operator>(const etl::move_iterator<TIterator>& lhs, const etl::move_iterator<TIterator>& rhs)
566 {
567 return (rhs < lhs);
568 }
569
570 template <typename TIterator>
571 bool operator>=(const etl::move_iterator<TIterator>& lhs, const etl::move_iterator<TIterator>& rhs)
572 {
573 return !(lhs < rhs);
574 }
575
576 template <typename TIterator>
577 move_iterator<TIterator> operator+(typename move_iterator<TIterator>::difference_type n, const move_iterator<TIterator>& rhs)
578 {
579 return rhs + n;
580 }
581
582 template <typename TIterator1, typename TIterator2 >
583 auto operator-(const move_iterator<TIterator1>& lhs, const move_iterator<TIterator2>& rhs) -> decltype(lhs.base() - rhs.base())
584 {
585 return lhs.base() - rhs.base();
586 }
587
588 template <typename TIterator>
589 etl::move_iterator<TIterator> make_move_iterator(TIterator itr)
590 {
591 return etl::move_iterator<TIterator>(itr);
592 }
593
594#endif // ETL_USING_CPP11
595
596 //***************************************************************************
597 // back_insert_iterator
598 //***************************************************************************
599
600 //***************************************************************************
602 //***************************************************************************
603 template <typename TContainer>
604 class back_insert_iterator : public etl::iterator<ETL_OR_STD::output_iterator_tag, void, void, void, void>
605 {
606 public:
607
608 typedef TContainer container_type;
609
610 //***************************************************************************
612 //***************************************************************************
613 explicit ETL_CONSTEXPR14 back_insert_iterator(TContainer& c)
614 : container(etl::addressof(c))
615 {
616 }
617
618 //***************************************************************************
620 //***************************************************************************
621 ETL_CONSTEXPR14 back_insert_iterator& operator=(const typename TContainer::value_type& value)
622 {
623 container->push_back(value);
624
625 return (*this);
626 }
627
628#if ETL_USING_CPP11
629 //***************************************************************************
631 //***************************************************************************
632 ETL_CONSTEXPR14 back_insert_iterator& operator=(typename TContainer::value_type&& value)
633 {
634 container->push_back(etl::move(value));
635
636 return (*this);
637 }
638#endif // ETL_USING_CPP11
639
640 //***************************************************************************
642 //***************************************************************************
643 ETL_NODISCARD ETL_CONSTEXPR14 back_insert_iterator& operator*()
644 {
645 return (*this);
646 }
647
648 //***************************************************************************
650 //***************************************************************************
652 {
653 return (*this);
654 }
655
656 //***************************************************************************
658 //***************************************************************************
659 ETL_CONSTEXPR14 back_insert_iterator operator++(int)
660 {
661 return (*this);
662 }
663
664 protected:
665
666 TContainer* container;
667 };
668
669 //***************************************************************************
671 //***************************************************************************
672 template <typename TContainer>
673 ETL_NODISCARD ETL_CONSTEXPR14 etl::back_insert_iterator<TContainer> back_inserter(TContainer& container)
674 {
676 }
677
678 //***************************************************************************
679 // front_insert_iterator
680 //***************************************************************************
681
682 //***************************************************************************
684 //***************************************************************************
685 template <typename TContainer>
686 class front_insert_iterator : public etl::iterator<ETL_OR_STD::output_iterator_tag, void, void, void, void>
687 {
688 public:
689
690 typedef TContainer container_type;
691
692 //***************************************************************************
694 //***************************************************************************
695 explicit ETL_CONSTEXPR14 front_insert_iterator(TContainer& c)
696 : container(etl::addressof(c))
697 {
698 }
699
700 //***************************************************************************
702 //***************************************************************************
703 ETL_CONSTEXPR14 front_insert_iterator& operator=(const typename TContainer::value_type& value)
704 {
705 container->push_front(value);
706 return (*this);
707 }
708
709#if ETL_USING_CPP11
710 //***************************************************************************
712 //***************************************************************************
713 ETL_CONSTEXPR14 front_insert_iterator& operator=(typename TContainer::value_type&& value)
714 {
715 container->push_front(etl::move(value));
716 return (*this);
717 }
718#endif // ETL_USING_CPP11
719
720 //***************************************************************************
722 //***************************************************************************
723 ETL_NODISCARD ETL_CONSTEXPR14 front_insert_iterator& operator*()
724 {
725 return (*this);
726 }
727
728 //***************************************************************************
730 //***************************************************************************
732 {
733 return (*this);
734 }
735
736 //***************************************************************************
738 //***************************************************************************
740 {
741 return (*this);
742 }
743
744 protected:
745
746 TContainer* container;
747 };
748
749 //***************************************************************************
751 //***************************************************************************
752 template <typename TContainer>
753 ETL_NODISCARD ETL_CONSTEXPR14 etl::front_insert_iterator<TContainer> front_inserter(TContainer& container)
754 {
756 }
757
758 //***************************************************************************
759 // push_insert_iterator
760 //***************************************************************************
761
762 //***************************************************************************
764 //***************************************************************************
765 template <typename TContainer>
766 class push_insert_iterator : public etl::iterator<ETL_OR_STD::output_iterator_tag, void, void, void, void>
767 {
768 public:
769
770 typedef TContainer container_type;
771
772 //***************************************************************************
774 //***************************************************************************
775 explicit ETL_CONSTEXPR14 push_insert_iterator(TContainer& c)
776 : container(etl::addressof(c))
777 {
778 }
779
780 //***************************************************************************
782 //***************************************************************************
783 ETL_CONSTEXPR14 push_insert_iterator& operator=(const typename TContainer::value_type& value)
784 {
785 container->push(value);
786
787 return (*this);
788 }
789
790#if ETL_USING_CPP11
791 //***************************************************************************
793 //***************************************************************************
794 ETL_CONSTEXPR14 push_insert_iterator& operator=(typename TContainer::value_type&& value)
795 {
796 container->push(etl::move(value));
797
798 return (*this);
799 }
800#endif // ETL_USING_CPP11
801
802 //***************************************************************************
804 //***************************************************************************
805 ETL_NODISCARD ETL_CONSTEXPR14 push_insert_iterator& operator*()
806 {
807 return (*this);
808 }
809
810 //***************************************************************************
812 //***************************************************************************
814 {
815 return (*this);
816 }
817
818 //***************************************************************************
820 //***************************************************************************
821 ETL_CONSTEXPR14 push_insert_iterator operator++(int)
822 {
823 return (*this);
824 }
825
826 protected:
827
828 TContainer* container;
829 };
830
831 //***************************************************************************
833 //***************************************************************************
834 template <typename TContainer>
835 ETL_NODISCARD ETL_CONSTEXPR14 etl::push_insert_iterator<TContainer> push_inserter(TContainer& container)
836 {
838 }
839
840 //***************************************************************************
841 // Helper templates.
842 //***************************************************************************
843 template <typename T>
845 {
846 static ETL_CONSTANT bool value = etl::is_same<typename etl::iterator_traits<T>::iterator_category, ETL_OR_STD::input_iterator_tag>::value;
847 };
848
849 template <typename T>
850 ETL_CONSTANT bool is_input_iterator<T>::value;
851
852 template <typename T>
854 {
855 static ETL_CONSTANT bool value = etl::is_same<typename etl::iterator_traits<T>::iterator_category, ETL_OR_STD::output_iterator_tag>::value;
856 };
857
858 template <typename T>
859 ETL_CONSTANT bool is_output_iterator<T>::value;
860
861 template <typename T>
863 {
864 static ETL_CONSTANT bool value = etl::is_same<typename etl::iterator_traits<T>::iterator_category, ETL_OR_STD::forward_iterator_tag>::value;
865 };
866
867 template <typename T>
868 ETL_CONSTANT bool is_forward_iterator<T>::value;
869
870 template <typename T>
872 {
873 static ETL_CONSTANT bool value = etl::is_same<typename etl::iterator_traits<T>::iterator_category, ETL_OR_STD::bidirectional_iterator_tag>::value;
874 };
875
876 template <typename T>
877 ETL_CONSTANT bool is_bidirectional_iterator<T>::value;
878
879 // Deprecated
880 template <typename T>
882 {
883 static ETL_CONSTANT bool value = etl::is_same<typename etl::iterator_traits<T>::iterator_category, ETL_OR_STD::random_access_iterator_tag>::value;
884 };
885
886 template <typename T>
887 ETL_CONSTANT bool is_random_iterator<T>::value;
888
889 template <typename T>
891 {
892 static ETL_CONSTANT bool value = etl::is_same<typename etl::iterator_traits<T>::iterator_category, ETL_OR_STD::random_access_iterator_tag>::value;
893 };
894
895 template <typename T>
896 ETL_CONSTANT bool is_random_access_iterator<T>::value;
897
898 template <typename T>
900 {
901 static
902 ETL_CONSTANT bool value = etl::is_input_iterator<T>::value || etl::is_forward_iterator<T>::value || etl::is_bidirectional_iterator<T>::value
903 || etl::is_random_iterator<T>::value;
904 };
905
906 template <typename T>
907 ETL_CONSTANT bool is_input_iterator_concept<T>::value;
908
909 template <typename T>
911 {
912 static
913 ETL_CONSTANT bool value = etl::is_output_iterator<T>::value || etl::is_forward_iterator<T>::value || etl::is_bidirectional_iterator<T>::value
914 || etl::is_random_iterator<T>::value;
915 };
916
917 template <typename T>
918 ETL_CONSTANT bool is_output_iterator_concept<T>::value;
919
920 template <typename T>
922 {
923 static
924 ETL_CONSTANT bool value = etl::is_forward_iterator<T>::value || etl::is_bidirectional_iterator<T>::value || etl::is_random_iterator<T>::value;
925 };
926
927 template <typename T>
928 ETL_CONSTANT bool is_forward_iterator_concept<T>::value;
929
930 template <typename T>
932 {
933 static ETL_CONSTANT bool value = etl::is_bidirectional_iterator<T>::value || etl::is_random_iterator<T>::value;
934 };
935
936 template <typename T>
937 ETL_CONSTANT bool is_bidirectional_iterator_concept<T>::value;
938
939 // Deprecated
940 template <typename T>
942 {
943 static ETL_CONSTANT bool value = etl::is_random_iterator<T>::value;
944 };
945
946 // Deprecated
947 template <typename T>
948 ETL_CONSTANT bool is_random_iterator_concept<T>::value;
949
950 // Deprecated
951 template <typename T>
953 {
954 static ETL_CONSTANT bool value = etl::is_random_access_iterator<T>::value;
955 };
956
957 // Deprecated
958 template <typename T>
959 ETL_CONSTANT bool is_random_access_iterator_concept<T>::value;
960
961#if ETL_NOT_USING_STL || ETL_CPP11_NOT_SUPPORTED
962 //*****************************************************************************
965 //*****************************************************************************
966 template <typename TContainer>
967 ETL_CONSTEXPR typename TContainer::iterator begin(TContainer& container)
968 {
969 return container.begin();
970 }
971
972 //*****************************************************************************
975 //*****************************************************************************
976 template <typename TContainer>
977 ETL_CONSTEXPR typename TContainer::const_iterator begin(const TContainer& container)
978 {
979 return container.begin();
980 }
981
982 //*****************************************************************************
985 //*****************************************************************************
986 template <typename TContainer>
987 ETL_CONSTEXPR typename TContainer::const_iterator cbegin(const TContainer& container)
988 {
989 return container.cbegin();
990 }
991
992 //*****************************************************************************
995 //*****************************************************************************
996 template <typename TContainer>
997 ETL_CONSTEXPR typename TContainer::iterator end(TContainer& container)
998 {
999 return container.end();
1000 }
1001
1002 //*****************************************************************************
1005 //*****************************************************************************
1006 template <typename TContainer>
1007 ETL_CONSTEXPR typename TContainer::const_iterator end(const TContainer& container)
1008 {
1009 return container.end();
1010 }
1011
1012 //*****************************************************************************
1015 //*****************************************************************************
1016 template <typename TContainer>
1017 ETL_CONSTEXPR typename TContainer::const_iterator cend(const TContainer& container)
1018 {
1019 return container.cend();
1020 }
1021
1022 //*****************************************************************************
1025 //*****************************************************************************
1026 template <typename TValue, size_t Array_Size>
1027 ETL_CONSTEXPR TValue* begin(TValue (&data)[Array_Size])
1028 {
1029 return &data[0];
1030 }
1031
1032 //*****************************************************************************
1035 //*****************************************************************************
1036 template <typename TValue, size_t Array_Size>
1037 ETL_CONSTEXPR const TValue* begin(const TValue (&data)[Array_Size])
1038 {
1039 return &data[0];
1040 }
1041
1042 //*****************************************************************************
1045 //*****************************************************************************
1046 template <typename TValue, size_t Array_Size>
1047 ETL_CONSTEXPR const TValue* cbegin(const TValue (&data)[Array_Size])
1048 {
1049 return &data[0];
1050 }
1051
1052 //*****************************************************************************
1055 //*****************************************************************************
1056 template <typename TValue, size_t Array_Size>
1057 ETL_CONSTEXPR TValue* end(TValue (&data)[Array_Size])
1058 {
1059 return &data[Array_Size];
1060 }
1061
1062 //*****************************************************************************
1065 //*****************************************************************************
1066 template <typename TValue, size_t Array_Size>
1067 ETL_CONSTEXPR const TValue* end(const TValue (&data)[Array_Size])
1068 {
1069 return &data[Array_Size];
1070 }
1071
1072 //*****************************************************************************
1075 //*****************************************************************************
1076 template <typename TValue, size_t Array_Size>
1077 ETL_CONSTEXPR const TValue* cend(const TValue (&data)[Array_Size])
1078 {
1079 return &data[Array_Size];
1080 }
1081#endif
1082
1083#if ETL_NOT_USING_STL || ETL_CPP14_NOT_SUPPORTED
1084 //*****************************************************************************
1087 //*****************************************************************************
1088 template <typename TContainer>
1089 ETL_CONSTEXPR typename TContainer::reverse_iterator rbegin(TContainer& container)
1090 {
1091 return container.rbegin();
1092 }
1093
1094 //*****************************************************************************
1097 //*****************************************************************************
1098 template <typename TContainer>
1099 ETL_CONSTEXPR typename TContainer::const_reverse_iterator rbegin(const TContainer& container)
1100 {
1101 return container.rbegin();
1102 }
1103
1104 //*****************************************************************************
1107 //*****************************************************************************
1108 template <typename TContainer>
1109 ETL_CONSTEXPR typename TContainer::const_reverse_iterator crbegin(const TContainer& container)
1110 {
1111 return container.crbegin();
1112 }
1113
1114 //*****************************************************************************
1117 //*****************************************************************************
1118 template <typename TContainer>
1119 ETL_CONSTEXPR typename TContainer::reverse_iterator rend(TContainer& container)
1120 {
1121 return container.rend();
1122 }
1123
1124 //*****************************************************************************
1127 //*****************************************************************************
1128 template <typename TContainer>
1129 ETL_CONSTEXPR typename TContainer::const_reverse_iterator rend(const TContainer& container)
1130 {
1131 return container.rend();
1132 }
1133
1134 //*****************************************************************************
1137 //*****************************************************************************
1138 template <typename TContainer>
1139 ETL_CONSTEXPR typename TContainer::const_reverse_iterator crend(const TContainer& container)
1140 {
1141 return container.crend();
1142 }
1143
1144 //*****************************************************************************
1147 //*****************************************************************************
1148 template <typename TValue, size_t Array_Size>
1149 ETL_OR_STD::reverse_iterator<TValue*> rbegin(TValue (&data)[Array_Size])
1150 {
1151 return ETL_OR_STD::reverse_iterator<TValue*>(&data[Array_Size]);
1152 }
1153
1154 //*****************************************************************************
1157 //*****************************************************************************
1158 template <typename TValue, size_t Array_Size>
1159 ETL_CONSTEXPR ETL_OR_STD::reverse_iterator<const TValue*> crbegin(const TValue (&data)[Array_Size])
1160 {
1161 return ETL_OR_STD::reverse_iterator<const TValue*>(&data[Array_Size]);
1162 }
1163
1164 //*****************************************************************************
1167 //*****************************************************************************
1168 template <typename TValue, size_t Array_Size>
1169 ETL_CONSTEXPR ETL_OR_STD::reverse_iterator<TValue*> rend(TValue (&data)[Array_Size])
1170 {
1171 return ETL_OR_STD::reverse_iterator<TValue*>(&data[0]);
1172 }
1173
1174 //*****************************************************************************
1177 //*****************************************************************************
1178 template <typename TValue, size_t Array_Size>
1179 ETL_CONSTEXPR ETL_OR_STD::reverse_iterator<const TValue*> crend(const TValue (&data)[Array_Size])
1180 {
1181 return ETL_OR_STD::reverse_iterator<const TValue*>(&data[0]);
1182 }
1183#endif
1184
1185#if ETL_NOT_USING_STL || ETL_CPP17_NOT_SUPPORTED
1186 //**************************************************************************
1190 //**************************************************************************
1191 template <typename TContainer>
1192 ETL_CONSTEXPR typename TContainer::size_type size(const TContainer& container)
1193 {
1194 return container.size();
1195 }
1196
1202 template <typename TValue, size_t Array_Size>
1203 ETL_CONSTEXPR size_t size(TValue (&)[Array_Size])
1204 {
1205 return Array_Size;
1206 }
1207#endif
1208
1209 //**************************************************************************
1215 //**************************************************************************
1216 template <typename T, size_t Array_Size>
1217 char (&array_size(T (&array)[Array_Size]))[Array_Size];
1218
1219#define ETL_ARRAY_SIZE(a) sizeof(etl::array_size(a))
1220
1221#if ETL_NOT_USING_STL || ETL_CPP17_NOT_SUPPORTED
1222 //**************************************************************************
1226 //**************************************************************************
1227 template <typename TContainer>
1228 ETL_CONSTEXPR typename TContainer::pointer data(TContainer& container)
1229 {
1230 return container.data();
1231 }
1232
1233 //**************************************************************************
1237 //**************************************************************************
1238 template <typename TContainer>
1239 ETL_CONSTEXPR typename TContainer::const_pointer data(const TContainer& container)
1240 {
1241 return container.data();
1242 }
1243
1249 template <typename TValue, size_t Array_Size>
1250 ETL_CONSTEXPR TValue* data(TValue (&a)[Array_Size])
1251 {
1252 return a;
1253 }
1254
1260 template <typename TValue, size_t Array_Size>
1261 ETL_CONSTEXPR const TValue* data(const TValue (&a)[Array_Size])
1262 {
1263 return a;
1264 }
1265#endif
1266
1267#if ETL_USING_CPP17
1268 template <class T>
1269 using iter_value_t = typename etl::iterator_traits<etl::remove_cvref_t<T>>::value_type;
1270
1271 template <class T>
1272 using iter_reference_t = decltype(*etl::declval<T&>());
1273
1274 #if ETL_USING_CPP20
1275 template <class T>
1276 using iter_const_reference_t = typename etl::common_reference_t<const etl::iter_value_t<T>&&, etl::iter_reference_t<T>>;
1277 #endif
1278
1279 template <class T>
1280 using iter_difference_t = typename etl::iterator_traits<etl::remove_cvref_t<T>>::difference_type;
1281
1282 template <class I, class Proj>
1283 using projected_value_t = etl::remove_cvref_t<etl::invoke_result_t<Proj&, etl::iter_reference_t<I>>>;
1284
1285 namespace ranges
1286 {
1287 namespace private_ranges
1288 {
1289 struct begin
1290 {
1291 template <class T>
1292 constexpr auto operator()(T& t) const
1293 {
1294 return ETL_OR_STD::begin(t);
1295 }
1296 };
1297
1298 struct end
1299 {
1300 template <class T>
1301 constexpr auto operator()(T& t) const
1302 {
1303 return ETL_OR_STD::end(t);
1304 }
1305 };
1306
1307 struct cbegin
1308 {
1309 template <class T>
1310 constexpr auto operator()(T& t) const
1311 {
1312 return ETL_OR_STD::cbegin(t);
1313 }
1314 };
1315
1316 struct cend
1317 {
1318 template <class T>
1319 constexpr auto operator()(T& t) const
1320 {
1321 return ETL_OR_STD::cend(t);
1322 }
1323 };
1324
1325 struct rbegin
1326 {
1327 template <class T>
1328 constexpr auto operator()(T& t) const
1329 {
1330 return ETL_OR_STD::rbegin(t);
1331 }
1332 };
1333
1334 struct rend
1335 {
1336 template <class T>
1337 constexpr auto operator()(T& t) const
1338 {
1339 return ETL_OR_STD::rend(t);
1340 }
1341 };
1342
1343 struct crbegin
1344 {
1345 template <class T>
1346 constexpr auto operator()(T& t) const
1347 {
1348 return ETL_OR_STD::crbegin(t);
1349 }
1350 };
1351
1352 struct crend
1353 {
1354 template <class T>
1355 constexpr auto operator()(T& t) const
1356 {
1357 return ETL_OR_STD::crend(t);
1358 }
1359 };
1360
1361 template <class T, class = void>
1362 struct has_size_member : etl::false_type
1363 {
1364 };
1365
1366 template <class T>
1367 struct has_size_member< T, etl::void_t<decltype(etl::declval<const T&>().size())>> : etl::true_type
1368 {
1369 };
1370
1371 template <class T, class = void>
1372 struct has_empty_member : etl::false_type
1373 {
1374 };
1375
1376 template <class T>
1377 struct has_empty_member< T, etl::void_t<decltype(etl::declval<const T&>().empty())>> : etl::true_type
1378 {
1379 };
1380
1381 struct distance
1382 {
1383 // Overload for common ranges (iterator == sentinel type)
1384 template <typename I, typename = etl::enable_if_t< etl::is_input_iterator_concept<I>::value || etl::is_output_iterator_concept<I>::value>>
1385 constexpr etl::iter_difference_t<I> operator()(I first, I last) const
1386 {
1387 if constexpr (etl::is_random_access_iterator_concept<I>::value)
1388 {
1389 return last - first;
1390 }
1391 else
1392 {
1393 etl::iter_difference_t<I> n = 0;
1394 while (!(first == last))
1395 {
1396 ++first;
1397 ++n;
1398 }
1399 return n;
1400 }
1401 }
1402
1403 // Overload for non-common ranges (iterator != sentinel type)
1404 template <typename I, typename S,
1405 typename = etl::enable_if_t< (etl::is_input_iterator_concept<I>::value || etl::is_output_iterator_concept<I>::value)
1406 && !etl::is_same<I, S>::value>>
1407 constexpr etl::iter_difference_t<I> operator()(I first, S last) const
1408 {
1409 etl::iter_difference_t<I> n = 0;
1410 while (!(first == last))
1411 {
1412 ++first;
1413 ++n;
1414 }
1415 return n;
1416 }
1417 };
1418
1419 struct size
1420 {
1421 template <class T>
1422 constexpr size_t operator()(T&& t) const
1423 {
1424 using U = etl::remove_cvref_t<T>;
1425
1426 if constexpr (has_size_member<U>::value)
1427 {
1428 return static_cast<size_t>(t.size());
1429 }
1430 else
1431 {
1432 using iter_type = decltype(ETL_OR_STD::begin(t));
1433 static_assert(etl::is_forward_iterator_concept<iter_type>::value, "ranges::size requires a sized range or at least a forward range; "
1434 "single-pass input ranges are not supported");
1435 return static_cast<size_t>(distance{}(ETL_OR_STD::begin(t), ETL_OR_STD::end(t)));
1436 }
1437 }
1438 };
1439
1440 struct ssize
1441 {
1442 template <class T>
1443 constexpr auto operator()(T&& t) const
1444 {
1445 using U = etl::remove_cvref_t<T>;
1446
1447 if constexpr (has_size_member<U>::value)
1448 {
1449 return static_cast<ptrdiff_t>(t.size());
1450 }
1451 else
1452 {
1453 using iter_type = decltype(ETL_OR_STD::begin(t));
1454 static_assert(etl::is_forward_iterator_concept<iter_type>::value, "ranges::ssize requires a sized range or at least a forward range; "
1455 "single-pass input ranges are not supported");
1456 return static_cast<ptrdiff_t>(distance{}(ETL_OR_STD::begin(t), ETL_OR_STD::end(t)));
1457 }
1458 }
1459 };
1460
1461 struct empty
1462 {
1463 template <class T>
1464 constexpr auto operator()(T&& t) const
1465 {
1466 using U = etl::remove_cvref_t<T>;
1467
1468 if constexpr (has_empty_member<U>::value)
1469 {
1470 return t.empty();
1471 }
1472 else
1473 {
1474 return ETL_OR_STD::cbegin(t) == ETL_OR_STD::cend(t);
1475 }
1476 }
1477 };
1478
1479 struct data
1480 {
1481 template <class T>
1482 constexpr auto operator()(T& t) const
1483 {
1484 return ETL_OR_STD::data(t);
1485 }
1486 };
1487
1488 struct cdata
1489 {
1490 template <class T>
1491 constexpr etl::add_pointer_t< etl::add_const_t<etl::remove_pointer_t< decltype(ETL_OR_STD::data(etl::declval<T&>()))>>> operator()(T& t) const
1492 {
1493 return ETL_OR_STD::data(t);
1494 }
1495 };
1496 } // namespace private_ranges
1497
1498 inline constexpr private_ranges::begin begin;
1499 inline constexpr private_ranges::end end;
1500 inline constexpr private_ranges::cbegin cbegin;
1501 inline constexpr private_ranges::cend cend;
1502 inline constexpr private_ranges::rbegin rbegin;
1503 inline constexpr private_ranges::rend rend;
1504 inline constexpr private_ranges::crbegin crbegin;
1505 inline constexpr private_ranges::crend crend;
1506 inline constexpr private_ranges::size size;
1507 inline constexpr private_ranges::ssize ssize;
1508 inline constexpr private_ranges::empty empty;
1509 inline constexpr private_ranges::data data;
1510 inline constexpr private_ranges::cdata cdata;
1511 inline constexpr private_ranges::distance distance;
1512
1513 //*************************************************************************
1515 //*************************************************************************
1516
1517 template <class T>
1518 using iterator_t = decltype(etl::ranges::begin(etl::declval<T&>()));
1519
1520 template <class T>
1521 using const_iterator_t = decltype(etl::ranges::cbegin(etl::declval<T&>()));
1522
1523 template <class T>
1524 using sentinel_t = decltype(etl::ranges::end(etl::declval<T&>()));
1525
1526 template <class T>
1527 using const_sentinel_t = decltype(etl::ranges::cend(etl::declval<T&>()));
1528
1529 template <class T>
1530 using range_size_t = decltype(etl::ranges::size(etl::declval<T&>()));
1531
1532 template <class T>
1533 using range_difference_t = etl::iter_difference_t<etl::ranges::iterator_t<T>>;
1534
1535 template <class T>
1536 using range_value_t = etl::iter_value_t<etl::ranges::iterator_t<T>>;
1537
1538 template <class T>
1539 using range_reference_t = etl::iter_reference_t<ranges::iterator_t<T>>;
1540
1541 struct advance_fn
1542 {
1543 template <typename I, typename = etl::enable_if_t< (etl::is_input_iterator_concept<I>::value || etl::is_output_iterator_concept<I>::value)
1544 && etl::is_integral<etl::iter_difference_t<I>>::value>>
1545 constexpr void operator()(I& i, etl::iter_difference_t<I> n) const
1546 {
1547 if constexpr (etl::is_random_access_iterator_concept<I>::value)
1548 {
1549 i += n;
1550 }
1551 else
1552 {
1553 while (n > 0)
1554 {
1555 --n;
1556 ++i;
1557 }
1558
1559 if constexpr (etl::is_bidirectional_iterator_concept<I>::value)
1560 {
1561 while (n < 0)
1562 {
1563 ++n;
1564 --i;
1565 }
1566 }
1567 }
1568 }
1569
1570 template <typename I, typename S,
1571 typename = etl::enable_if_t< (etl::is_input_iterator_concept<I>::value || etl::is_output_iterator_concept<I>::value)
1572 && !etl::is_integral<S>::value>>
1573 constexpr void operator()(I& i, S bound) const
1574 {
1575 if constexpr (etl::is_assignable_v<I&, S>)
1576 {
1577 i = etl::move(bound);
1578 }
1579 else if constexpr (etl::is_same_v<S, I> && etl::is_random_access_iterator_concept<I>::value)
1580 {
1581 (*this)(i, bound - i);
1582 }
1583 else
1584 {
1585 while (!(i == bound))
1586 {
1587 ++i;
1588 }
1589 }
1590 }
1591
1592 template <typename I, typename S,
1593 typename = etl::enable_if_t< etl::is_input_iterator_concept<I>::value || etl::is_output_iterator_concept<I>::value>>
1594 constexpr etl::iter_difference_t<I> operator()(I& i, etl::iter_difference_t<I> n, S bound) const
1595 {
1596 if constexpr (etl::is_same_v<S, I> && etl::is_random_access_iterator_concept<I>::value)
1597 {
1598 const auto dist = bound - i;
1599
1600 if ((n >= 0 && dist >= 0 && n >= dist) || (n <= 0 && dist <= 0 && n <= dist))
1601 {
1602 (*this)(i, bound);
1603 return n - dist;
1604 }
1605
1606 (*this)(i, n);
1607 return 0;
1608 }
1609 else
1610 {
1611 while (n > 0 && !(i == bound))
1612 {
1613 --n;
1614 ++i;
1615 }
1616
1617 if constexpr (etl::is_bidirectional_iterator_concept<I>::value)
1618 {
1619 while (n < 0 && !(i == bound))
1620 {
1621 ++n;
1622 --i;
1623 }
1624 }
1625
1626 return n;
1627 }
1628 }
1629 };
1630
1631 inline constexpr auto advance = advance_fn();
1632
1633 struct prev_fn
1634 {
1635 template <typename I, typename = etl::enable_if_t< etl::is_bidirectional_iterator_concept<I>::value>>
1636 constexpr I operator()(I i) const
1637 {
1638 --i;
1639 return i;
1640 }
1641
1642 template <typename I, typename = etl::enable_if_t< etl::is_bidirectional_iterator_concept<I>::value>>
1643 constexpr I operator()(I i, etl::iter_difference_t<I> n) const
1644 {
1645 ranges::advance(i, -n);
1646 return i;
1647 }
1648
1649 template <typename I, typename = etl::enable_if_t< etl::is_bidirectional_iterator_concept<I>::value>>
1650 constexpr I operator()(I i, etl::iter_difference_t<I> n, I bound) const
1651 {
1652 ranges::advance(i, -n, bound);
1653 return i;
1654 }
1655 };
1656
1657 inline constexpr auto prev = prev_fn();
1658
1659 struct next_fn
1660 {
1661 template <typename I, typename = etl::enable_if_t< etl::is_input_iterator_concept<I>::value || etl::is_output_iterator_concept<I>::value>>
1662 constexpr I operator()(I i) const
1663 {
1664 ++i;
1665 return i;
1666 }
1667
1668 template <typename I, typename = etl::enable_if_t< (etl::is_input_iterator_concept<I>::value || etl::is_output_iterator_concept<I>::value)
1669 && etl::is_integral<etl::iter_difference_t<I>>::value>>
1670 constexpr I operator()(I i, etl::iter_difference_t<I> n) const
1671 {
1672 ranges::advance(i, n);
1673 return i;
1674 }
1675
1676 template <typename I, typename S,
1677 typename = etl::enable_if_t< (etl::is_input_iterator_concept<I>::value || etl::is_output_iterator_concept<I>::value)
1678 && !etl::is_integral<S>::value>>
1679 constexpr I operator()(I i, S bound) const
1680 {
1681 ranges::advance(i, bound);
1682 return i;
1683 }
1684
1685 template <typename I, typename S,
1686 typename = etl::enable_if_t< (etl::is_input_iterator_concept<I>::value || etl::is_output_iterator_concept<I>::value)
1687 && !etl::is_integral<S>::value>>
1688 constexpr I operator()(I i, etl::iter_difference_t<I> n, S bound) const
1689 {
1690 ranges::advance(i, n, bound);
1691 return i;
1692 }
1693 };
1694
1695 inline constexpr auto next = next_fn();
1696 } // namespace ranges
1697
1698 struct unreachable_sentinel_t
1699 {
1700 };
1701
1702 inline constexpr unreachable_sentinel_t unreachable_sentinel{};
1703
1704 template <typename I>
1705 constexpr bool operator==(unreachable_sentinel_t, const I&) noexcept
1706 {
1707 return false;
1708 }
1709
1710 template <typename I>
1711 constexpr bool operator==(const I&, unreachable_sentinel_t) noexcept
1712 {
1713 return false;
1714 }
1715
1716 template <typename I>
1717 constexpr bool operator!=(unreachable_sentinel_t, const I& i) noexcept
1718 {
1719 return !(unreachable_sentinel_t{} == i);
1720 }
1721
1722 template <typename I>
1723 constexpr bool operator!=(const I& i, unreachable_sentinel_t) noexcept
1724 {
1725 return !(i == unreachable_sentinel_t{});
1726 }
1727
1728 struct default_sentinel_t
1729 {
1730 };
1731
1732 inline constexpr default_sentinel_t default_sentinel{};
1733
1734 namespace private_iterator
1735 {
1736 template <typename T, typename = void>
1737 struct has_arrow_operator : etl::false_type
1738 {
1739 };
1740
1741 template <typename T>
1742 struct has_arrow_operator< T, etl::void_t<decltype(etl::declval<const T&>().operator->())>> : etl::true_type
1743 {
1744 };
1745
1746 //***********************************
1751 //***********************************
1752 template <typename TValue>
1753 struct arrow_proxy
1754 {
1755 TValue stored;
1756
1757 constexpr arrow_proxy(TValue value)
1758 : stored(etl::move(value))
1759 {
1760 }
1761 constexpr const TValue* operator->() const noexcept
1762 {
1763 return etl::addressof(stored);
1764 }
1765 };
1766 } // namespace private_iterator
1767
1768 template <class I>
1769 class counted_iterator
1770 {
1771 template <class>
1772 friend class counted_iterator;
1773
1774 public:
1775
1776 using iterator_type = I;
1777 using value_type = etl::iter_value_t<I>;
1778 using difference_type = etl::iter_difference_t<I>;
1779 using iterator_category = typename etl::iterator_traits<iterator_type>::iterator_category;
1780 using pointer = typename etl::iterator_traits<iterator_type>::pointer;
1781 using reference = typename etl::iterator_traits<iterator_type>::reference;
1782
1783 constexpr counted_iterator() = default;
1784
1785 constexpr counted_iterator(I x, etl::iter_difference_t<I> n)
1786 : current(etl::move(x))
1787 , length(n)
1788 {
1789 }
1790
1791 template <class I2>
1792 constexpr counted_iterator(const counted_iterator<I2>& other)
1793 : current(other.current)
1794 , length(other.length)
1795 {
1796 }
1797
1798 template <class I2>
1799 constexpr counted_iterator& operator=(const counted_iterator<I2>& other)
1800 {
1801 current = other.current;
1802 length = other.length;
1803 return *this;
1804 }
1805
1806 constexpr const I& base() const& noexcept
1807 {
1808 return current;
1809 }
1810
1811 constexpr I base() &&
1812 {
1813 return etl::move(current);
1814 }
1815
1816 constexpr etl::iter_difference_t<I> count() const noexcept
1817 {
1818 return length;
1819 }
1820
1821 constexpr decltype(auto) operator*() const
1822 {
1823 return *current;
1824 }
1825
1826 // operator-> for iterator types that provide a member operator->
1827 template < typename J = I, etl::enable_if_t<(etl::is_input_iterator_concept<J>::value || etl::is_output_iterator_concept<J>::value)
1828 && private_iterator::has_arrow_operator<J>::value,
1829 int> = 0>
1830 constexpr auto operator->() const noexcept
1831 {
1832 return current.operator->();
1833 }
1834
1835 // operator-> fallback for raw-pointer iterators (addressof is always safe)
1836 template < typename J = I, etl::enable_if_t<(etl::is_input_iterator_concept<J>::value || etl::is_output_iterator_concept<J>::value)
1837 && !private_iterator::has_arrow_operator<J>::value && etl::is_pointer<J>::value,
1838 int> = 0>
1839 constexpr auto operator->() const noexcept
1840 {
1841 return current;
1842 }
1843
1844 // operator-> fallback for class-type iterators without member operator->
1845 // When *current yields an lvalue reference, just take its address.
1846 template < typename J = I, etl::enable_if_t< (etl::is_input_iterator_concept<J>::value || etl::is_output_iterator_concept<J>::value)
1847 && !private_iterator::has_arrow_operator<J>::value && !etl::is_pointer<J>::value
1848 && etl::is_lvalue_reference< decltype(*etl::declval<const J&>())>::value,
1849 int> = 0>
1850 constexpr auto operator->() const noexcept
1851 {
1852 return etl::addressof(*current);
1853 }
1854
1855 // operator-> fallback for class-type iterators without member operator->
1856 // When *current yields a prvalue / proxy, use an owning proxy so the
1857 // address remains valid.
1858 template < typename J = I, etl::enable_if_t< (etl::is_input_iterator_concept<J>::value || etl::is_output_iterator_concept<J>::value)
1859 && !private_iterator::has_arrow_operator<J>::value && !etl::is_pointer<J>::value
1860 && !etl::is_lvalue_reference< decltype(*etl::declval<const J&>())>::value,
1861 int> = 0>
1862 constexpr auto operator->() const
1863 {
1864 return private_iterator::arrow_proxy<value_type>{*current};
1865 }
1866
1867 template < typename J = I, etl::enable_if_t<etl::is_random_access_iterator<J>::value, int> = 0>
1868 constexpr decltype(auto) operator[](etl::iter_difference_t<I> n) const
1869 {
1870 return current[n];
1871 }
1872
1873 constexpr counted_iterator& operator++()
1874 {
1875 ++current;
1876 --length;
1877 return *this;
1878 }
1879
1880 constexpr counted_iterator operator++(int)
1881 {
1882 counted_iterator tmp = *this;
1883 current++;
1884 length--;
1885 return tmp;
1886 }
1887
1888 template < typename J = I, etl::enable_if_t<etl::is_random_access_iterator<J>::value, int> = 0>
1889 constexpr counted_iterator& operator+=(etl::iter_difference_t<I> n)
1890 {
1891 current += n;
1892 length -= n;
1893 return *this;
1894 }
1895
1896 template < typename J = I, etl::enable_if_t<etl::is_random_access_iterator<J>::value, int> = 0>
1897 constexpr counted_iterator operator+(etl::iter_difference_t<I> n) const
1898 {
1899 counted_iterator result{*this};
1900 result += n;
1901 return result;
1902 }
1903
1904 constexpr counted_iterator& operator--()
1905 {
1906 --current;
1907 ++length;
1908 return *this;
1909 }
1910
1911 constexpr counted_iterator operator--(int)
1912 {
1913 counted_iterator tmp = *this;
1914 current--;
1915 length++;
1916 return tmp;
1917 }
1918
1919 template < typename J = I, etl::enable_if_t<etl::is_random_access_iterator<J>::value, int> = 0>
1920 constexpr counted_iterator& operator-=(etl::iter_difference_t<I> n)
1921 {
1922 current -= n;
1923 length += n;
1924 return *this;
1925 }
1926
1927 template < typename J = I, etl::enable_if_t<etl::is_random_access_iterator<J>::value, int> = 0>
1928 constexpr counted_iterator operator-(etl::iter_difference_t<I> n) const
1929 {
1930 counted_iterator result{*this};
1931 result -= n;
1932 return result;
1933 }
1934
1935 friend constexpr bool operator==(const counted_iterator& x, const counted_iterator& y)
1936 {
1937 return x.length == y.length;
1938 }
1939
1940 friend constexpr bool operator==(const counted_iterator& x, etl::default_sentinel_t)
1941 {
1942 return x.count() == 0;
1943 }
1944
1945 friend constexpr bool operator==(etl::default_sentinel_t, const counted_iterator& x)
1946 {
1947 return x.count() == 0;
1948 }
1949
1950 friend constexpr bool operator!=(const counted_iterator& x, etl::default_sentinel_t)
1951 {
1952 return x.count() != 0;
1953 }
1954
1955 friend constexpr bool operator!=(etl::default_sentinel_t, const counted_iterator& y)
1956 {
1957 return y.count() != 0;
1958 }
1959
1960 template < typename J = I, etl::enable_if_t<etl::is_random_access_iterator<J>::value, int> = 0>
1961 friend constexpr counted_iterator operator+(etl::iter_difference_t<I> n, const counted_iterator& x)
1962 {
1963 return counted_iterator(x.current + n, x.length - n);
1964 }
1965
1966 friend constexpr etl::iter_difference_t<I> operator-(const counted_iterator& x, const counted_iterator& y)
1967 {
1968 return y.length - x.length;
1969 }
1970
1971 friend constexpr etl::iter_difference_t<I> operator-(const counted_iterator& x, etl::default_sentinel_t)
1972 {
1973 return -x.length;
1974 }
1975
1976 friend constexpr etl::iter_difference_t<I> operator-(etl::default_sentinel_t, const counted_iterator& y)
1977 {
1978 return y.length;
1979 }
1980
1981 private:
1982
1983 I current{};
1984 difference_type length{};
1985 };
1986
1987 template <typename TIterator,
1988 typename = etl::enable_if_t<etl::is_base_of< etl::counted_iterator<typename TIterator::iterator_type>, TIterator>::value>>
1989 constexpr typename etl::iterator_traits<TIterator>::difference_type distance(TIterator first, etl::default_sentinel_t)
1990 {
1991 return first.count();
1992 }
1993#endif
1994
1995#if ETL_USING_CPP14
1996 template <class T, typename = void>
1997 struct is_range : etl::false_type
1998 {
1999 };
2000
2001 template <class T>
2002 struct is_range< T, etl::void_t<decltype(ETL_OR_STD::begin(etl::declval<T&>())), decltype(ETL_OR_STD::end(etl::declval<T&>()))>> : etl::true_type
2003 {
2004 };
2005
2006 #if ETL_USING_CPP17
2007 template <typename T>
2008 inline constexpr bool is_range_v = is_range<T>::value;
2009 #endif
2010#endif
2011} // namespace etl
2012
2013#endif
Turns assignment into push_back.
Definition iterator.h:605
ETL_CONSTEXPR14 back_insert_iterator & operator++()
Pre-increment operator.
Definition iterator.h:651
ETL_CONSTEXPR14 back_insert_iterator(TContainer &c)
Constructor.
Definition iterator.h:613
ETL_CONSTEXPR14 back_insert_iterator & operator=(const typename TContainer::value_type &value)
Assignment operator.
Definition iterator.h:621
ETL_NODISCARD ETL_CONSTEXPR14 back_insert_iterator & operator*()
Dereference operator.
Definition iterator.h:643
ETL_CONSTEXPR14 back_insert_iterator operator++(int)
Post-increment operator.
Definition iterator.h:659
Turns assignment into a push_front.
Definition iterator.h:687
ETL_CONSTEXPR14 front_insert_iterator(TContainer &c)
Constructor.
Definition iterator.h:695
ETL_CONSTEXPR14 front_insert_iterator & operator++()
Pre-increment operator.
Definition iterator.h:731
ETL_CONSTEXPR14 front_insert_iterator operator++(int)
Post-increment operator.
Definition iterator.h:739
ETL_NODISCARD ETL_CONSTEXPR14 front_insert_iterator & operator*()
Dereference operator.
Definition iterator.h:723
ETL_CONSTEXPR14 front_insert_iterator & operator=(const typename TContainer::value_type &value)
Assignment operator.
Definition iterator.h:703
Turns assignment into a push.
Definition iterator.h:767
ETL_NODISCARD ETL_CONSTEXPR14 push_insert_iterator & operator*()
Dereference operator.
Definition iterator.h:805
ETL_CONSTEXPR14 push_insert_iterator & operator=(const typename TContainer::value_type &value)
Assignment operator.
Definition iterator.h:783
ETL_CONSTEXPR14 push_insert_iterator & operator++()
Pre-increment operator.
Definition iterator.h:813
ETL_CONSTEXPR14 push_insert_iterator(TContainer &c)
Constructor.
Definition iterator.h:775
ETL_CONSTEXPR14 push_insert_iterator operator++(int)
Post-increment operator.
Definition iterator.h:821
Definition iterator.h:252
Definition array.h:88
ETL_CONSTEXPR17 etl::enable_if<!etl::is_same< T, etl::nullptr_t >::value, T >::type * addressof(T &t)
Definition addressof.h:52
bitset_ext
Definition absolute.h:40
ETL_CONSTEXPR14 bool operator==(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition array.h:1081
ETL_CONSTEXPR TContainer::reverse_iterator rend(TContainer &container)
Definition iterator.h:1119
ETL_CONSTEXPR TContainer::pointer data(TContainer &container)
Definition iterator.h:1228
ETL_CONSTEXPR TContainer::const_reverse_iterator crbegin(const TContainer &container)
Definition iterator.h:1109
ETL_CONSTEXPR14 etl::circular_iterator< TIterator > operator-(etl::circular_iterator< TIterator > &lhs, typename etl::iterator_traits< TIterator >::difference_type offset)
Definition circular_iterator.h:675
bool operator>(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition array.h:1133
ETL_NODISCARD ETL_CONSTEXPR14 etl::push_insert_iterator< TContainer > push_inserter(TContainer &container)
Creates a push_insert_iterator from a container.
Definition iterator.h:835
ETL_NODISCARD ETL_CONSTEXPR14 etl::front_insert_iterator< TContainer > front_inserter(TContainer &container)
Creates a front_insert_iterator from a container.
Definition iterator.h:753
char(& array_size(T(&array)[Array_Size]))[Array_Size]
ETL_CONSTEXPR TContainer::reverse_iterator rbegin(TContainer &container)
Definition iterator.h:1089
integral_constant< bool, false > false_type
integral_constant specialisations
Definition type_traits.h:80
bool operator>=(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition array.h:1147
ETL_CONSTEXPR TContainer::const_iterator cbegin(const TContainer &container)
Definition iterator.h:987
ETL_CONSTEXPR14 bool operator!=(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition array.h:1093
ETL_NODISCARD ETL_CONSTEXPR14 etl::back_insert_iterator< TContainer > back_inserter(TContainer &container)
Creates a back_insert_iterator from a container.
Definition iterator.h:673
ETL_CONSTEXPR TContainer::size_type size(const TContainer &container)
Definition iterator.h:1192
ETL_CONSTEXPR TContainer::iterator begin(TContainer &container)
Definition iterator.h:967
ETL_CONSTEXPR14 enable_if<!etl::is_specialization< TRep2, etl::chrono::duration >::value, etl::chrono::duration< typenameetl::common_type< TRep1, TRep2 >::type, TPeriod1 > >::type operator*(const etl::chrono::duration< TRep1, TPeriod1 > &lhs, const TRep2 &rhs) ETL_NOEXCEPT
Operator *.
Definition duration.h:541
ETL_CONSTEXPR14 etl::circular_iterator< TIterator > operator+(etl::circular_iterator< TIterator > &lhs, typename etl::iterator_traits< TIterator >::difference_type offset)
Definition circular_iterator.h:662
ETL_CONSTEXPR TContainer::const_reverse_iterator crend(const TContainer &container)
Definition iterator.h:1139
ETL_CONSTEXPR TContainer::const_iterator cend(const TContainer &container)
Definition iterator.h:1017
bool operator<(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition array.h:1106
bool operator<=(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition array.h:1120
ETL_CONSTEXPR TContainer::iterator end(TContainer &container)
Definition iterator.h:997
Definition iterator.h:61
Definition iterator.h:58
Definition iterator.h:52
Definition iterator.h:872
Definition iterator.h:922
Definition iterator.h:863
Definition iterator.h:900
Definition iterator.h:845
Definition iterator.h:911
Definition iterator.h:854
Definition iterator.h:891
Definition iterator.h:942
Definition iterator.h:882
Definition iterator.h:74
iterator
Definition iterator.h:424
Definition iterator.h:55
Definition iterator.h:64