Some useful stuff

Dependents:   FtEncoder FtControlSet

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?

UserRevisionLine numberNew 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