Some useful stuff

Dependents:   FtEncoder FtControlSet

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&) {}
+};
+
+
+
+
+
+
+
+
+
+
+