Skip to content

Instantly share code, notes, and snippets.

@nariakiiwatani
Created September 9, 2014 11:16
Show Gist options
  • Save nariakiiwatani/c6b57a78334d400d7a6f to your computer and use it in GitHub Desktop.
Save nariakiiwatani/c6b57a78334d400d7a6f to your computer and use it in GitHub Desktop.
RingBuffer
#pragma once
template <bool B, size_t T, size_t F>
struct binarywrap_t { static const size_t size = T; };
template <size_t T, size_t F>
struct binarywrap_t<false, T, F> { static const size_t size = F; };
template <size_t n, size_t m = 1>
struct binarywrap {
static const size_t size = binarywrap_t<(m < n), binarywrap<n, (m << 1)>::size, m>::size;
};
template <size_t n>
struct binarywrap<n, 0> { static const size_t size = 1; };
template<typename T, size_t _size>
class RingBuffer
{
public:
RingBuffer():index_(-1){}
void add(const T &t) {
index_ = _next(1);
buffer_[index_] = t;
}
void next(size_t interval=1) {
index_ = _next(interval);
}
T& get(size_t interval) {
return buffer_[_prev(interval)];
}
size_t size() { return SIZE; }
private:
static const size_t SIZE = binarywrap<_size>::size;
T buffer_[SIZE];
size_t index_;
private:
size_t _next(size_t interval) {
return (index_+interval)&(SIZE-1);
}
size_t _prev(size_t interval) {
interval &= SIZE-1;
return (index_-interval+SIZE)&(SIZE-1);
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment