#ifndef RINGBUFFER_H #define RINGBUFFER_H #include #include "../Assertions.h" template class RingBuffer { private: std::vector data; int iWrite; int iRead; int available; public: /** ctor with the size of the buffer */ RingBuffer(const int size) : data(size), iWrite(0), iRead(0), available(0) { ; } /** add a new element */ void add(const Element& element) { Assert::isTrue(available != (int)data.size(), "buffer overflow"); data[iWrite] = element; ++iWrite; iWrite %= data.size(); ++available; //if (available > (int)data.size()) {available = data.size();} } /** get the next element */ const Element& get() { Assert::isNot0(available, "buffer is empty"); const Element& tmp = data[iRead]; ++iRead; iRead %= data.size(); --available; if (available < 0) {available = 0;} return tmp; } /** reset the ringbuffer */ void reset() { iWrite = 0; iRead = 0; available = 0; } /** is the buffer empty? */ bool empty() const { return available == 0; } /** get the number of available entries */ int size() const { return available; } struct Iterator { int idx; int available; const std::vector& data; /** ctor */ Iterator(const int idx, const int available, const std::vector& data) : idx(idx), available(available), data(data) {;} bool operator != (const Iterator& other) {return other.available != available;} void operator ++ () {idx = (idx+1) % data.size(); --available;} const Element& operator * () const {return data[idx];} }; Iterator begin() const {return Iterator(iRead, available, data);} Iterator end() const {return Iterator(iWrite, 0, data);} }; #endif // RINGBUFFER_H