Embedded Template Library 1.0
Loading...
Searching...
No Matches
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 //***************************************************************************
59
60 //***************************************************************************
62 //***************************************************************************
64 {
65 public:
66
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
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;
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 //*************************************************************************
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 //*************************************************************************
237 {
238 return picb->pbuffer[current];
239 }
240
241 //*************************************************************************
243 //*************************************************************************
245 {
246 return &picb->pbuffer[current];
247 }
248
249 //*************************************************************************
251 //*************************************************************************
252 reference operator [](size_t index)
253 {
254 return picb->pbuffer[(current + index) % picb->buffer_size];
255 }
256
257 //*************************************************************************
259 //*************************************************************************
260 const_reference operator [](size_t index) const
261 {
262 return picb->pbuffer[(current + index) % picb->buffer_size];
263 }
264
265 //*************************************************************************
267 //*************************************************************************
269 {
270 ++current;
271
272 // Did we reach the end of the buffer?
273 if (current == picb->buffer_size)
274 {
275 current = 0U;
276 }
277
278 return (*this);
279 }
280
281 //*************************************************************************
283 //*************************************************************************
285 {
286 iterator original(*this);
287
288 ++(*this);
289
290 return (original);
291 }
292
293 //*************************************************************************
295 //*************************************************************************
297 {
298 // Are we at the end of the buffer?
299 if (current == 0U)
300 {
301 current = picb->buffer_size - 1;
302 }
303 else
304 {
305 --current;
306 }
307
308 return (*this);
309 }
310
311 //*************************************************************************
313 //*************************************************************************
315 {
316 iterator original(*this);
317
318 --(*this);
319
320 return (original);
321 }
322
323 //*************************************************************************
325 //*************************************************************************
327 {
328 current += size_type(picb->buffer_size + n);
329 current %= picb->buffer_size;
330
331 return (*this);
332 }
333
334 //*************************************************************************
336 //*************************************************************************
338 {
339 return (this->operator+=(-n));
340 }
341
342 //*************************************************************************
344 //*************************************************************************
345 friend iterator operator +(const iterator& lhs, int n)
346 {
347 iterator temp = lhs;
348
349 temp += n;
350
351 return temp;
352 }
353
354 //*************************************************************************
356 //*************************************************************************
357 friend iterator operator +(int n, const iterator& rhs)
358 {
359 iterator temp = rhs;
360
361 temp += n;
362
363 return temp;
364 }
365
366 //*************************************************************************
368 //*************************************************************************
369 friend iterator operator -(const iterator& lhs, int n)
370 {
371 iterator temp = lhs;
372
373 temp -= n;
374
375 return temp;
376 }
377
378 //*************************************************************************
380 //*************************************************************************
381 friend bool operator == (const iterator& lhs, const iterator& rhs)
382 {
383 return (lhs.current == rhs.current);
384 }
385
386 //*************************************************************************
388 //*************************************************************************
389 friend bool operator != (const iterator& lhs, const iterator& rhs)
390 {
391 return !(lhs == rhs);
392 }
393
394 //***************************************************
395 friend bool operator < (const iterator& lhs, const iterator& rhs)
396 {
397 const difference_type lhs_index = lhs.get_index();
398 const difference_type rhs_index = rhs.get_index();
399 const difference_type reference_index = lhs.container().begin().get_index();
400 const size_t buffer_size = lhs.container().max_size() + 1UL;
401
402 const difference_type lhs_distance = (lhs_index < reference_index) ? buffer_size + lhs_index - reference_index : lhs_index - reference_index;
403 const difference_type rhs_distance = (rhs_index < reference_index) ? buffer_size + rhs_index - reference_index : rhs_index - reference_index;
404
405 return lhs_distance < rhs_distance;
406 }
407
408 //***************************************************
409 friend bool operator <= (const iterator& lhs, const iterator& rhs)
410 {
411 return !(lhs > rhs);
412 }
413
414 //***************************************************
415 friend bool operator > (const iterator& lhs, const iterator& rhs)
416 {
417 return (rhs < lhs);
418 }
419
420 //***************************************************
421 friend bool operator >= (const iterator& lhs, const iterator& rhs)
422 {
423 return !(lhs < rhs);
424 }
425
426 //***************************************************
427 difference_type get_index() const
428 {
429 return current;
430 }
431
432 //***************************************************
433 const icircular_buffer& container() const
434 {
435 return *picb;
436 }
437
438 //***************************************************
439 pointer get_buffer() const
440 {
441 return picb->pbuffer;
442 }
443
444 protected:
445
446 //***************************************************
447 difference_type distance(difference_type firstIndex, difference_type index) const
448 {
449 if (index < firstIndex)
450 {
451 return picb->buffer_size + current - firstIndex;
452 }
453 else
454 {
455 return index - firstIndex;
456 }
457 }
458
459 //*************************************************************************
461 //*************************************************************************
463 : picb(picb_)
464 , current(current_)
465 {
466 }
467
468 private:
469
470 const icircular_buffer<T>* picb;
471 size_type current;
472 };
473
474 //*************************************************************************
476 //*************************************************************************
477 class const_iterator : public etl::iterator<ETL_OR_STD::random_access_iterator_tag, const T>
478 {
479 public:
480
481 friend class icircular_buffer;
482
483 //*************************************************************************
485 //*************************************************************************
487 : picb(ETL_NULLPTR)
488 , current(0U)
489 {
490 }
491
492 //*************************************************************************
494 //*************************************************************************
496 : picb(other.picb)
497 , current(other.current)
498 {
499 }
500
501 //*************************************************************************
503 //*************************************************************************
505 : picb(other.picb)
506 , current(other.current)
507 {
508 }
509
510 //*************************************************************************
512 //*************************************************************************
514 {
515 picb = other.picb;
516 current = other.current;
517
518 return *this;
519 }
520
521 //*************************************************************************
523 //*************************************************************************
525 {
526 picb = other.picb;
527 current = other.current;
528
529 return *this;
530 }
531
532 //*************************************************************************
534 //*************************************************************************
536 {
537 return picb->pbuffer[current];
538 }
539
540 //*************************************************************************
542 //*************************************************************************
544 {
545 return &(picb->pbuffer[current]);
546 }
547
548 //*************************************************************************
550 //*************************************************************************
551 const_reference operator [](size_t index) const
552 {
553 return picb->pbuffer[(current + index) % picb->buffer_size];
554 }
555
556 //*************************************************************************
558 //*************************************************************************
560 {
561 ++current;
562
563 // Did we reach the end of the buffer?
564 if (current == picb->buffer_size)
565 {
566 current = 0U;
567 }
568
569 return (*this);
570 }
571
572 //*************************************************************************
574 //*************************************************************************
576 {
578
579 ++(*this);
580
581 return (original);
582 }
583
584 //*************************************************************************
586 //*************************************************************************
588 {
589 // Are we at the end of the buffer?
590 if (current == 0U)
591 {
592 current = picb->buffer_size - 1;
593 }
594 else
595 {
596 --current;
597 }
598
599 return (*this);
600 }
601
602 //*************************************************************************
604 //*************************************************************************
606 {
608
609 --(*this);
610
611 return (original);
612 }
613
614 //*************************************************************************
616 //*************************************************************************
618 {
619 current += size_type(picb->buffer_size + n);
620 current %= picb->buffer_size;
621
622 return (*this);
623 }
624
625 //*************************************************************************
627 //*************************************************************************
629 {
630 return (this->operator+=(-n));
631 }
632
633 //*************************************************************************
635 //*************************************************************************
637 {
639
640 temp += n;
641
642 return temp;
643 }
644
645 //*************************************************************************
647 //*************************************************************************
649 {
651
652 temp -= n;
653
654 return temp;
655 }
656
657 //*************************************************************************
659 //*************************************************************************
661 {
662 return (lhs.current == rhs.current);
663 }
664
665 //*************************************************************************
667 //*************************************************************************
669 {
670 return !(lhs == rhs);
671 }
672
673 //***************************************************
674 friend bool operator < (const const_iterator& lhs, const const_iterator& rhs)
675 {
676 const difference_type lhs_index = lhs.get_index();
677 const difference_type rhs_index = rhs.get_index();
678 const difference_type reference_index = lhs.container().begin().get_index();
679 const size_t buffer_size = lhs.container().max_size() + 1UL;
680
681 const difference_type lhs_distance = (lhs_index < reference_index) ? buffer_size + lhs_index - reference_index : lhs_index - reference_index;
682 const difference_type rhs_distance = (rhs_index < reference_index) ? buffer_size + rhs_index - reference_index : rhs_index - reference_index;
683
684 return lhs_distance < rhs_distance;
685 }
686
687 //***************************************************
688 friend bool operator <= (const const_iterator& lhs, const const_iterator& rhs)
689 {
690 return !(lhs > rhs);
691 }
692
693 //***************************************************
694 friend bool operator > (const const_iterator& lhs, const const_iterator& rhs)
695 {
696 return (rhs < lhs);
697 }
698
699 //***************************************************
700 friend bool operator >= (const const_iterator& lhs, const const_iterator& rhs)
701 {
702 return !(lhs < rhs);
703 }
704
705 //***************************************************
706 difference_type get_index() const
707 {
708 return current;
709 }
710
711 //***************************************************
712 const icircular_buffer& container() const
713 {
714 return *picb;
715 }
716
717 //***************************************************
718 pointer get_buffer() const
719 {
720 return picb->pbuffer;
721 }
722
723 protected:
724
725 //*************************************************************************
727 //*************************************************************************
729 : picb(picb_)
730 , current(current_)
731 {
732 }
733
734 private:
735
736 const icircular_buffer<T>* picb;
737 size_type current;
738 };
739
740 friend class iterator;
741 friend class const_iterator;
742
744 typedef etl::reverse_iterator<const_iterator> const_reverse_iterator;
745
746 //*************************************************************************
748 //*************************************************************************
750 {
751 return iterator(this, out);
752 }
753
754 //*************************************************************************
756 //*************************************************************************
758 {
759 return const_iterator(this, out);
760 }
761
762 //*************************************************************************
764 //*************************************************************************
766 {
767 return const_iterator(this, out);
768 }
769
770 //*************************************************************************
772 //*************************************************************************
774 {
775 return iterator(this, in);
776 }
777
778 //*************************************************************************
780 //*************************************************************************
782 {
783 return const_iterator(this, in);
784 }
785
786 //*************************************************************************
788 //*************************************************************************
790 {
791 return const_iterator(this, in);
792 }
793
794 //*************************************************************************
796 //*************************************************************************
798 {
799 return reverse_iterator(end());
800 }
801
802 //*************************************************************************
804 //*************************************************************************
806 {
807 return const_reverse_iterator(end());
808 }
809
810 //*************************************************************************
812 //*************************************************************************
814 {
815 return const_reverse_iterator(end());
816 }
817
818 //*************************************************************************
820 //*************************************************************************
822 {
823 return reverse_iterator(begin());
824 }
825
826 //*************************************************************************
828 //*************************************************************************
830 {
832 }
833
834 //*************************************************************************
836 //*************************************************************************
838 {
840 }
841
842 //*************************************************************************
845 //*************************************************************************
847 {
848 ETL_ASSERT(!empty(), ETL_ERROR(circular_buffer_empty));
849
850 return pbuffer[out];
851 }
852
853 //*************************************************************************
856 //*************************************************************************
858 {
859 ETL_ASSERT(!empty(), ETL_ERROR(circular_buffer_empty));
860
861 return pbuffer[out];
862 }
863
864 //*************************************************************************
867 //*************************************************************************
869 {
870 ETL_ASSERT(!empty(), ETL_ERROR(circular_buffer_empty));
871
872 return pbuffer[in == 0U ? buffer_size - 1 : in - 1U];
873 }
874
875 //*************************************************************************
878 //*************************************************************************
880 {
881 ETL_ASSERT(!empty(), ETL_ERROR(circular_buffer_empty));
882
883 return pbuffer[in == 0U ? buffer_size - 1 : in - 1U];
884 }
885
886 //*************************************************************************
888 //*************************************************************************
889 reference operator [](size_t index)
890 {
891 return pbuffer[(out + index) % buffer_size];
892 }
893
894 //*************************************************************************
897 //*************************************************************************
898 const_reference operator [](size_t index) const
899 {
900 return pbuffer[(out + index) % buffer_size];
901 }
902
903 //*************************************************************************
907 //*************************************************************************
909 {
910 ::new (&pbuffer[in]) T(item);
911 increment_in();
912
913 // Did we catch up with the 'out' index?
914 if (in == out)
915 {
916 // Forget about the oldest one.
917 pbuffer[out].~T();
918 this->increment_out();
919 }
920 else
921 {
922 ETL_INCREMENT_DEBUG_COUNT;
923 }
924 }
925
926#if ETL_USING_CPP11
927 //*************************************************************************
931 //*************************************************************************
933 {
934 ::new (&pbuffer[in]) T(etl::move(item));
935 increment_in();
936
937 // Did we catch up with the 'out' index?
938 if (in == out)
939 {
940 // Forget about the oldest item.
941 pbuffer[out].~T();
942 increment_out();
943 }
944 else
945 {
946 ETL_INCREMENT_DEBUG_COUNT;
947 }
948 }
949#endif
950
951 //*************************************************************************
953 //*************************************************************************
954 template <typename TIterator>
955 void push(TIterator first, const TIterator& last)
956 {
957 while (first != last)
958 {
959 push(*first);
960 ++first;
961 }
962 }
963
964 //*************************************************************************
966 //*************************************************************************
967 void pop()
968 {
969 ETL_ASSERT(!empty(), ETL_ERROR(circular_buffer_empty));
970 pbuffer[out].~T();
971 increment_out();
972 ETL_DECREMENT_DEBUG_COUNT;
973 }
974
975 //*************************************************************************
977 //*************************************************************************
979 {
980 while (n-- != 0U)
981 {
982 pop();
983 }
984 }
985
986 //*************************************************************************
988 //*************************************************************************
989 void clear()
990 {
992 {
993 in = 0U;
994 out = 0U;
995 ETL_RESET_DEBUG_COUNT;
996 }
997 else
998 {
999 while (!empty())
1000 {
1001 pop();
1002 }
1003 }
1004 }
1005
1006 //*************************************************************************
1008 //*************************************************************************
1009 void fill(const T& value)
1010 {
1011 etl::fill(begin(), end(), value);
1012 }
1013
1014#ifdef ETL_ICIRCULAR_BUFFER_REPAIR_ENABLE
1015 //*************************************************************************
1017 //*************************************************************************
1018 virtual void repair() = 0;
1019#endif
1020
1021 //*************************************************************************
1023 //*************************************************************************
1024 friend difference_type operator -(const iterator& lhs, const iterator& rhs)
1025 {
1026 return distance(rhs, lhs);
1027 }
1028
1029 //*************************************************************************
1031 //*************************************************************************
1032 friend difference_type operator -(const const_iterator& lhs, const const_iterator& rhs)
1033 {
1034 return distance(rhs, lhs);
1035 }
1036
1037 protected:
1038
1039 //*************************************************************************
1041 //*************************************************************************
1047
1048 //*************************************************************************
1050 //*************************************************************************
1051 template <typename TIterator1, typename TIterator2>
1052 static difference_type distance(const TIterator1& range_begin, const TIterator2& range_end)
1053 {
1054 difference_type distance1 = distance(range_begin);
1055 difference_type distance2 = distance(range_end);
1056
1057 return distance2 - distance1;
1058 }
1059
1060 //*************************************************************************
1062 //*************************************************************************
1063 template <typename TIterator>
1064 static difference_type distance(const TIterator& other)
1065 {
1066 const difference_type index = other.get_index();
1067 const difference_type reference_index = other.container().out;
1068 const size_t buffer_size = other.container().buffer_size;
1069
1070 if (index < reference_index)
1071 {
1072 return buffer_size + index - reference_index;
1073 }
1074 else
1075 {
1076 return index - reference_index;
1077 }
1078 }
1079
1080 //*************************************************************************
1082 //*************************************************************************
1084 {
1085 pbuffer = pbuffer_;
1086 }
1087
1088 pointer pbuffer;
1089
1090 private:
1091
1092 //*************************************************************************
1094 //*************************************************************************
1095#if defined(ETL_POLYMORPHIC_CIRCULAR_BUFFER) || defined(ETL_POLYMORPHIC_CONTAINERS)
1096 public:
1097 virtual ~icircular_buffer()
1098 {
1099 }
1100#else
1101 protected:
1103 {
1104 }
1105#endif
1106 };
1107
1108 //***************************************************************************
1111 //***************************************************************************
1112 template <typename T, size_t MAX_SIZE_>
1114 {
1115 public:
1116
1117 ETL_STATIC_ASSERT((MAX_SIZE_ > 0U), "Zero capacity etl::circular_buffer is not valid");
1118
1119 static ETL_CONSTANT typename icircular_buffer<T>::size_type MAX_SIZE = typename icircular_buffer<T>::size_type(MAX_SIZE_);
1120
1121 //*************************************************************************
1123 //*************************************************************************
1125 : icircular_buffer<T>(reinterpret_cast<T*>(buffer.raw), MAX_SIZE)
1126 {
1127 }
1128
1129 //*************************************************************************
1132 //*************************************************************************
1133 template <typename TIterator>
1135 : icircular_buffer<T>(reinterpret_cast<T*>(buffer.raw), MAX_SIZE)
1136 {
1137 while (first != last)
1138 {
1139 this->push(*first);
1140 ++first;
1141 }
1142 }
1143
1144#if ETL_HAS_INITIALIZER_LIST
1145 //*************************************************************************
1147 //*************************************************************************
1148 circular_buffer(std::initializer_list<T> init)
1149 : icircular_buffer<T>(reinterpret_cast<T*>(buffer.raw), MAX_SIZE)
1150 {
1151 this->push(init.begin(), init.end());
1152 }
1153#endif
1154
1155 //*************************************************************************
1157 //*************************************************************************
1159 : icircular_buffer<T>(reinterpret_cast<T*>(buffer.raw), MAX_SIZE)
1160 {
1161 if (this != &other)
1162 {
1163 this->push(other.begin(), other.end());
1164 }
1165 }
1166
1167 //*************************************************************************
1169 //*************************************************************************
1171 {
1172 if (this != &other)
1173 {
1174 this->clear();
1175 this->push(other.begin(), other.end());
1176 }
1177
1178 return *this;
1179 }
1180
1181#if ETL_USING_CPP11
1182 //*************************************************************************
1184 //*************************************************************************
1186 : icircular_buffer<T>(reinterpret_cast<T*>(buffer.raw), MAX_SIZE)
1187 {
1188 if (this != &other)
1189 {
1190 typename etl::icircular_buffer<T>::iterator itr = other.begin();
1191 while (itr != other.end())
1192 {
1193 this->push(etl::move(*itr));
1194 ++itr;
1195 }
1196 }
1197 }
1198
1199 //*************************************************************************
1201 //*************************************************************************
1203 {
1204 if (this != &other)
1205 {
1206 this->clear();
1207
1208 for (typename etl::icircular_buffer<T>::const_iterator itr = other.begin(); itr != other.end(); ++itr)
1209 {
1210 this->push(etl::move(*itr));
1211 }
1212 }
1213
1214 return *this;
1215 }
1216
1217#endif
1218
1219 //*************************************************************************
1221 //*************************************************************************
1223 {
1224 this->clear();
1225 }
1226
1227 //*************************************************************************
1229 //*************************************************************************
1230#ifdef ETL_ICIRCULAR_BUFFER_REPAIR_ENABLE
1231 virtual void repair() ETL_OVERRIDE
1232#else
1240
1241 private:
1242
1245 };
1246
1247 template <typename T, size_t MAX_SIZE_>
1248 ETL_CONSTANT typename icircular_buffer<T>::size_type circular_buffer<T, MAX_SIZE_>::MAX_SIZE;
1249
1250 //***************************************************************************
1253 //***************************************************************************
1254 template <typename T>
1256 {
1257 public:
1258
1259 //*************************************************************************
1261 //*************************************************************************
1262 circular_buffer_ext(void* buffer, size_t max_size)
1264 {
1265 }
1266
1267 //*************************************************************************
1270 //*************************************************************************
1271 circular_buffer_ext(size_t max_size)
1272 : icircular_buffer<T>(ETL_NULLPTR, max_size)
1273 {
1274 }
1275
1276 //*************************************************************************
1279 //*************************************************************************
1280 template <typename TIterator>
1281 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)
1283 {
1284 while (first != last)
1285 {
1286 this->push(*first);
1287 ++first;
1288 }
1289 }
1290
1291#if ETL_HAS_INITIALIZER_LIST
1292 //*************************************************************************
1294 //*************************************************************************
1295 circular_buffer_ext(std::initializer_list<T> init, void* buffer, size_t max_size)
1297 {
1298 this->push(init.begin(), init.end());
1299 }
1300#endif
1301
1302 //*************************************************************************
1304 //*************************************************************************
1305 circular_buffer_ext(const circular_buffer_ext& other, void* buffer, size_t max_size)
1307 {
1308 if (this != &other)
1309 {
1310 this->push(other.begin(), other.end());
1311 }
1312 }
1313
1314 //*************************************************************************
1316 //*************************************************************************
1318
1319 //*************************************************************************
1321 //*************************************************************************
1323 {
1324
1325 if (this != &other)
1326 {
1327 this->clear();
1328 this->push(other.begin(), other.end());
1329 }
1330
1331 return *this;
1332 }
1333
1334#if ETL_USING_CPP11
1335 //*************************************************************************
1337 //*************************************************************************
1338 circular_buffer_ext(circular_buffer_ext&& other, void* buffer, size_t max_size)
1340 {
1341 if (this != &other)
1342 {
1343 typename etl::icircular_buffer<T>::iterator itr = other.begin();
1344 while (itr != other.end())
1345 {
1346 this->push(etl::move(*itr));
1347 ++itr;
1348 }
1349 }
1350 }
1351
1352 //*************************************************************************
1354 //*************************************************************************
1355 circular_buffer_ext& operator =(circular_buffer_ext&& other)
1356 {
1357 if (this != &other)
1358 {
1359 this->clear();
1360
1361 for (typename etl::icircular_buffer<T>::iterator itr = other.begin(); itr != other.end(); ++itr)
1362 {
1363 this->push(etl::move(*itr));
1364 }
1365 }
1366
1367 return *this;
1368 }
1369#endif
1370
1371 //*************************************************************************
1373 //*************************************************************************
1374 void swap(circular_buffer_ext& other) ETL_NOEXCEPT
1375 {
1376 using ETL_OR_STD::swap; // Allow ADL
1377
1378 swap(this->in, other.in);
1379 swap(this->out, other.out);
1380 swap(this->pbuffer, other.pbuffer);
1381 swap(this->buffer_size, other.buffer_size);
1382
1383#if defined(ETL_DEBUG_COUNT)
1384 this->etl_debug_count.swap(other.etl_debug_count);
1385#endif
1386 }
1387
1388 //*************************************************************************
1390 //*************************************************************************
1391 void set_buffer(void* buffer)
1392 {
1393 this->pbuffer = reinterpret_cast<T*>(buffer);
1394 }
1395
1396 //*************************************************************************
1398 //*************************************************************************
1399 bool is_valid() const
1400 {
1401 return this->pbuffer != ETL_NULLPTR;
1402 }
1403
1404 //*************************************************************************
1406 //*************************************************************************
1408 {
1409 this->clear();
1410 }
1411
1412 //*************************************************************************
1414 //*************************************************************************
1415#ifdef ETL_ICIRCULAR_BUFFER_REPAIR_ENABLE
1416 virtual void repair() ETL_OVERRIDE
1417#else
1418 void repair()
1419#endif
1420 {
1421 }
1422 };
1423
1424 //*************************************************************************
1426 //*************************************************************************
1427#if ETL_USING_CPP17 && ETL_HAS_INITIALIZER_LIST
1428 template <typename T, typename... Ts>
1429 circular_buffer(T, Ts...)
1430 ->circular_buffer<etl::enable_if_t<(etl::is_same_v<T, Ts> && ...), T>, 1U + sizeof...(Ts)>;
1431#endif
1432
1433 //*************************************************************************
1435 //*************************************************************************
1436 template <typename T>
1441
1442 //*************************************************************************
1444 //*************************************************************************
1445 template <typename T>
1447 {
1448 return (lhs.size() == rhs.size()) && etl::equal(lhs.begin(), lhs.end(), rhs.begin());
1449 }
1450
1451 //*************************************************************************
1453 //*************************************************************************
1454 template <typename T>
1456 {
1457 return !(lhs == rhs);
1458 }
1459}
1460
1461#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
ETL_DECLARE_DEBUG_COUNT
Internal debugging.
Definition circular_buffer.h:173
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:1256
void swap(circular_buffer_ext &other) ETL_NOEXCEPT
Swap with another circular buffer.
Definition circular_buffer.h:1374
circular_buffer_ext & operator=(const circular_buffer_ext &other)
Assignment operator.
Definition circular_buffer.h:1322
circular_buffer_ext(size_t max_size)
Definition circular_buffer.h:1271
void set_buffer(void *buffer)
set_buffer
Definition circular_buffer.h:1391
circular_buffer_ext(const circular_buffer_ext &other) ETL_DELETE
Copy Constructor (Deleted)
bool is_valid() const
set_buffer
Definition circular_buffer.h:1399
circular_buffer_ext(void *buffer, size_t max_size)
Constructor.
Definition circular_buffer.h:1262
circular_buffer_ext(const circular_buffer_ext &other, void *buffer, size_t max_size)
Construct a copy.
Definition circular_buffer.h:1305
~circular_buffer_ext()
Destructor.
Definition circular_buffer.h:1407
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:1281
void repair()
Fix the internal pointers after a low level memory copy.
Definition circular_buffer.h:1418
Incompatible type exception.
Definition circular_buffer.h:77
Definition circular_buffer.h:1114
circular_buffer(TIterator first, const TIterator &last, typename etl::enable_if<!etl::is_integral< TIterator >::value, int >::type=0)
Definition circular_buffer.h:1134
circular_buffer & operator=(const circular_buffer &other)
Assignment operator.
Definition circular_buffer.h:1170
circular_buffer(const circular_buffer &other)
Copy Constructor.
Definition circular_buffer.h:1158
~circular_buffer()
Destructor.
Definition circular_buffer.h:1222
void repair()
Fix the internal pointers after a low level memory copy.
Definition circular_buffer.h:1233
circular_buffer()
Constructor.
Definition circular_buffer.h:1124
Iterator iterating through the circular buffer.
Definition circular_buffer.h:478
const_iterator & operator-=(int n)
Subtract offset.
Definition circular_buffer.h:628
const_iterator()
Constructor.
Definition circular_buffer.h:486
const_iterator(const icircular_buffer< T > *picb_, size_type current_)
Protected constructor. Only icircular_buffer can create one.
Definition circular_buffer.h:728
const_iterator(const typename icircular_buffer::iterator &other)
Copy Constructor from iterator.
Definition circular_buffer.h:495
const_reference operator[](size_t index) const
[] operator
Definition circular_buffer.h:551
friend bool operator!=(const const_iterator &lhs, const const_iterator &rhs)
Inequality operator.
Definition circular_buffer.h:668
const_iterator & operator+=(int n)
Add offset.
Definition circular_buffer.h:617
const_iterator & operator--()
Pre-decrement.
Definition circular_buffer.h:587
friend bool operator==(const const_iterator &lhs, const const_iterator &rhs)
Equality operator.
Definition circular_buffer.h:660
const_iterator(const const_iterator &other)
Copy Constructor from const iterator.
Definition circular_buffer.h:504
const_iterator & operator++()
Pre-increment.
Definition circular_buffer.h:559
const_reference operator*() const
Definition circular_buffer.h:535
friend const_iterator operator-(const const_iterator &lhs, int n)
Subtract offset.
Definition circular_buffer.h:648
const_pointer operator->() const
-> operator
Definition circular_buffer.h:543
friend const_iterator operator+(const const_iterator &lhs, int n)
Add offset.
Definition circular_buffer.h:636
const_iterator & operator=(const typename icircular_buffer::iterator &other)
Assignment operator.
Definition circular_buffer.h:513
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:462
iterator & operator+=(int n)
Add offset.
Definition circular_buffer.h:326
friend bool operator==(const iterator &lhs, const iterator &rhs)
Equality operator.
Definition circular_buffer.h:381
iterator & operator--()
Pre-decrement.
Definition circular_buffer.h:296
friend iterator operator-(const iterator &lhs, int n)
Subtract offset.
Definition circular_buffer.h:369
pointer operator->() const
-> operator
Definition circular_buffer.h:244
iterator & operator-=(int n)
Subtract offset.
Definition circular_buffer.h:337
friend iterator operator+(const iterator &lhs, int n)
Add offset.
Definition circular_buffer.h:345
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
reference operator[](size_t index)
[] operator
Definition circular_buffer.h:252
friend bool operator!=(const iterator &lhs, const iterator &rhs)
Inequality operator.
Definition circular_buffer.h:389
iterator & operator++()
Pre-increment.
Definition circular_buffer.h:268
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:1052
void fill(const T &value)
Fills the buffer.
Definition circular_buffer.h:1009
const_reverse_iterator rend() const
Gets a const reverse iterator to the end of the buffer.
Definition circular_buffer.h:829
void pop()
pop
Definition circular_buffer.h:967
reverse_iterator rend()
Gets a reverse iterator to the end of the buffer.
Definition circular_buffer.h:821
const_reverse_iterator rbegin() const
Gets a const reverse iterator to the start of the buffer.
Definition circular_buffer.h:805
void push(TIterator first, const TIterator &last)
Push a buffer from an iterator range.
Definition circular_buffer.h:955
friend difference_type operator-(const iterator &lhs, const iterator &rhs)
Definition circular_buffer.h:1024
const_iterator end() const
Gets a const iterator to the end of the buffer.
Definition circular_buffer.h:781
const_reference back() const
Definition circular_buffer.h:879
iterator end()
Gets an iterator to the end of the buffer.
Definition circular_buffer.h:773
iterator begin()
Gets an iterator to the start of the buffer.
Definition circular_buffer.h:749
const_iterator begin() const
Gets a const iterator to the start of the buffer.
Definition circular_buffer.h:757
const_iterator cbegin() const
Gets a const iterator to the start of the buffer.
Definition circular_buffer.h:765
const_reverse_iterator crend() const
Gets a const reverse iterator to the end of the buffer.
Definition circular_buffer.h:837
reference front()
Definition circular_buffer.h:846
void clear()
Clears the buffer.
Definition circular_buffer.h:989
void repair_buffer(T *pbuffer_)
Fix the internal pointers after a low level memory copy.
Definition circular_buffer.h:1083
reference back()
Definition circular_buffer.h:868
icircular_buffer(pointer pbuffer_, size_type max_length)
Protected constructor.
Definition circular_buffer.h:1042
reverse_iterator rbegin()
Gets a reverse iterator to the start of the buffer.
Definition circular_buffer.h:797
void pop(size_type n)
pop(n)
Definition circular_buffer.h:978
reference operator[](size_t index)
Get a reference to the item.
Definition circular_buffer.h:889
void push(const_reference item)
Definition circular_buffer.h:908
const_iterator cend() const
Gets a const iterator to the end of the buffer.
Definition circular_buffer.h:789
const_reverse_iterator crbegin() const
Gets a const reverse iterator to the start of the buffer.
Definition circular_buffer.h:813
static difference_type distance(const TIterator &other)
Measures the distance from the _begin iterator to the specified iterator.
Definition circular_buffer.h:1064
~icircular_buffer()
Destructor.
Definition circular_buffer.h:1102
const_reference front() const
Definition circular_buffer.h:857
Definition iterator.h:228
#define ETL_ASSERT(b, e)
Definition error_handler.h:356
Definition exception.h:47
enable_if
Definition type_traits_generator.h:1186
is_integral
Definition type_traits_generator.h:996
bitset_ext
Definition absolute.h:38
size_t max_size() const
Returns the maximum number of items in the variant_pool.
Definition variant_pool_generator.h:395
bool operator!=(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition array.h:654
void swap(etl::array< T, SIZE > &lhs, etl::array< T, SIZE > &rhs)
Template deduction guides.
Definition array.h:630
bool operator==(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition array.h:642
Definition type_traits_generator.h:2110
Definition type_traits_generator.h:2096
iterator
Definition iterator.h:399
pair holds two objects of arbitrary type
Definition utility.h:164