Some useful stuff
Dependents: FtEncoder FtControlSet
Diff: Buffer.h
- Revision:
- 1:bf8fc4455615
- Child:
- 2:8882925900db
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Buffer.h Thu Mar 28 00:07:10 2013 +0000 @@ -0,0 +1,155 @@ +#include<cstdint> + + +/// a template for a simple buffer class holding at max N elements of type T +/// Can be used as stack, queue or ring buffer +/// There is heap and a stack based implemenation +template<class T, uint32_t N> +class Buffer +{ +protected: + + static const T outOfBoundsAccessDefaultReturn=T(); + /// the buffer for the stored elements, initialized in the concrete specializations + T* elements; + /// points to the oldest element (if not empty; equal to the latest if only one element stored) + uint32_t startCsr; + /// points one element behind the latest + uint32_t endCsr; + /// number of elements currently stored in the Buffer + uint32_t nElements; + + /// private helper that increments revolving cursors + inline void incrCsr(uint32_t& csr) { + if(++csr>=N) csr=0; + } + /// private helper that decrements revolving cursors + inline void decrCsr(uint32_t& csr) { + if(--csr>=N) csr=N-1; // will get quite large on underlow since csr is unsigned + } + + /// guess what: a constructor! But this class is kind of abtract, + /// so it has been declared protected to remove it from the public interface + Buffer():elements(0),startCsr(0),endCsr(0),nElements(0) {}; + +public: + + /// virtual destructor + virtual ~Buffer() {}; + + /// if used as queue or stack, use this function to insert new element to the buffer + /// returns true on success and false if full + inline bool push(const T& element) { + bool ok = !isFull(); + if(ok) { + elements[endCsr]=element; + incrCsr(endCsr); + ++nElements; + } + return ok; + } + + /// if used as ring buffer, use this function to insert new elements to the buffer + inline void pushCircular(const T& element) { + elements[endPos]=element; + incrCsr(endCsr); + if(isFull())incrCsr(startCsr); + ++nElements; + } + + /// pop the latest element from buffer. Returns a default instance of type T if empty + inline const T& popLatest() { + if(isEmpty())return outOfBoundsAccessDefaultReturn; + decrCsr(endCsr); + --nElements; + return elements[endCsr]; + } + + /// pop the oldest element from buffer. Returns a default instance of type T if empty + inline const T& popOldest() { + if(isEmpty())return outOfBoundsAccessDefaultReturn; + T& oldest = elements[startCsr]; + incrCsr(startCsr); + --nElements; + return oldest; + } + + /// returns true if buffer is empty + inline bool isEmpty() const { + return nElements==0; + } + + /// returns true if buffer is full + inline bool isFull() const { + return nElements==N; + } + + /// retuns number of currently stored elements + inline uint32_t size() const { + return nElements; + } + + /// returns maximum number of storable elements + inline uint32_t maxSize() const { + return N; + } + + /// read only access operator: Element with index 0 is the oldest and the one with index size()-1 the latest + inline const T& operator[](uint32_t idx)const { + return operator[](idx); + } + + /// read/write access operator: Element with index 0 is the oldest and the one with index size()-1 the latest + inline T& operator[](uint32_t idx) { + if(idx>=nElements())return outOfBoundsAccessDefaultReturn; + idx+=startCsr; + if(idx>=N)idx-=N; + return elements[idx]; + } +}; + +/// concrete Buffer class template that implements the elements storage as simple C-array +/// this baby can be copied using default implicit operator and copy ctors +template<class T, uint32_t N> +class BufferOnStack : public Buffer<T,N> +{ + T storage[N]; +public: + /// create a Buffe class with storage on stack, static or global. + BufferOnStack():Buffer<T,N>() { + Buffer<T,N>::elements=storage; + } +}; + +/// concrete Buffer class template that allocates the elements storage on the heap +/// This cannot be copied unless you implement the needed ctor and assignment op +template<class T, uint32_t N> +class BufferOnHeap : public Buffer<T,N> +{ +public: + /// constructor + BufferOnHeap():Buffer<T,N>() { + Buffer<T,N>::elements=new T[N]; + } + /// destructor + virtual ~BufferOnHeap() { + delete[] Buffer<T,N>::elements; + } + +protected: + /// no copy ctor + BufferOnHeap(BufferOnHeap&) {}; + ///no assignment + BufferOnHeap& operator=(BufferOnHeap&) {} +}; + + + + + + + + + + +