Some useful stuff
Dependents: FtEncoder FtControlSet
Buffer.h@1:bf8fc4455615, 2013-03-28 (annotated)
- Committer:
- humlet
- Date:
- Thu Mar 28 00:07:10 2013 +0000
- Revision:
- 1:bf8fc4455615
- Child:
- 2:8882925900db
Added new Buffer class (not tested yet)
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
humlet | 1:bf8fc4455615 | 1 | #include<cstdint> |
humlet | 1:bf8fc4455615 | 2 | |
humlet | 1:bf8fc4455615 | 3 | |
humlet | 1:bf8fc4455615 | 4 | /// a template for a simple buffer class holding at max N elements of type T |
humlet | 1:bf8fc4455615 | 5 | /// Can be used as stack, queue or ring buffer |
humlet | 1:bf8fc4455615 | 6 | /// There is heap and a stack based implemenation |
humlet | 1:bf8fc4455615 | 7 | template<class T, uint32_t N> |
humlet | 1:bf8fc4455615 | 8 | class Buffer |
humlet | 1:bf8fc4455615 | 9 | { |
humlet | 1:bf8fc4455615 | 10 | protected: |
humlet | 1:bf8fc4455615 | 11 | |
humlet | 1:bf8fc4455615 | 12 | static const T outOfBoundsAccessDefaultReturn=T(); |
humlet | 1:bf8fc4455615 | 13 | /// the buffer for the stored elements, initialized in the concrete specializations |
humlet | 1:bf8fc4455615 | 14 | T* elements; |
humlet | 1:bf8fc4455615 | 15 | /// points to the oldest element (if not empty; equal to the latest if only one element stored) |
humlet | 1:bf8fc4455615 | 16 | uint32_t startCsr; |
humlet | 1:bf8fc4455615 | 17 | /// points one element behind the latest |
humlet | 1:bf8fc4455615 | 18 | uint32_t endCsr; |
humlet | 1:bf8fc4455615 | 19 | /// number of elements currently stored in the Buffer |
humlet | 1:bf8fc4455615 | 20 | uint32_t nElements; |
humlet | 1:bf8fc4455615 | 21 | |
humlet | 1:bf8fc4455615 | 22 | /// private helper that increments revolving cursors |
humlet | 1:bf8fc4455615 | 23 | inline void incrCsr(uint32_t& csr) { |
humlet | 1:bf8fc4455615 | 24 | if(++csr>=N) csr=0; |
humlet | 1:bf8fc4455615 | 25 | } |
humlet | 1:bf8fc4455615 | 26 | /// private helper that decrements revolving cursors |
humlet | 1:bf8fc4455615 | 27 | inline void decrCsr(uint32_t& csr) { |
humlet | 1:bf8fc4455615 | 28 | if(--csr>=N) csr=N-1; // will get quite large on underlow since csr is unsigned |
humlet | 1:bf8fc4455615 | 29 | } |
humlet | 1:bf8fc4455615 | 30 | |
humlet | 1:bf8fc4455615 | 31 | /// guess what: a constructor! But this class is kind of abtract, |
humlet | 1:bf8fc4455615 | 32 | /// so it has been declared protected to remove it from the public interface |
humlet | 1:bf8fc4455615 | 33 | Buffer():elements(0),startCsr(0),endCsr(0),nElements(0) {}; |
humlet | 1:bf8fc4455615 | 34 | |
humlet | 1:bf8fc4455615 | 35 | public: |
humlet | 1:bf8fc4455615 | 36 | |
humlet | 1:bf8fc4455615 | 37 | /// virtual destructor |
humlet | 1:bf8fc4455615 | 38 | virtual ~Buffer() {}; |
humlet | 1:bf8fc4455615 | 39 | |
humlet | 1:bf8fc4455615 | 40 | /// if used as queue or stack, use this function to insert new element to the buffer |
humlet | 1:bf8fc4455615 | 41 | /// returns true on success and false if full |
humlet | 1:bf8fc4455615 | 42 | inline bool push(const T& element) { |
humlet | 1:bf8fc4455615 | 43 | bool ok = !isFull(); |
humlet | 1:bf8fc4455615 | 44 | if(ok) { |
humlet | 1:bf8fc4455615 | 45 | elements[endCsr]=element; |
humlet | 1:bf8fc4455615 | 46 | incrCsr(endCsr); |
humlet | 1:bf8fc4455615 | 47 | ++nElements; |
humlet | 1:bf8fc4455615 | 48 | } |
humlet | 1:bf8fc4455615 | 49 | return ok; |
humlet | 1:bf8fc4455615 | 50 | } |
humlet | 1:bf8fc4455615 | 51 | |
humlet | 1:bf8fc4455615 | 52 | /// if used as ring buffer, use this function to insert new elements to the buffer |
humlet | 1:bf8fc4455615 | 53 | inline void pushCircular(const T& element) { |
humlet | 1:bf8fc4455615 | 54 | elements[endPos]=element; |
humlet | 1:bf8fc4455615 | 55 | incrCsr(endCsr); |
humlet | 1:bf8fc4455615 | 56 | if(isFull())incrCsr(startCsr); |
humlet | 1:bf8fc4455615 | 57 | ++nElements; |
humlet | 1:bf8fc4455615 | 58 | } |
humlet | 1:bf8fc4455615 | 59 | |
humlet | 1:bf8fc4455615 | 60 | /// pop the latest element from buffer. Returns a default instance of type T if empty |
humlet | 1:bf8fc4455615 | 61 | inline const T& popLatest() { |
humlet | 1:bf8fc4455615 | 62 | if(isEmpty())return outOfBoundsAccessDefaultReturn; |
humlet | 1:bf8fc4455615 | 63 | decrCsr(endCsr); |
humlet | 1:bf8fc4455615 | 64 | --nElements; |
humlet | 1:bf8fc4455615 | 65 | return elements[endCsr]; |
humlet | 1:bf8fc4455615 | 66 | } |
humlet | 1:bf8fc4455615 | 67 | |
humlet | 1:bf8fc4455615 | 68 | /// pop the oldest element from buffer. Returns a default instance of type T if empty |
humlet | 1:bf8fc4455615 | 69 | inline const T& popOldest() { |
humlet | 1:bf8fc4455615 | 70 | if(isEmpty())return outOfBoundsAccessDefaultReturn; |
humlet | 1:bf8fc4455615 | 71 | T& oldest = elements[startCsr]; |
humlet | 1:bf8fc4455615 | 72 | incrCsr(startCsr); |
humlet | 1:bf8fc4455615 | 73 | --nElements; |
humlet | 1:bf8fc4455615 | 74 | return oldest; |
humlet | 1:bf8fc4455615 | 75 | } |
humlet | 1:bf8fc4455615 | 76 | |
humlet | 1:bf8fc4455615 | 77 | /// returns true if buffer is empty |
humlet | 1:bf8fc4455615 | 78 | inline bool isEmpty() const { |
humlet | 1:bf8fc4455615 | 79 | return nElements==0; |
humlet | 1:bf8fc4455615 | 80 | } |
humlet | 1:bf8fc4455615 | 81 | |
humlet | 1:bf8fc4455615 | 82 | /// returns true if buffer is full |
humlet | 1:bf8fc4455615 | 83 | inline bool isFull() const { |
humlet | 1:bf8fc4455615 | 84 | return nElements==N; |
humlet | 1:bf8fc4455615 | 85 | } |
humlet | 1:bf8fc4455615 | 86 | |
humlet | 1:bf8fc4455615 | 87 | /// retuns number of currently stored elements |
humlet | 1:bf8fc4455615 | 88 | inline uint32_t size() const { |
humlet | 1:bf8fc4455615 | 89 | return nElements; |
humlet | 1:bf8fc4455615 | 90 | } |
humlet | 1:bf8fc4455615 | 91 | |
humlet | 1:bf8fc4455615 | 92 | /// returns maximum number of storable elements |
humlet | 1:bf8fc4455615 | 93 | inline uint32_t maxSize() const { |
humlet | 1:bf8fc4455615 | 94 | return N; |
humlet | 1:bf8fc4455615 | 95 | } |
humlet | 1:bf8fc4455615 | 96 | |
humlet | 1:bf8fc4455615 | 97 | /// read only access operator: Element with index 0 is the oldest and the one with index size()-1 the latest |
humlet | 1:bf8fc4455615 | 98 | inline const T& operator[](uint32_t idx)const { |
humlet | 1:bf8fc4455615 | 99 | return operator[](idx); |
humlet | 1:bf8fc4455615 | 100 | } |
humlet | 1:bf8fc4455615 | 101 | |
humlet | 1:bf8fc4455615 | 102 | /// read/write access operator: Element with index 0 is the oldest and the one with index size()-1 the latest |
humlet | 1:bf8fc4455615 | 103 | inline T& operator[](uint32_t idx) { |
humlet | 1:bf8fc4455615 | 104 | if(idx>=nElements())return outOfBoundsAccessDefaultReturn; |
humlet | 1:bf8fc4455615 | 105 | idx+=startCsr; |
humlet | 1:bf8fc4455615 | 106 | if(idx>=N)idx-=N; |
humlet | 1:bf8fc4455615 | 107 | return elements[idx]; |
humlet | 1:bf8fc4455615 | 108 | } |
humlet | 1:bf8fc4455615 | 109 | }; |
humlet | 1:bf8fc4455615 | 110 | |
humlet | 1:bf8fc4455615 | 111 | /// concrete Buffer class template that implements the elements storage as simple C-array |
humlet | 1:bf8fc4455615 | 112 | /// this baby can be copied using default implicit operator and copy ctors |
humlet | 1:bf8fc4455615 | 113 | template<class T, uint32_t N> |
humlet | 1:bf8fc4455615 | 114 | class BufferOnStack : public Buffer<T,N> |
humlet | 1:bf8fc4455615 | 115 | { |
humlet | 1:bf8fc4455615 | 116 | T storage[N]; |
humlet | 1:bf8fc4455615 | 117 | public: |
humlet | 1:bf8fc4455615 | 118 | /// create a Buffe class with storage on stack, static or global. |
humlet | 1:bf8fc4455615 | 119 | BufferOnStack():Buffer<T,N>() { |
humlet | 1:bf8fc4455615 | 120 | Buffer<T,N>::elements=storage; |
humlet | 1:bf8fc4455615 | 121 | } |
humlet | 1:bf8fc4455615 | 122 | }; |
humlet | 1:bf8fc4455615 | 123 | |
humlet | 1:bf8fc4455615 | 124 | /// concrete Buffer class template that allocates the elements storage on the heap |
humlet | 1:bf8fc4455615 | 125 | /// This cannot be copied unless you implement the needed ctor and assignment op |
humlet | 1:bf8fc4455615 | 126 | template<class T, uint32_t N> |
humlet | 1:bf8fc4455615 | 127 | class BufferOnHeap : public Buffer<T,N> |
humlet | 1:bf8fc4455615 | 128 | { |
humlet | 1:bf8fc4455615 | 129 | public: |
humlet | 1:bf8fc4455615 | 130 | /// constructor |
humlet | 1:bf8fc4455615 | 131 | BufferOnHeap():Buffer<T,N>() { |
humlet | 1:bf8fc4455615 | 132 | Buffer<T,N>::elements=new T[N]; |
humlet | 1:bf8fc4455615 | 133 | } |
humlet | 1:bf8fc4455615 | 134 | /// destructor |
humlet | 1:bf8fc4455615 | 135 | virtual ~BufferOnHeap() { |
humlet | 1:bf8fc4455615 | 136 | delete[] Buffer<T,N>::elements; |
humlet | 1:bf8fc4455615 | 137 | } |
humlet | 1:bf8fc4455615 | 138 | |
humlet | 1:bf8fc4455615 | 139 | protected: |
humlet | 1:bf8fc4455615 | 140 | /// no copy ctor |
humlet | 1:bf8fc4455615 | 141 | BufferOnHeap(BufferOnHeap&) {}; |
humlet | 1:bf8fc4455615 | 142 | ///no assignment |
humlet | 1:bf8fc4455615 | 143 | BufferOnHeap& operator=(BufferOnHeap&) {} |
humlet | 1:bf8fc4455615 | 144 | }; |
humlet | 1:bf8fc4455615 | 145 | |
humlet | 1:bf8fc4455615 | 146 | |
humlet | 1:bf8fc4455615 | 147 | |
humlet | 1:bf8fc4455615 | 148 | |
humlet | 1:bf8fc4455615 | 149 | |
humlet | 1:bf8fc4455615 | 150 | |
humlet | 1:bf8fc4455615 | 151 | |
humlet | 1:bf8fc4455615 | 152 | |
humlet | 1:bf8fc4455615 | 153 | |
humlet | 1:bf8fc4455615 | 154 | |
humlet | 1:bf8fc4455615 | 155 |