31#ifndef ETL_CIRCULAR_BUFFER_INCLUDED
32#define ETL_CIRCULAR_BUFFER_INCLUDED
42#include "static_assert.h"
54 circular_buffer_exception(string_type reason_, string_type file_name_, numeric_type line_number_)
55 :
exception(reason_, file_name_, line_number_)
67 circular_buffer_empty(string_type file_name_, numeric_type line_number_)
76 class circular_buffer_incompatible_type :
public circular_buffer_exception
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_)
89 class circular_buffer_base
114 if (i == buffer_size) ETL_UNLIKELY
131 return buffer_size - 1U;
137 return buffer_size - 1U;
143 circular_buffer_base(
size_type buffer_size_)
144 : buffer_size(buffer_size_)
154 if (
in == buffer_size) ETL_UNLIKELY
164 if (
out == buffer_size) ETL_UNLIKELY
179 template <
typename T>
184 typedef T value_type;
185 typedef T& reference;
186 typedef const T& const_reference;
188 typedef T&& rvalue_reference;
191 typedef const T* const_pointer;
193 typedef typename etl::iterator_traits<pointer>::difference_type difference_type;
202 friend class icircular_buffer;
218 , current(other.current)
228 current = other.current;
238 return picb->pbuffer[current];
246 return &picb->pbuffer[current];
254 return picb->pbuffer[(current + index) % picb->buffer_size];
262 return picb->pbuffer[(current + index) % picb->buffer_size];
273 if (current == picb->buffer_size)
301 current = picb->buffer_size - 1;
328 current +=
size_type(picb->buffer_size + n);
329 current %= picb->buffer_size;
339 return (this->
operator+=(-n));
383 return (lhs.current == rhs.current);
391 return !(lhs == rhs);
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;
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;
405 return lhs_distance < rhs_distance;
427 difference_type get_index()
const
433 const icircular_buffer& container()
const
439 pointer get_buffer()
const
441 return picb->pbuffer;
447 difference_type distance(difference_type firstIndex, difference_type index)
const
449 if (index < firstIndex)
451 return picb->buffer_size + current - firstIndex;
455 return index - firstIndex;
481 friend class icircular_buffer;
497 , current(other.current)
506 , current(other.current)
516 current = other.current;
527 current = other.current;
537 return picb->pbuffer[current];
545 return &(picb->pbuffer[current]);
553 return picb->pbuffer[(current + index) % picb->buffer_size];
564 if (current == picb->buffer_size)
592 current = picb->buffer_size - 1;
619 current +=
size_type(picb->buffer_size + n);
620 current %= picb->buffer_size;
630 return (this->
operator+=(-n));
662 return (lhs.current == rhs.current);
670 return !(lhs == rhs);
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;
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;
684 return lhs_distance < rhs_distance;
706 difference_type get_index()
const
712 const icircular_buffer& container()
const
718 pointer get_buffer()
const
720 return picb->pbuffer;
799 return reverse_iterator(
end());
807 return const_reverse_iterator(
end());
815 return const_reverse_iterator(
end());
823 return reverse_iterator(
begin());
829 const_reverse_iterator
rend()
const
831 return const_reverse_iterator(
begin());
837 const_reverse_iterator
crend()
const
839 return const_reverse_iterator(
begin());
872 return pbuffer[
in == 0U ? buffer_size - 1 :
in - 1U];
883 return pbuffer[
in == 0U ? buffer_size - 1 :
in - 1U];
891 return pbuffer[(
out + index) % buffer_size];
900 return pbuffer[(
out + index) % buffer_size];
908 void push(const_reference item)
910 ::new (&pbuffer[
in]) T(item);
918 this->increment_out();
922 ETL_INCREMENT_DEBUG_COUNT;
932 void push(rvalue_reference item)
934 ::new (&pbuffer[
in]) T(etl::move(item));
946 ETL_INCREMENT_DEBUG_COUNT;
954 template <
typename TIterator>
955 void push(TIterator first,
const TIterator& last)
957 while (first != last)
972 ETL_DECREMENT_DEBUG_COUNT;
991 if ETL_IF_CONSTEXPR(etl::is_trivially_destructible<T>::value)
995 ETL_RESET_DEBUG_COUNT;
1014#ifdef ETL_ICIRCULAR_BUFFER_REPAIR_ENABLE
1018 virtual void repair() = 0;
1043 : circular_buffer_base(max_length + 1U)
1051 template <
typename TIterator1,
typename TIterator2>
1052 static difference_type
distance(
const TIterator1& range_begin,
const TIterator2& range_end)
1054 difference_type distance1 =
distance(range_begin);
1055 difference_type distance2 =
distance(range_end);
1057 return distance2 - distance1;
1063 template <
typename TIterator>
1064 static difference_type
distance(
const TIterator& other)
1066 const difference_type index = other.get_index();
1067 const difference_type reference_index =
static_cast<difference_type
>(other.container().
out);
1068 const size_t buffer_size = other.container().buffer_size;
1070 if (index < reference_index)
1072 return buffer_size + index - reference_index;
1076 return index - reference_index;
1095#if defined(ETL_POLYMORPHIC_CIRCULAR_BUFFER) || defined(ETL_POLYMORPHIC_CONTAINERS)
1112 template <
typename T,
size_t MAX_SIZE_>
1117 ETL_STATIC_ASSERT((MAX_SIZE_ > 0U),
"Zero capacity etl::circular_buffer is not valid");
1133 template <
typename TIterator>
1137 while (first != last)
1144#if ETL_HAS_INITIALIZER_LIST
1151 this->
push(init.begin(), init.end());
1191 while (itr != other.end())
1193 this->
push(etl::move(*itr));
1208 for (
typename etl::icircular_buffer<T>::const_iterator itr = other.begin(); itr != other.end(); ++itr)
1210 this->
push(etl::move(*itr));
1230#ifdef ETL_ICIRCULAR_BUFFER_REPAIR_ENABLE
1231 virtual void repair() ETL_OVERRIDE
1247 template <
typename T,
size_t MAX_SIZE_>
1254 template <
typename T>
1280 template <
typename TIterator>
1284 while (first != last)
1291#if ETL_HAS_INITIALIZER_LIST
1298 this->
push(init.begin(), init.end());
1344 while (itr != other.end())
1346 this->
push(etl::move(*itr));
1361 for (
typename etl::icircular_buffer<T>::iterator itr = other.begin(); itr != other.end(); ++itr)
1363 this->
push(etl::move(*itr));
1376 using ETL_OR_STD::swap;
1378 swap(this->
in, other.in);
1380 swap(this->pbuffer, other.pbuffer);
1381 swap(this->buffer_size, other.buffer_size);
1383#if defined(ETL_DEBUG_COUNT)
1384 this->etl_debug_count.swap(other.etl_debug_count);
1394 using ETL_OR_STD::swap;
1396 swap(this->
in, other.in);
1398 swap(this->pbuffer, other.pbuffer);
1399 swap(this->buffer_size, other.buffer_size);
1401#if defined(ETL_DEBUG_COUNT)
1402 this->etl_debug_count.swap(other.etl_debug_count);
1412 this->pbuffer =
reinterpret_cast<T*
>(buffer);
1420 return this->pbuffer != ETL_NULLPTR;
1434#ifdef ETL_ICIRCULAR_BUFFER_REPAIR_ENABLE
1435 virtual void repair() ETL_OVERRIDE
1446#if ETL_USING_CPP17 && ETL_HAS_INITIALIZER_LIST
1447 template <
typename T,
typename... Ts>
1448 circular_buffer(T, Ts...)
1449 ->circular_buffer<etl::enable_if_t<(etl::is_same_v<T, Ts> && ...), T>, 1U +
sizeof...(Ts)>;
1455 template <
typename T>
1465 template <
typename T>
1475 template <
typename T>
1478 return (lhs.size() == rhs.size()) && etl::equal(lhs.
begin(), lhs.
end(), rhs.
begin());
1484 template <
typename T>
1487 return !(lhs == rhs);
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:1410
circular_buffer_ext(const circular_buffer_ext &other) ETL_DELETE
Copy Constructor (Deleted).
bool is_valid() const
set_buffer
Definition circular_buffer.h:1418
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:1426
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:1437
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
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:1254
bitset_ext
Definition absolute.h:39
ETL_CONSTEXPR14 void swap(etl::typed_storage_ext< T > &lhs, etl::typed_storage_ext< T > &rhs) ETL_NOEXCEPT
Swap two etl::typed_storage_ext.
Definition alignment.h:838
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:1151
bool operator==(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition array.h:1139
iterator
Definition iterator.h:399