Embedded Template Library 1.0
circular_buffer.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) 2020 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_BUFFER_INCLUDED
32#define ETL_CIRCULAR_BUFFER_INCLUDED
33
34#include "platform.h"
35#include "vector.h"
36#include "exception.h"
37#include "error_handler.h"
38#include "memory.h"
39#include "memory_model.h"
40#include "type_traits.h"
41#include "iterator.h"
42#include "static_assert.h"
43#include "initializer_list.h"
44
45namespace etl
46{
47 //***************************************************************************
49 //***************************************************************************
51 {
52 public:
53
54 circular_buffer_exception(string_type reason_, string_type file_name_, numeric_type line_number_)
55 : exception(reason_, file_name_, line_number_)
56 {
57 }
58 };
59
60 //***************************************************************************
62 //***************************************************************************
64 {
65 public:
66
67 circular_buffer_empty(string_type file_name_, numeric_type line_number_)
68 : etl::circular_buffer_exception(ETL_ERROR_TEXT("circular_buffer:empty", ETL_CIRCULAR_BUFFER_FILE_ID"A"), file_name_, line_number_)
69 {
70 }
71 };
72
73 //***************************************************************************
75 //***************************************************************************
77 {
78 public:
79
80 circular_buffer_incompatible_type(string_type file_name_, numeric_type line_number_)
81 : circular_buffer_exception(ETL_ERROR_TEXT("circular_buffer:type", ETL_CIRCULAR_BUFFER_FILE_ID"B"), file_name_, line_number_)
82 {
83 }
84 };
85
86 //***************************************************************************
88 //***************************************************************************
90 {
91 public:
92
94 typedef size_t size_type;
95
96 //*************************************************************************
97 size_type size() const
98 {
99 return (in >= out) ? in - out : buffer_size - (out - in);
100 }
101
102 //*************************************************************************
103 bool empty() const
104 {
105 return in == out;
106 }
107
108 //*************************************************************************
109 bool full() const
110 {
111 size_t i = in;
112
113 ++i;
114 if (i == buffer_size) ETL_UNLIKELY
115 {
116 i = 0U;
117 }
118
119 return i == out;
120 }
121
122 //*************************************************************************
123 size_type available() const
124 {
125 return max_size() - size();
126 }
127
128 //*************************************************************************
129 size_type max_size() const
130 {
131 return buffer_size - 1U;
132 }
133
134 //*************************************************************************
135 size_type capacity() const
136 {
137 return buffer_size - 1U;
138 }
139
140 protected:
141
142 //*************************************************************************
143 circular_buffer_base(size_type buffer_size_)
144 : buffer_size(buffer_size_)
145 , in(0U)
146 , out(0U)
147 {
148 }
149
150 //*************************************************************************
151 void increment_in()
152 {
153 ++in;
154 if (in == buffer_size) ETL_UNLIKELY
155 {
156 in = 0U;
157 }
158 }
159
160 //*************************************************************************
161 void increment_out()
162 {
163 ++out;
164 if (out == buffer_size) ETL_UNLIKELY
165 {
166 out = 0U;
167 }
168 }
169
170 size_type buffer_size;
173 ETL_DECLARE_DEBUG_COUNT
174 };
175
176 //***************************************************************************
178 //***************************************************************************
179 template <typename T>
181 {
182 public:
183
184 typedef T value_type;
185 typedef T& reference;
186 typedef const T& const_reference;
187#if ETL_USING_CPP11
188 typedef T&& rvalue_reference;
189#endif
190 typedef T* pointer;
191 typedef const T* const_pointer;
192
193 typedef typename etl::iterator_traits<pointer>::difference_type difference_type;
194
195 //*************************************************************************
197 //*************************************************************************
198 class iterator : public etl::iterator<ETL_OR_STD::random_access_iterator_tag, T>
199 {
200 public:
201
202 friend class icircular_buffer;
203
204 //*************************************************************************
206 //*************************************************************************
208 : picb(ETL_NULLPTR)
209 , current(0U)
210 {
211 }
212
213 //*************************************************************************
215 //*************************************************************************
216 iterator(const iterator& other)
217 : picb(other.picb)
218 , current(other.current)
219 {
220 }
221
222 //*************************************************************************
224 //*************************************************************************
226 {
227 picb = other.picb;
228 current = other.current;
229
230 return *this;
231 }
232
233 //*************************************************************************
235 //*************************************************************************
236 reference operator *() const
237 {
238 return picb->pbuffer[current];
239 }
240
241 //*************************************************************************
243 //*************************************************************************
244 pointer operator ->() const
245 {
246 return &picb->pbuffer[current];
247 }
248
249 //*************************************************************************
251 //*************************************************************************
253 {
254 ++current;
255
256 // Did we reach the end of the buffer?
257 if (current == picb->buffer_size)
258 {
259 current = 0U;
260 }
261
262 return (*this);
263 }
264
265 //*************************************************************************
267 //*************************************************************************
269 {
270 iterator original(*this);
271
272 ++(*this);
273
274 return (original);
275 }
276
277 //*************************************************************************
279 //*************************************************************************
281 {
282 // Are we at the end of the buffer?
283 if (current == 0U)
284 {
285 current = picb->buffer_size - 1;
286 }
287 else
288 {
289 --current;
290 }
291
292 return (*this);
293 }
294
295 //*************************************************************************
297 //*************************************************************************
299 {
300 iterator original(*this);
301
302 --(*this);
303
304 return (original);
305 }
306
307 //*************************************************************************
309 //*************************************************************************
311 {
312 current += size_type(picb->buffer_size + n);
313 current %= picb->buffer_size;
314
315 return (*this);
316 }
317
318 //*************************************************************************
320 //*************************************************************************
322 {
323 return (this->operator+=(-n));
324 }
325
326 //*************************************************************************
328 //*************************************************************************
329 friend iterator operator +(const iterator& lhs, int n)
330 {
331 iterator temp = lhs;
332
333 temp += n;
334
335 return temp;
336 }
337
338 //*************************************************************************
340 //*************************************************************************
341 friend iterator operator -(const iterator& lhs, int n)
342 {
343 iterator temp = lhs;
344
345 temp -= n;
346
347 return temp;
348 }
349
350 //*************************************************************************
352 //*************************************************************************
353 friend bool operator == (const iterator& lhs, const iterator& rhs)
354 {
355 return (lhs.current == rhs.current);
356 }
357
358 //*************************************************************************
360 //*************************************************************************
361 friend bool operator != (const iterator& lhs, const iterator& rhs)
362 {
363 return !(lhs == rhs);
364 }
365
366 //***************************************************
367 friend bool operator < (const iterator& lhs, const iterator& rhs)
368 {
369 const difference_type lhs_index = lhs.get_index();
370 const difference_type rhs_index = rhs.get_index();
371 const difference_type reference_index = lhs.container().begin().get_index();
372 const size_t buffer_size = lhs.container().max_size() + 1UL;
373
374 const difference_type lhs_distance = (lhs_index < reference_index) ? buffer_size + lhs_index - reference_index : lhs_index - reference_index;
375 const difference_type rhs_distance = (rhs_index < reference_index) ? buffer_size + rhs_index - reference_index : rhs_index - reference_index;
376
377 return lhs_distance < rhs_distance;
378 }
379
380 //***************************************************
381 friend bool operator <= (const iterator& lhs, const iterator& rhs)
382 {
383 return !(lhs > rhs);
384 }
385
386 //***************************************************
387 friend bool operator > (const iterator& lhs, const iterator& rhs)
388 {
389 return (rhs < lhs);
390 }
391
392 //***************************************************
393 friend bool operator >= (const iterator& lhs, const iterator& rhs)
394 {
395 return !(lhs < rhs);
396 }
397
398 //***************************************************
399 difference_type get_index() const
400 {
401 return current;
402 }
403
404 //***************************************************
405 const icircular_buffer& container() const
406 {
407 return *picb;
408 }
409
410 //***************************************************
411 pointer get_buffer() const
412 {
413 return pbuffer;
414 }
415
416 protected:
417
418 //***************************************************
419 difference_type distance(difference_type firstIndex, difference_type index) const
420 {
421 if (index < firstIndex)
422 {
423 return picb->buffer_size + current - firstIndex;
424 }
425 else
426 {
427 return index - firstIndex;
428 }
429 }
430
431 //*************************************************************************
433 //*************************************************************************
434 iterator(const icircular_buffer<T>* picb_, size_type current_)
435 : picb(picb_)
436 , current(current_)
437 {
438 }
439
440 private:
441
442 const icircular_buffer<T>* picb;
443 size_type current;
444 };
445
446 //*************************************************************************
448 //*************************************************************************
449 class const_iterator : public etl::iterator<ETL_OR_STD::random_access_iterator_tag, const T>
450 {
451 public:
452
453 friend class icircular_buffer;
454
455 //*************************************************************************
457 //*************************************************************************
459 : picb(ETL_NULLPTR)
460 , current(0U)
461 {
462 }
463
464 //*************************************************************************
466 //*************************************************************************
468 : picb(other.picb)
469 , current(other.current)
470 {
471 }
472
473 //*************************************************************************
475 //*************************************************************************
477 : picb(other.picb)
478 , current(other.current)
479 {
480 }
481
482 //*************************************************************************
484 //*************************************************************************
486 {
487 picb = other.picb;
488 current = other.current;
489
490 return *this;
491 }
492
493 //*************************************************************************
495 //*************************************************************************
497 {
498 picb = other.picb;
499 current = other.current;
500
501 return *this;
502 }
503
504 //*************************************************************************
506 //*************************************************************************
507 const_reference operator *() const
508 {
509 return picb->pbuffer[current];
510 }
511
512 //*************************************************************************
514 //*************************************************************************
515 const_pointer operator ->() const
516 {
517 return &(picb->pbuffer[current]);
518 }
519
520 //*************************************************************************
522 //*************************************************************************
524 {
525 ++current;
526
527 // Did we reach the end of the buffer?
528 if (current == picb->buffer_size)
529 {
530 current = 0U;
531 }
532
533 return (*this);
534 }
535
536 //*************************************************************************
538 //*************************************************************************
540 {
541 const_iterator original(*this);
542
543 ++(*this);
544
545 return (original);
546 }
547
548 //*************************************************************************
550 //*************************************************************************
552 {
553 // Are we at the end of the buffer?
554 if (current == 0U)
555 {
556 current = picb->buffer_size - 1;
557 }
558 else
559 {
560 --current;
561 }
562
563 return (*this);
564 }
565
566 //*************************************************************************
568 //*************************************************************************
570 {
571 const_iterator original(*this);
572
573 --(*this);
574
575 return (original);
576 }
577
578 //*************************************************************************
580 //*************************************************************************
582 {
583 current += size_type(picb->buffer_size + n);
584 current %= picb->buffer_size;
585
586 return (*this);
587 }
588
589 //*************************************************************************
591 //*************************************************************************
593 {
594 return (this->operator+=(-n));
595 }
596
597 //*************************************************************************
599 //*************************************************************************
600 friend const_iterator operator +(const const_iterator& lhs, int n)
601 {
602 const_iterator temp = lhs;
603
604 temp += n;
605
606 return temp;
607 }
608
609 //*************************************************************************
611 //*************************************************************************
612 friend const_iterator operator -(const const_iterator& lhs, int n)
613 {
614 const_iterator temp = lhs;
615
616 temp -= n;
617
618 return temp;
619 }
620
621 //*************************************************************************
623 //*************************************************************************
624 friend bool operator == (const const_iterator& lhs, const const_iterator& rhs)
625 {
626 return (lhs.current == rhs.current);
627 }
628
629 //*************************************************************************
631 //*************************************************************************
632 friend bool operator != (const const_iterator& lhs, const const_iterator& rhs)
633 {
634 return !(lhs == rhs);
635 }
636
637 //***************************************************
638 friend bool operator < (const const_iterator& lhs, const const_iterator& rhs)
639 {
640 const difference_type lhs_index = lhs.get_index();
641 const difference_type rhs_index = rhs.get_index();
642 const difference_type reference_index = lhs.container().begin().get_index();
643 const size_t buffer_size = lhs.container().max_size() + 1UL;
644
645 const difference_type lhs_distance = (lhs_index < reference_index) ? buffer_size + lhs_index - reference_index : lhs_index - reference_index;
646 const difference_type rhs_distance = (rhs_index < reference_index) ? buffer_size + rhs_index - reference_index : rhs_index - reference_index;
647
648 return lhs_distance < rhs_distance;
649 }
650
651 //***************************************************
652 friend bool operator <= (const const_iterator& lhs, const const_iterator& rhs)
653 {
654 return !(lhs > rhs);
655 }
656
657 //***************************************************
658 friend bool operator > (const const_iterator& lhs, const const_iterator& rhs)
659 {
660 return (rhs < lhs);
661 }
662
663 //***************************************************
664 friend bool operator >= (const const_iterator& lhs, const const_iterator& rhs)
665 {
666 return !(lhs < rhs);
667 }
668
669 //***************************************************
670 difference_type get_index() const
671 {
672 return current;
673 }
674
675 //***************************************************
676 const icircular_buffer& container() const
677 {
678 return *picb;
679 }
680
681 //***************************************************
682 pointer get_buffer() const
683 {
684 return pbuffer;
685 }
686
687 protected:
688
689 //*************************************************************************
691 //*************************************************************************
693 : picb(picb_)
694 , current(current_)
695 {
696 }
697
698 private:
699
700 const icircular_buffer<T>* picb;
701 size_type current;
702 };
703
704 friend class iterator;
705 friend class const_iterator;
706
708 typedef etl::reverse_iterator<const_iterator> const_reverse_iterator;
709
710 //*************************************************************************
712 //*************************************************************************
714 {
715 return iterator(this, out);
716 }
717
718 //*************************************************************************
720 //*************************************************************************
722 {
723 return const_iterator(this, out);
724 }
725
726 //*************************************************************************
728 //*************************************************************************
730 {
731 return const_iterator(this, out);
732 }
733
734 //*************************************************************************
736 //*************************************************************************
738 {
739 return iterator(this, in);
740 }
741
742 //*************************************************************************
744 //*************************************************************************
746 {
747 return const_iterator(this, in);
748 }
749
750 //*************************************************************************
752 //*************************************************************************
754 {
755 return const_iterator(this, in);
756 }
757
758 //*************************************************************************
760 //*************************************************************************
762 {
763 return reverse_iterator(end());
764 }
765
766 //*************************************************************************
768 //*************************************************************************
770 {
771 return const_reverse_iterator(end());
772 }
773
774 //*************************************************************************
776 //*************************************************************************
778 {
779 return const_reverse_iterator(end());
780 }
781
782 //*************************************************************************
784 //*************************************************************************
786 {
787 return reverse_iterator(begin());
788 }
789
790 //*************************************************************************
792 //*************************************************************************
794 {
796 }
797
798 //*************************************************************************
800 //*************************************************************************
802 {
804 }
805
806 //*************************************************************************
809 //*************************************************************************
810 reference front()
811 {
812 ETL_ASSERT(!empty(), ETL_ERROR(circular_buffer_empty));
813
814 return pbuffer[out];
815 }
816
817 //*************************************************************************
820 //*************************************************************************
821 const_reference front() const
822 {
823 ETL_ASSERT(!empty(), ETL_ERROR(circular_buffer_empty));
824
825 return pbuffer[out];
826 }
827
828 //*************************************************************************
831 //*************************************************************************
832 reference back()
833 {
834 ETL_ASSERT(!empty(), ETL_ERROR(circular_buffer_empty));
835
836 return pbuffer[in == 0U ? buffer_size - 1 : in - 1U];
837 }
838
839 //*************************************************************************
842 //*************************************************************************
843 const_reference back() const
844 {
845 ETL_ASSERT(!empty(), ETL_ERROR(circular_buffer_empty));
846
847 return pbuffer[in == 0U ? buffer_size - 1 : in - 1U];
848 }
849
850 //*************************************************************************
852 //*************************************************************************
853 reference operator [](size_t index)
854 {
855 return pbuffer[(out + index) % buffer_size];
856 }
857
858 //*************************************************************************
861 //*************************************************************************
862 const_reference operator [](size_t index) const
863 {
864 return pbuffer[(out + index) % buffer_size];
865 }
866
867 //*************************************************************************
871 //*************************************************************************
872 void push(const_reference item)
873 {
874 ::new (&pbuffer[in]) T(item);
875 increment_in();
876
877 // Did we catch up with the 'out' index?
878 if (in == out)
879 {
880 // Forget about the oldest one.
881 pbuffer[out].~T();
882 this->increment_out();
883 }
884 else
885 {
886 ETL_INCREMENT_DEBUG_COUNT;
887 }
888 }
889
890#if ETL_USING_CPP11
891 //*************************************************************************
895 //*************************************************************************
896 void push(rvalue_reference item)
897 {
898 ::new (&pbuffer[in]) T(etl::move(item));
899 increment_in();
900
901 // Did we catch up with the 'out' index?
902 if (in == out)
903 {
904 // Forget about the oldest item.
905 pbuffer[out].~T();
906 increment_out();
907 }
908 else
909 {
910 ETL_INCREMENT_DEBUG_COUNT;
911 }
912 }
913#endif
914
915 //*************************************************************************
917 //*************************************************************************
918 template <typename TIterator>
919 void push(TIterator first, const TIterator& last)
920 {
921 while (first != last)
922 {
923 push(*first);
924 ++first;
925 }
926 }
927
928 //*************************************************************************
930 //*************************************************************************
931 void pop()
932 {
933 ETL_ASSERT(!empty(), ETL_ERROR(circular_buffer_empty));
934 pbuffer[out].~T();
935 increment_out();
936 ETL_DECREMENT_DEBUG_COUNT
937 }
938
939 //*************************************************************************
941 //*************************************************************************
943 {
944 while (n-- != 0U)
945 {
946 pop();
947 }
948 }
949
950 //*************************************************************************
952 //*************************************************************************
953 void clear()
954 {
956 {
957 in = 0U;
958 out = 0U;
959 ETL_RESET_DEBUG_COUNT
960 }
961 else
962 {
963 while (!empty())
964 {
965 pop();
966 }
967 }
968 }
969
970 //*************************************************************************
972 //*************************************************************************
973 void fill(const T& value)
974 {
975 etl::fill(begin(), end(), value);
976 }
977
978#ifdef ETL_ICIRCULAR_BUFFER_REPAIR_ENABLE
979 //*************************************************************************
981 //*************************************************************************
982 virtual void repair() = 0;
983#endif
984
985 //*************************************************************************
987 //*************************************************************************
988 friend difference_type operator -(const iterator& lhs, const iterator& rhs)
989 {
990 return distance(rhs, lhs);
991 }
992
993 //*************************************************************************
995 //*************************************************************************
996 friend difference_type operator -(const const_iterator& lhs, const const_iterator& rhs)
997 {
998 return distance(rhs, lhs);
999 }
1000
1001 //*************************************************************************
1003 //*************************************************************************
1004 friend difference_type operator -(const reverse_iterator& lhs, const reverse_iterator& rhs)
1005 {
1006 return distance(lhs.base(), rhs.base());
1007 }
1008
1009 //*************************************************************************
1011 //*************************************************************************
1012 friend difference_type operator -(const const_reverse_iterator& lhs, const const_reverse_iterator& rhs)
1013 {
1014 return distance(lhs.base(), rhs.base());
1015 }
1016
1017 protected:
1018
1019 //*************************************************************************
1021 //*************************************************************************
1022 icircular_buffer(pointer pbuffer_, size_type max_length)
1023 : circular_buffer_base(max_length + 1U)
1024 , pbuffer(pbuffer_)
1025 {
1026 }
1027
1028 //*************************************************************************
1030 //*************************************************************************
1031 template <typename TIterator1, typename TIterator2>
1032 static difference_type distance(const TIterator1& range_begin, const TIterator2& range_end)
1033 {
1034 difference_type distance1 = distance(range_begin);
1035 difference_type distance2 = distance(range_end);
1036
1037 return distance2 - distance1;
1038 }
1039
1040 //*************************************************************************
1042 //*************************************************************************
1043 template <typename TIterator>
1044 static difference_type distance(const TIterator& other)
1045 {
1046 const difference_type index = other.get_index();
1047 const difference_type reference_index = other.container().out;
1048 const size_t buffer_size = other.container().buffer_size;
1049
1050 if (index < reference_index)
1051 {
1052 return buffer_size + index - reference_index;
1053 }
1054 else
1055 {
1056 return index - reference_index;
1057 }
1058 }
1059
1060 //*************************************************************************
1062 //*************************************************************************
1063 void repair_buffer(T* pbuffer_)
1064 {
1065 pbuffer = pbuffer_;
1066 }
1067
1068 pointer pbuffer;
1069
1070 private:
1071
1072 //*************************************************************************
1074 //*************************************************************************
1075#if defined(ETL_POLYMORPHIC_CIRCULAR_BUFFER) || defined(ETL_POLYMORPHIC_CONTAINERS)
1076 public:
1077 virtual ~icircular_buffer()
1078 {
1079 }
1080#else
1081 protected:
1083 {
1084 }
1085#endif
1086 };
1087
1088 //***************************************************************************
1091 //***************************************************************************
1092 template <typename T, size_t MAX_SIZE_>
1094 {
1095 public:
1096
1097 ETL_STATIC_ASSERT((MAX_SIZE_ > 0U), "Zero capacity etl::circular_buffer is not valid");
1098
1099 static ETL_CONSTANT typename icircular_buffer<T>::size_type MAX_SIZE = typename icircular_buffer<T>::size_type(MAX_SIZE_);
1100
1101 //*************************************************************************
1103 //*************************************************************************
1105 : icircular_buffer<T>(reinterpret_cast<T*>(buffer.raw), MAX_SIZE)
1106 {
1107 }
1108
1109 //*************************************************************************
1112 //*************************************************************************
1113 template <typename TIterator>
1114 circular_buffer(TIterator first, const TIterator& last, typename etl::enable_if<!etl::is_integral<TIterator>::value, int>::type = 0)
1115 : icircular_buffer<T>(reinterpret_cast<T*>(buffer.raw), MAX_SIZE)
1116 {
1117 while (first != last)
1118 {
1119 this->push(*first);
1120 ++first;
1121 }
1122 }
1123
1124#if ETL_HAS_INITIALIZER_LIST
1125 //*************************************************************************
1127 //*************************************************************************
1128 circular_buffer(std::initializer_list<T> init)
1129 : icircular_buffer<T>(reinterpret_cast<T*>(buffer.raw), MAX_SIZE)
1130 {
1131 this->push(init.begin(), init.end());
1132 }
1133#endif
1134
1135 //*************************************************************************
1137 //*************************************************************************
1139 : icircular_buffer<T>(reinterpret_cast<T*>(buffer.raw), MAX_SIZE)
1140 {
1141 if (this != &other)
1142 {
1143 this->push(other.begin(), other.end());
1144 }
1145 }
1146
1147 //*************************************************************************
1149 //*************************************************************************
1151 {
1152 if (this != &other)
1153 {
1154 this->clear();
1155 this->push(other.begin(), other.end());
1156 }
1157
1158 return *this;
1159 }
1160
1161#if ETL_USING_CPP11
1162 //*************************************************************************
1164 //*************************************************************************
1166 : icircular_buffer<T>(reinterpret_cast<T*>(buffer.raw), MAX_SIZE)
1167 {
1168 if (this != &other)
1169 {
1170 typename etl::icircular_buffer<T>::iterator itr = other.begin();
1171 while (itr != other.end())
1172 {
1173 this->push(etl::move(*itr));
1174 ++itr;
1175 }
1176 }
1177 }
1178
1179 //*************************************************************************
1181 //*************************************************************************
1183 {
1184 if (this != &other)
1185 {
1186 this->clear();
1187
1188 for (typename etl::icircular_buffer<T>::const_iterator itr = other.begin(); itr != other.end(); ++itr)
1189 {
1190 this->push(etl::move(*itr));
1191 }
1192 }
1193
1194 return *this;
1195 }
1196
1197#endif
1198
1199 //*************************************************************************
1201 //*************************************************************************
1203 {
1204 this->clear();
1205 }
1206
1207 //*************************************************************************
1209 //*************************************************************************
1210#ifdef ETL_ICIRCULAR_BUFFER_REPAIR_ENABLE
1211 virtual
1212#endif
1213 void repair()
1214#ifdef ETL_ICIRCULAR_BUFFER_REPAIR_ENABLE
1215 ETL_OVERRIDE
1216#endif
1217 {
1219
1221 }
1222
1223 private:
1224
1227 };
1228
1229 template <typename T, size_t MAX_SIZE_>
1230 ETL_CONSTANT typename icircular_buffer<T>::size_type circular_buffer<T, MAX_SIZE_>::MAX_SIZE;
1231
1232 //***************************************************************************
1235 //***************************************************************************
1236 template <typename T>
1238 {
1239 public:
1240
1241 //*************************************************************************
1243 //*************************************************************************
1244 circular_buffer_ext(void* buffer, size_t max_size)
1245 : icircular_buffer<T>(reinterpret_cast<T*>(buffer), max_size)
1246 {
1247 }
1248
1249 //*************************************************************************
1252 //*************************************************************************
1253 circular_buffer_ext(size_t max_size)
1254 : icircular_buffer<T>(ETL_NULLPTR, max_size)
1255 {
1256 }
1257
1258 //*************************************************************************
1261 //*************************************************************************
1262 template <typename TIterator>
1263 circular_buffer_ext(TIterator first, const TIterator& last, void* buffer, size_t max_size, typename etl::enable_if<!etl::is_integral<TIterator>::value, int>::type = 0)
1264 : icircular_buffer<T>(reinterpret_cast<T*>(buffer), max_size)
1265 {
1266 while (first != last)
1267 {
1268 this->push(*first);
1269 ++first;
1270 }
1271 }
1272
1273#if ETL_HAS_INITIALIZER_LIST
1274 //*************************************************************************
1276 //*************************************************************************
1277 circular_buffer_ext(std::initializer_list<T> init, void* buffer, size_t max_size)
1278 : icircular_buffer<T>(reinterpret_cast<T*>(buffer), max_size)
1279 {
1280 this->push(init.begin(), init.end());
1281 }
1282#endif
1283
1284 //*************************************************************************
1286 //*************************************************************************
1287 circular_buffer_ext(const circular_buffer_ext& other, void* buffer, size_t max_size)
1288 : icircular_buffer<T>(reinterpret_cast<T*>(buffer), max_size)
1289 {
1290 if (this != &other)
1291 {
1292 this->push(other.begin(), other.end());
1293 }
1294 }
1295
1296 //*************************************************************************
1298 //*************************************************************************
1300
1301 //*************************************************************************
1303 //*************************************************************************
1305 {
1306
1307 if (this != &other)
1308 {
1309 this->clear();
1310 this->push(other.begin(), other.end());
1311 }
1312
1313 return *this;
1314 }
1315
1316#if ETL_USING_CPP11
1317 //*************************************************************************
1319 //*************************************************************************
1320 circular_buffer_ext(circular_buffer_ext&& other, void* buffer, size_t max_size)
1321 : icircular_buffer<T>(reinterpret_cast<T*>(buffer), max_size)
1322 {
1323 if (this != &other)
1324 {
1325 typename etl::icircular_buffer<T>::iterator itr = other.begin();
1326 while (itr != other.end())
1327 {
1328 this->push(etl::move(*itr));
1329 ++itr;
1330 }
1331 }
1332 }
1333
1334 //*************************************************************************
1336 //*************************************************************************
1338 {
1339 if (this != &other)
1340 {
1341 this->clear();
1342
1343 for (typename etl::icircular_buffer<T>::iterator itr = other.begin(); itr != other.end(); ++itr)
1344 {
1345 this->push(etl::move(*itr));
1346 }
1347 }
1348
1349 return *this;
1350 }
1351#endif
1352
1353 //*************************************************************************
1355 //*************************************************************************
1356 void swap(circular_buffer_ext& other) ETL_NOEXCEPT
1357 {
1358 using ETL_OR_STD::swap; // Allow ADL
1359
1360 swap(this->in, other.in);
1361 swap(this->out, other.out);
1362 swap(this->pbuffer, other.pbuffer);
1363 swap(this->buffer_size, other.buffer_size);
1364
1365#if defined(ETL_DEBUG_COUNT)
1366 this->etl_debug_count.swap(other.etl_debug_count);
1367#endif
1368 }
1369
1370 //*************************************************************************
1372 //*************************************************************************
1373 void set_buffer(void* buffer)
1374 {
1375 this->pbuffer = reinterpret_cast<T*>(buffer);
1376 }
1377
1378 //*************************************************************************
1380 //*************************************************************************
1381 bool is_valid() const
1382 {
1383 return this->pbuffer != ETL_NULLPTR;
1384 }
1385
1386 //*************************************************************************
1388 //*************************************************************************
1390 {
1391 this->clear();
1392 }
1393
1394 //*************************************************************************
1396 //*************************************************************************
1397#ifdef ETL_ICIRCULAR_BUFFER_REPAIR_ENABLE
1398 virtual
1399#endif
1400 void repair()
1401#ifdef ETL_ICIRCULAR_BUFFER_REPAIR_ENABLE
1402 ETL_OVERRIDE
1403#endif
1404 {
1405 }
1406 };
1407
1408 //*************************************************************************
1410 //*************************************************************************
1411#if ETL_USING_CPP17 && ETL_HAS_INITIALIZER_LIST
1412 template <typename T, typename... Ts>
1413 circular_buffer(T, Ts...)
1414 ->circular_buffer<etl::enable_if_t<(etl::is_same_v<T, Ts> && ...), T>, 1U + sizeof...(Ts)>;
1415#endif
1416
1417 //*************************************************************************
1419 //*************************************************************************
1420 template <typename T>
1422 {
1423 lhs.swap(rhs);
1424 }
1425
1426 //*************************************************************************
1428 //*************************************************************************
1429 template <typename T>
1431 {
1432 return (lhs.size() == rhs.size()) && etl::equal(lhs.begin(), lhs.end(), rhs.begin());
1433 }
1434
1435 //*************************************************************************
1437 //*************************************************************************
1438 template <typename T>
1440 {
1441 return !(lhs == rhs);
1442 }
1443}
1444
1445#endif
Definition: circular_buffer.h:90
size_t size_type
The type used for determining the size of queue.
Definition: circular_buffer.h:94
size_type out
Index to the next read.
Definition: circular_buffer.h:172
size_type in
Index to the next write.
Definition: circular_buffer.h:171
Empty exception for the circular_buffer.
Definition: circular_buffer.h:64
Exception for the circular_buffer.
Definition: circular_buffer.h:51
Definition: circular_buffer.h:1238
void swap(circular_buffer_ext &other) ETL_NOEXCEPT
Swap with another circular buffer.
Definition: circular_buffer.h:1356
circular_buffer_ext & operator=(const circular_buffer_ext &other)
Assignment operator.
Definition: circular_buffer.h:1304
circular_buffer_ext(size_t max_size)
Definition: circular_buffer.h:1253
void set_buffer(void *buffer)
set_buffer
Definition: circular_buffer.h:1373
circular_buffer_ext(const circular_buffer_ext &other) ETL_DELETE
Copy Constructor (Deleted)
bool is_valid() const
set_buffer
Definition: circular_buffer.h:1381
circular_buffer_ext(void *buffer, size_t max_size)
Constructor.
Definition: circular_buffer.h:1244
circular_buffer_ext(const circular_buffer_ext &other, void *buffer, size_t max_size)
Construct a copy.
Definition: circular_buffer.h:1287
~circular_buffer_ext()
Destructor.
Definition: circular_buffer.h:1389
circular_buffer_ext(TIterator first, const TIterator &last, void *buffer, size_t max_size, typename etl::enable_if<!etl::is_integral< TIterator >::value, int >::type=0)
Definition: circular_buffer.h:1263
void repair()
Fix the internal pointers after a low level memory copy.
Definition: circular_buffer.h:1400
Incompatible type exception.
Definition: circular_buffer.h:77
Definition: circular_buffer.h:1094
circular_buffer(TIterator first, const TIterator &last, typename etl::enable_if<!etl::is_integral< TIterator >::value, int >::type=0)
Definition: circular_buffer.h:1114
circular_buffer & operator=(const circular_buffer &other)
Assignment operator.
Definition: circular_buffer.h:1150
circular_buffer(const circular_buffer &other)
Copy Constructor.
Definition: circular_buffer.h:1138
~circular_buffer()
Destructor.
Definition: circular_buffer.h:1202
void repair()
Fix the internal pointers after a low level memory copy.
Definition: circular_buffer.h:1213
circular_buffer()
Constructor.
Definition: circular_buffer.h:1104
Iterator iterating through the circular buffer.
Definition: circular_buffer.h:450
const_iterator & operator-=(int n)
Subtract offset.
Definition: circular_buffer.h:592
const_iterator()
Constructor.
Definition: circular_buffer.h:458
const_iterator(const icircular_buffer< T > *picb_, size_type current_)
Protected constructor. Only icircular_buffer can create one.
Definition: circular_buffer.h:692
const_iterator(const typename icircular_buffer::iterator &other)
Copy Constructor from iterator.
Definition: circular_buffer.h:467
friend bool operator!=(const const_iterator &lhs, const const_iterator &rhs)
Inequality operator.
Definition: circular_buffer.h:632
const_iterator & operator+=(int n)
Add offset.
Definition: circular_buffer.h:581
const_iterator & operator--()
Pre-decrement.
Definition: circular_buffer.h:551
friend bool operator==(const const_iterator &lhs, const const_iterator &rhs)
Equality operator.
Definition: circular_buffer.h:624
const_iterator(const const_iterator &other)
Copy Constructor from const iterator.
Definition: circular_buffer.h:476
const_iterator & operator++()
Pre-increment.
Definition: circular_buffer.h:523
const_reference operator*() const
Definition: circular_buffer.h:507
friend const_iterator operator-(const const_iterator &lhs, int n)
Subtract offset.
Definition: circular_buffer.h:612
const_pointer operator->() const
-> operator
Definition: circular_buffer.h:515
friend const_iterator operator+(const const_iterator &lhs, int n)
Add offset.
Definition: circular_buffer.h:600
const_iterator & operator=(const typename icircular_buffer::iterator &other)
Assignment operator.
Definition: circular_buffer.h:485
Iterator iterating through the circular buffer.
Definition: circular_buffer.h:199
iterator(const icircular_buffer< T > *picb_, size_type current_)
Protected constructor. Only icircular_buffer can create one.
Definition: circular_buffer.h:434
iterator & operator+=(int n)
Add offset.
Definition: circular_buffer.h:310
friend bool operator==(const iterator &lhs, const iterator &rhs)
Equality operator.
Definition: circular_buffer.h:353
iterator & operator--()
Pre-decrement.
Definition: circular_buffer.h:280
friend iterator operator-(const iterator &lhs, int n)
Subtract offset.
Definition: circular_buffer.h:341
pointer operator->() const
-> operator
Definition: circular_buffer.h:244
iterator & operator-=(int n)
Subtract offset.
Definition: circular_buffer.h:321
friend iterator operator+(const iterator &lhs, int n)
Add offset.
Definition: circular_buffer.h:329
reference operator*() const
Definition: circular_buffer.h:236
iterator & operator=(const iterator &other)
Assignment operator.
Definition: circular_buffer.h:225
iterator()
Constructor.
Definition: circular_buffer.h:207
friend bool operator!=(const iterator &lhs, const iterator &rhs)
Inequality operator.
Definition: circular_buffer.h:361
iterator & operator++()
Pre-increment.
Definition: circular_buffer.h:252
iterator(const iterator &other)
Copy Constructor.
Definition: circular_buffer.h:216
Definition: circular_buffer.h:181
static difference_type distance(const TIterator1 &range_begin, const TIterator2 &range_end)
Measures the distance between two iterators.
Definition: circular_buffer.h:1032
void fill(const T &value)
Fills the buffer.
Definition: circular_buffer.h:973
const_reverse_iterator rend() const
Gets a const reverse iterator to the end of the buffer.
Definition: circular_buffer.h:793
void pop()
pop
Definition: circular_buffer.h:931
reverse_iterator rend()
Gets a reverse iterator to the end of the buffer.
Definition: circular_buffer.h:785
const_reverse_iterator rbegin() const
Gets a const reverse iterator to the start of the buffer.
Definition: circular_buffer.h:769
void push(TIterator first, const TIterator &last)
Push a buffer from an iterator range.
Definition: circular_buffer.h:919
friend difference_type operator-(const iterator &lhs, const iterator &rhs)
Definition: circular_buffer.h:988
const_iterator end() const
Gets a const iterator to the end of the buffer.
Definition: circular_buffer.h:745
const_reference back() const
Definition: circular_buffer.h:843
iterator end()
Gets an iterator to the end of the buffer.
Definition: circular_buffer.h:737
iterator begin()
Gets an iterator to the start of the buffer.
Definition: circular_buffer.h:713
const_iterator begin() const
Gets a const iterator to the start of the buffer.
Definition: circular_buffer.h:721
const_iterator cbegin() const
Gets a const iterator to the start of the buffer.
Definition: circular_buffer.h:729
const_reverse_iterator crend() const
Gets a const reverse iterator to the end of the buffer.
Definition: circular_buffer.h:801
reference front()
Definition: circular_buffer.h:810
void clear()
Clears the buffer.
Definition: circular_buffer.h:953
void repair_buffer(T *pbuffer_)
Fix the internal pointers after a low level memory copy.
Definition: circular_buffer.h:1063
reference back()
Definition: circular_buffer.h:832
icircular_buffer(pointer pbuffer_, size_type max_length)
Protected constructor.
Definition: circular_buffer.h:1022
reverse_iterator rbegin()
Gets a reverse iterator to the start of the buffer.
Definition: circular_buffer.h:761
void pop(size_type n)
pop(n)
Definition: circular_buffer.h:942
reference operator[](size_t index)
Get a reference to the item.
Definition: circular_buffer.h:853
void push(const_reference item)
Definition: circular_buffer.h:872
const_iterator cend() const
Gets a const iterator to the end of the buffer.
Definition: circular_buffer.h:753
const_reverse_iterator crbegin() const
Gets a const reverse iterator to the start of the buffer.
Definition: circular_buffer.h:777
static difference_type distance(const TIterator &other)
Measures the distance from the _begin iterator to the specified iterator.
Definition: circular_buffer.h:1044
~icircular_buffer()
Destructor.
Definition: circular_buffer.h:1082
const_reference front() const
Definition: circular_buffer.h:821
Definition: iterator.h:228
#define ETL_ASSERT(b, e)
Definition: error_handler.h:316
ETL_CONSTEXPR exception(string_type reason_, string_type, numeric_type line_)
Constructor.
Definition: exception.h:69
Definition: exception.h:47
enable_if
Definition: type_traits_generator.h:1191
is_integral
Definition: type_traits_generator.h:1001
bitset_ext
Definition: absolute.h:38
bool operator>(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition: array.h:684
size_t max_size() const
Returns the maximum number of items in the variant_pool.
Definition: variant_pool_generator.h:281
void swap(etl::circular_buffer_ext< T > &lhs, etl::circular_buffer_ext< T > &rhs)
Template deduction guides.
Definition: circular_buffer.h:1421
bool operator>=(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition: array.h:696
bool operator!=(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition: array.h:645
void swap(etl::array< T, SIZE > &lhs, etl::array< T, SIZE > &rhs)
Template deduction guides.
Definition: array.h:621
bool operator==(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition: array.h:633
bool operator<(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition: array.h:657
bool operator<=(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition: array.h:672
Definition: type_traits_generator.h:2069
Definition: type_traits_generator.h:2055
iterator
Definition: iterator.h:399