27#ifndef sigproc_circularBuffer
28#define sigproc_circularBuffer
77template <
typename _derivedT,
typename _storedT,
typename _indexT>
86 static_assert(std::is_signed_v<_indexT> ==
true,
"circularBuffer indexT must be signed");
189 return *
static_cast<derivedT *
>( this );
194 return *
static_cast<const derivedT *
>( this );
198template <
class derivedT,
typename storedT,
typename indexT>
203template <
class derivedT,
typename storedT,
typename indexT>
206 maxEntries( maxEnt );
209template <
class derivedT,
typename storedT,
typename indexT>
216 m_maxEntries = maxEnt;
217 m_buffer.reserve( m_maxEntries );
219 derived().setMaxEntries( maxEnt );
224template <
class derivedT,
typename storedT,
typename indexT>
230template <
class derivedT,
typename storedT,
typename indexT>
233 return m_buffer.size();
236template <
class derivedT,
typename storedT,
typename indexT>
239 if( m_buffer.size() < m_maxEntries )
241 m_buffer.push_back( newEnt );
242 m_latest = m_buffer.size() - 1;
247 m_buffer[m_nextEntry] = newEnt;
248 m_latest = m_nextEntry;
250 if( m_nextEntry > m_buffer.size() - 1 )
259template <
class derivedT,
typename storedT,
typename indexT>
262 if( m_buffer.size() < m_maxEntries )
264 m_buffer.emplace_back();
265 m_latest = m_buffer.size() - 1;
270 m_latest = m_nextEntry;
272 if( m_nextEntry > m_buffer.size() - 1 )
281template <
class derivedT,
typename storedT,
typename indexT>
287template <
class derivedT,
typename storedT,
typename indexT>
293template <
class derivedT,
typename storedT,
typename indexT>
299template <
class derivedT,
typename storedT,
typename indexT>
302 return derived().
at( m_nextEntry, idx );
305template <
class derivedT,
typename storedT,
typename indexT>
308 return derived().at( m_nextEntry, idx );
311template <
class derivedT,
typename storedT,
typename indexT>
314 return derived().at( refEntry, idx );
317template <
class derivedT,
typename storedT,
typename indexT>
320 return derived().at( refEntry, idx );
327template <
typename _storedT,
typename _indexT>
365 indexT _idx = refEntry + idx;
370 else if( _idx > this->
m_buffer.size()-1 )
391 indexT _idx = refEntry + idx;
396 else if( _idx > this->
m_buffer.size()-1 )
411template <
typename _storedT,
typename _indexT>
470template <
typename _storedT,
typename _indexT>
CRTP base class for all circular buffers, providing the underlying memory management and accessors.
storedT & at(indexT refEntry, indexT idx)
Get the entry at a given index relative a fixed reference entry.
storedT & operator[](indexT idx)
Get the entry at a given index.
circularBufferBase(indexT maxEnt)
Sizing constructor.
indexT maxEntries()
Get the maximum size of the buffer.
circularBufferBase()
Default c'tor.
std::vector< storedT > m_buffer
The circular buffer storage.
void maxEntries(indexT maxEnt)
Set the maximum size of the buffer.
indexT size() const
Get the number of entries.
const storedT & at(indexT refEntry, indexT idx) const
Get the entry at a given index relative a fixed start entry, const version.
indexT earliest()
Returns the index of the earliest entry.
indexT latest()
Returns the index of the latest entry.
const storedT & operator[](indexT idx) const
indexT m_maxEntries
The maximum number of entries to allow in the buffer before wrapping.
_derivedT derivedT
The child class.
_storedT storedT
The type stored in the circular buffer.
_indexT indexT
The index type, also used for sizes.
void nextEntry()
Move to the next entry in the circular buffer.
indexT m_latest
Index into m_buff of the latest entry. This is the newest entry in the buffer.
indexT m_nextEntry
Index into m_buffer of the next entry. This is the oldest entry in the buffer.
void nextEntry(const storedT &newEnt)
Add the next entry to the circular buffer.
Circular buffer which wraps with an if statement (branching) [faster than mod, less memory than index...
_storedT storedT
The maximum number of entries to allow in the buffer before wrapping.
void setMaxEntries(indexT maxEnt)
Interface implementation for maxEntries.
const storedT & at(indexT refEntry, indexT idx) const
Interface implementation for entry access, const version.
circularBufferBranch()
Default c'tor.
storedT & at(indexT refEntry, indexT idx)
Interface implementation for entry access.
circularBufferBranch(indexT maxEnt)
Sizing constructor.
_indexT indexT
The index type, also used for sizes.
Circular buffer which wraps with a pre-populated indices array [generally fastest].
std::vector< size_t > m_indices
Vector of indices for fast indexing into parent's m_buffer.
circularBufferIndex()
Default c'tor.
const storedT & at(indexT refEntry, indexT idx) const
Interface implementation for entry access, const version.
_indexT indexT
The index type, also used for sizes.
circularBufferIndex(indexT maxEnt)
Sizing constructor.
_storedT storedT
The maximum number of entries to allow in the buffer before wrapping.
storedT & at(indexT refEntry, indexT idx)
Interface implementation for entry access.
void setMaxEntries(indexT maxEnt)
Interface implementation for maxEntries.
Circular buffer which wraps with the mod opoerator [very slow].
_storedT storedT
The maximum number of entries to allow in the buffer before wrapping.
_indexT indexT
The index type, also used for sizes.
const storedT & at(indexT refEntry, indexT idx) const
Interface implementation for entry access, const version.
circularBufferMod()
Default c'tor.
circularBufferMod(indexT maxEnt)
Sizing constructor.
storedT & at(indexT refEntry, indexT idx)
Interface implementation for entry access.
void setMaxEntries(indexT maxEnt)
Interface implementation for maxEntries.