118 lines
2.6 KiB
C++
118 lines
2.6 KiB
C++
/*
|
||
* © 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 <vector>
|
||
#include "../Assertions.h"
|
||
|
||
template <typename Element> class RingBuffer {
|
||
|
||
private:
|
||
|
||
std::vector<Element> 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<Element>& data;
|
||
|
||
/** ctor */
|
||
Iterator(const int idx, const int available, const std::vector<Element>& 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
|