Skip to content

Instantly share code, notes, and snippets.

@bl4ckb0ne
Last active August 1, 2019 19:22
Show Gist options
  • Save bl4ckb0ne/62b72e713b80a2b4ad051782eb90d257 to your computer and use it in GitHub Desktop.
Save bl4ckb0ne/62b72e713b80a2b4ad051782eb90d257 to your computer and use it in GitHub Desktop.
Ring buffer
#include <assert.h>
#include <thread>
#include <atomic>
#include <vector>
#include <chrono>
#include <iostream>
#include <optional>
template <class T, size_t n>
class ring_buffer
{
const size_t size = n + 1;
std::array<T, n + 1> buffer;
std::atomic<size_t> read_idx;
std::atomic<size_t> write_idx;
public:
ring_buffer() : read_idx(0), write_idx(0)
{}
ring_buffer(const ring_buffer&) = delete;
ring_buffer(ring_buffer&&) = delete;
~ring_buffer()
{}
inline bool queue(T &&value)
{
std::cout << "rd_idx " << read_idx << " wr_idx " << write_idx << '\n';
if (this->is_full())
{
return false;
}
buffer[write_idx] = std::move(value);
write_idx = (write_idx + 1) % size;
return true;
}
inline std::optional<T> dequeue()
{
std::cout << "rd_idx " << read_idx << " wr_idx " << write_idx << '\n';
if (this->is_empty())
{
return std::nullopt;
}
std::optional<T> opt(std::move(buffer[read_idx]));
read_idx = (read_idx + 1) % size;
return opt;
}
inline bool is_empty()
{
return read_idx == write_idx;
}
inline bool is_full()
{
return read_idx == ((write_idx + 1) % size);
}
inline void clear()
{
read_idx = write_idx = 0;
// flush buffer ?
}
inline size_t count()
{
return abs(write_idx - read_idx);
}
};
int main(int argc, char* argv[])
{
ring_buffer<int, 12> rb;
assert(rb.dequeue() == std::nullopt);
for(int i = 0; i < 12; ++i)
{
int v = i;
std::cout << "queue " << v << '\n';
bool inserted = rb.queue(std::move(v));
assert(inserted);
std::cout << rb.count() << '\n';
assert(rb.count() == static_cast<size_t>(i + 1));
}
assert(rb.is_full());
bool full_insert = rb.queue(13);
assert(full_insert == false);
for(int i = 0; i < 12; ++i)
{
std::optional<int> v = rb.dequeue();
assert(v != std::nullopt);
assert(v.value() == i);
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment