Skip to content

Instantly share code, notes, and snippets.

@Elnee
Created October 8, 2019 11:24
Show Gist options
  • Save Elnee/cf253e586b7d37126929c54a5c7389c5 to your computer and use it in GitHub Desktop.
Save Elnee/cf253e586b7d37126929c54a5c7389c5 to your computer and use it in GitHub Desktop.
C++ circural buffer
#pragma once
#include <QObject>
#include <memory>
template <class T>
class circular_buffer
{
public:
explicit circular_buffer(size_t size)
: m_buf(std::unique_ptr<T[]>(new T[size]))
, m_max_size(size)
{ }
void put(T item);
T get();
void reset();
bool empty() const;
bool full() const;
bool all_equals() const;
size_t capacity() const;
size_t size() const;
private:
std::unique_ptr<T[]> m_buf;
size_t m_head = 0;
size_t m_tail = 0;
const size_t m_max_size;
bool m_full = false;
};
template <class T>
void circular_buffer<T>::reset()
{
m_head = m_tail;
m_full = false;
}
template <class T>
bool circular_buffer<T>::empty() const
{
return (!m_full && (m_head == m_tail));
}
template <class T>
bool circular_buffer<T>::full() const
{
return m_full;
}
template <class T>
bool circular_buffer<T>::all_equals() const
{
bool result = true;
T first = m_buf[0];
for (int i = 0; i < size(); ++i) {
if (m_buf[i] != first)
result = false;
}
return result;
}
template <class T>
size_t circular_buffer<T>::capacity() const
{
return m_max_size;
}
template <class T>
size_t circular_buffer<T>::size() const
{
size_t size = m_max_size;
if (!m_full) {
if (m_head >= m_tail) {
size = m_head - m_tail;
} else {
size = m_max_size + m_head - m_tail;
}
}
return size;
}
template <class T>
void circular_buffer<T>::put(T item)
{
m_buf[m_head] = item;
if (m_full) {
m_tail = (m_tail + 1) % m_max_size;
}
m_head = (m_head + 1) % m_max_size;
m_full = m_head == m_tail;
}
template <class T>
T circular_buffer<T>::get()
{
if (empty())
return T();
auto val = m_buf[m_tail];
m_full = false;
m_tail = (m_tail + 1) % m_max_size;
return val;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment