libDaisy
Hardware Library for Daisy
Loading...
Searching...
No Matches
FIFO.h
Go to the documentation of this file.
1#pragma once
2
3#include <stdint.h>
4#include <stddef.h>
5#include <initializer_list>
6
7namespace daisy
8{
10template <typename T>
12{
13 protected:
15 : buffer_(buffer), bufferSize_(bufferSize), bufferIn_(0), bufferOut_(0)
16 {
17 }
18
19 FIFOBase(T* buffer, size_t bufferSize, std::initializer_list<T> valuesToAdd)
20 : buffer_(buffer), bufferSize_(bufferSize), bufferIn_(0), bufferOut_(0)
21 {
23 }
24
25 public:
28 {
29 bufferIn_ = bufferOut_ = 0;
30 if(!other.IsEmpty())
31 {
32 int readPtr = other.bufferOut_;
33 while((readPtr != other.bufferIn_) && (bufferIn_ < bufferSize_))
34 {
35 buffer_[bufferIn_++] = other.buffer_[readPtr++];
36 if(readPtr >= other.bufferSize_)
37 readPtr -= other.bufferSize_;
38 }
39 }
40 return *this;
41 }
43
45 void Clear() { bufferIn_ = bufferOut_ = 0; }
46
49 bool PushBack(const T& elementToAdd)
50 {
51 if(!IsFull())
52 {
53 buffer_[bufferIn_++] = elementToAdd;
54 if(bufferIn_ >= bufferSize_)
55 bufferIn_ -= bufferSize_;
56 return true;
57 }
58 return false;
59 }
60
62 int PushBack(std::initializer_list<T> valuesToAdd)
63 {
64 int numAdded = 0;
65 for(const auto& v : valuesToAdd)
66 {
67 if(IsFull())
68 return numAdded;
69
70 PushBack(v);
71 numAdded++;
72 }
73 return numAdded;
74 }
75
77 T& Back()
78 {
79 if(IsEmpty())
80 // invalid, but better not pass a temporary T() object as a reference...
81 return buffer_[0];
82 int idx = bufferIn_ - 1;
83 if(idx < 0)
84 idx += bufferSize_;
85 return buffer_[idx];
86 }
87
89 const T& Back() const
90 {
91 if(IsEmpty())
92 // invalid, but better not pass a temporary T() object as a reference...
93 return buffer_[0];
94 int idx = bufferIn_ - 1;
95 if(idx < 0)
96 idx += bufferSize_;
97 return buffer_[idx];
98 }
99
102 {
103 if(IsEmpty())
104 return T();
105 else
106 {
107 const auto result = buffer_[bufferOut_];
108 bufferOut_++;
109 if(bufferOut_ >= bufferSize_)
110 bufferOut_ -= bufferSize_;
111 return result;
112 }
113 }
114
116 T& Front()
117 {
118 if(IsEmpty())
119 // invalid, but better not pass a temporary T() object as a reference...
120 return buffer_[0];
121 return buffer_[bufferOut_];
122 }
123
125 const T& Front() const
126 {
127 if(IsEmpty())
128 // invalid, but better not pass a temporary T() object as a reference...
129 return buffer_[0];
130 return buffer_[bufferOut_];
131 }
132
134 bool Contains(const T& element)
135 {
136 auto idx = bufferOut_;
137 while(idx != bufferIn_)
138 {
139 if(buffer_[idx] == element)
140 return true;
141 idx++;
142 if(idx >= bufferSize_)
143 idx -= bufferSize_;
144 }
145 return false;
146 }
147
149 size_t CountEqualTo(const T& element)
150 {
151 size_t result = 0;
152 size_t idx = bufferOut_;
153 while(idx != bufferIn_)
154 {
155 if(buffer_[idx] == element)
156 result++;
157 idx++;
158 if(idx >= bufferSize_)
159 idx -= bufferSize_;
160 }
161 return result;
162 }
163
165 bool IsEmpty() const { return bufferIn_ == bufferOut_; }
166
168 bool IsFull() const { return GetNumElements() == bufferSize_ - 1; }
169
171 size_t GetNumElements() const
172 {
173 int32_t numElements = bufferIn_ - bufferOut_;
174 if(numElements < 0)
175 numElements += bufferSize_;
176 return size_t(numElements);
177 }
178
180 bool Insert(size_t idx, const T& element)
181 {
182 if(idx > GetNumElements())
183 return false;
184 if(IsFull())
185 return false;
186 if(idx == GetNumElements())
187 {
189 return true;
190 }
191 // copy last element
192 PushBack(Back());
193 // move remaining elements: n => n+1
194 for(int i = GetNumElements() - 2; i > int(idx); i--)
195 (*this)[i] = (*this)[i - 1];
196 // insert element
197 (*this)[idx] = element;
198 return true;
199 }
200
203 bool Remove(size_t idx)
204 {
205 if(idx >= GetNumElements())
206 return false;
207
208 size_t index = bufferOut_ + idx;
209 if(index >= bufferSize_)
210 index -= bufferSize_;
211 size_t nextIndex = index + 1;
212 if(nextIndex >= bufferSize_)
213 nextIndex -= bufferSize_;
214
215 while(nextIndex != bufferIn_)
216 {
217 buffer_[index] = buffer_[nextIndex];
218 index++;
219 nextIndex++;
220 if(index >= bufferSize_)
221 index -= bufferSize_;
222 if(nextIndex >= bufferSize_)
223 nextIndex -= bufferSize_;
224 }
225
226 int32_t nextBufferIn = int32_t(bufferIn_) - 1;
227 if(nextBufferIn < 0)
228 nextBufferIn += bufferSize_;
229 bufferIn_ = size_t(nextBufferIn);
230
231 return true;
232 }
233
237 size_t RemoveAllEqualTo(const T& element)
238 {
239 size_t numRemoved = 0;
240 int idx = GetNumElements() - 1;
241 while(idx >= 0)
242 {
243 if((*this)[idx] == element)
244 {
245 numRemoved++;
246 Remove(idx);
247 // was that the last element?
248 if(idx == int(GetNumElements()) - 1)
249 idx--;
250 }
251 else
252 idx--;
253 }
254 return numRemoved;
255 }
256
258 T& operator[](size_t idx)
259 {
260 if(idx >= GetNumElements())
261 // invalid, but better not pass a temporary T() object as a reference...
262 return buffer_[0];
263
264 size_t index = bufferOut_ + idx;
265 if(index >= bufferSize_)
266 index -= bufferSize_;
267 return buffer_[index];
268 }
269
271 const T& operator[](size_t idx) const
272 {
273 if(idx >= GetNumElements())
274 // invalid, but better not pass a temporary T() object as a reference...
275 return buffer_[0];
276
277 size_t index = bufferOut_ + idx;
278 if(index >= bufferSize_)
279 index -= bufferSize_;
280 return buffer_[index];
281 }
282
284 size_t GetCapacity() const { return bufferSize_ - 1; }
285
286 private:
287 FIFOBase(const FIFOBase<T>&) {} // non copyable
288
289 private:
290 T* buffer_;
291 const size_t bufferSize_;
292 size_t bufferIn_;
293 size_t bufferOut_;
294};
295
297template <typename T, size_t capacity>
298class FIFO : public FIFOBase<T>
299{
300 public:
302 FIFO() : FIFOBase<T>(buffer_, capacity + 1) {}
303
305 explicit FIFO(std::initializer_list<T> valuesToAdd)
306 : FIFOBase<T>(buffer_, capacity, valuesToAdd)
307 {
308 }
309
311 template <size_t otherCapacity>
313 {
314 *this = other;
315 }
316
318 template <size_t otherCapacity>
324
325 private:
326 T buffer_[capacity + 1];
327};
328
329} // namespace daisy
Definition FIFO.h:12
T & Front()
Definition FIFO.h:116
bool PushBack(const T &elementToAdd)
Definition FIFO.h:49
T PopFront()
Definition FIFO.h:101
bool Contains(const T &element)
Definition FIFO.h:134
FIFOBase(T *buffer, size_t bufferSize)
Definition FIFO.h:14
const T & Front() const
Definition FIFO.h:125
const T & operator[](size_t idx) const
Definition FIFO.h:271
size_t GetNumElements() const
Definition FIFO.h:171
void Clear()
Definition FIFO.h:45
bool Insert(size_t idx, const T &element)
Definition FIFO.h:180
T & Back()
Definition FIFO.h:77
bool Remove(size_t idx)
Definition FIFO.h:203
~FIFOBase()
Definition FIFO.h:42
const T & Back() const
Definition FIFO.h:89
FIFOBase< T > & operator=(const FIFOBase< T > &other)
Definition FIFO.h:27
size_t RemoveAllEqualTo(const T &element)
Definition FIFO.h:237
FIFOBase(T *buffer, size_t bufferSize, std::initializer_list< T > valuesToAdd)
Definition FIFO.h:19
int PushBack(std::initializer_list< T > valuesToAdd)
Definition FIFO.h:62
bool IsFull() const
Definition FIFO.h:168
size_t CountEqualTo(const T &element)
Definition FIFO.h:149
T & operator[](size_t idx)
Definition FIFO.h:258
size_t GetCapacity() const
Definition FIFO.h:284
bool IsEmpty() const
Definition FIFO.h:165
Definition FIFO.h:299
FIFO(std::initializer_list< T > valuesToAdd)
Definition FIFO.h:305
FIFO< T, capacity > & operator=(const FIFO< T, otherCapacity > &other)
Definition FIFO.h:319
FIFO(const FIFO< T, otherCapacity > &other)
Definition FIFO.h:312
FIFO()
Definition FIFO.h:302
Definition leddriver.h:33
Hardware defines and helpers for daisy field platform.
Definition index.h:2