Skip to content

Instantly share code, notes, and snippets.

@amakukha
Created December 27, 2018 10:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save amakukha/2ee8930a2ad4979fdab64d0c666bacce to your computer and use it in GitHub Desktop.
Save amakukha/2ee8930a2ad4979fdab64d0c666bacce to your computer and use it in GitHub Desktop.
Circular buffer in C++
#ifndef _RING_BUFFER_
#define _RING_BUFFER_
// Source: https://embeddedartistry.com/blog/2017/4/6/circular-buffers-in-cc
#include <memory>
#include <mutex>
template <class T>
class RingBuffer {
public:
explicit RingBuffer(size_t size) :
buf_(std::unique_ptr<T[]>(new T[size])),
max_size_(size) {};
void put(T item);
T get();
void reset();
bool empty() const;
bool full() const;
size_t capacity() const;
size_t size() const;
private:
std::mutex mutex_;
std::unique_ptr<T[]> buf_;
size_t head_ = 0;
size_t tail_ = 0;
const size_t max_size_;
bool full_ = 0;
};
template<class T>
void RingBuffer<T>::reset() {
std::lock_guard<std::mutex> lock(mutex_);
head_ = tail_;
full_ = false;
}
template<class T>
bool RingBuffer<T>::empty() const {
//if head and tail are equal, we are empty
return (!full_ && (head_ == tail_));
}
template<class T>
bool RingBuffer<T>::full() const {
//If tail is ahead the head by 1, we are full
return full_;
}
template<class T>
size_t RingBuffer<T>::capacity() const {
return max_size_;
}
template<class T>
size_t RingBuffer<T>::size() const {
size_t size = max_size_;
if(!full_) {
if(head_ >= tail_)
size = head_ - tail_;
else
size = max_size_ + head_ - tail_;
}
return size;
}
template<class T>
void RingBuffer<T>::put(T item) {
std::lock_guard<std::mutex> lock(mutex_);
buf_[head_] = item;
// TODO: stop writing to buffer if full
if(full_)
tail_ = (tail_ + 1) % max_size_;
head_ = (head_ + 1) % max_size_;
full_ = head_ == tail_;
}
template<class T>
T RingBuffer<T>::get() {
std::lock_guard<std::mutex> lock(mutex_);
if(empty()) return T();
//Read data and advance the tail (we now have a free space)
auto val = buf_[tail_];
full_ = false;
tail_ = (tail_ + 1) % max_size_;
return val;
}
#endif // _RING_BUFFER_
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment