/* * © Copyright 2014 – Urheberrechtshinweis * Alle Rechte vorbehalten / All Rights Reserved * * Programmcode ist urheberrechtlich geschuetzt. * Das Urheberrecht liegt, soweit nicht ausdruecklich anders gekennzeichnet, bei Frank Ebner. * Keine Verwendung ohne explizite Genehmigung. * (vgl. § 106 ff UrhG / § 97 UrhG) */ #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 WITH overflow check! */ void addSafe(const Element& element) { Assert::isTrue(available != (int)data.size(), "buffer overflow"); add(element); } /** add a new element WIUTHOUT checking for overflows */ void add(const Element& element) { data[iWrite] = element; ++iWrite; iWrite %= data.size(); ++available; } /** 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; } /** peek into the given element without removing it */ const Element& peek(const int idx) const { const Element& tmp = data[(iRead + idx) % data.size()]; return tmp; } /** peek into the given element without removing it */ const Element& operator [] (const int idx) const { return peek(idx); } /** does the buffer contain the given element? */ bool contains(const Element& e) const { for (int i = 0; i < available; ++i) { if (peek(i) == e) {return true;} } return false; } /** 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