Jamba C++ API 7.5.0
Loading...
Searching...
No Matches
CircularBuffer.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2018-2019 pongasoft
3 *
4 * Licensed under the Apache License, Version 2.0 or the MIT license,
5 * at your option. You may not use this file except in compliance with
6 * one of these licenses. You may obtain copies of the licenses at:
7 *
8 * https://www.apache.org/licenses/LICENSE-2.0
9 * https://opensource.org/licenses/MIT
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14 * License for the specific language governing permissions and limitations under
15 * the License.
16 *
17 * @author Yan Pujante
18 */
19#ifndef __PONGASOFT_UTILS_COLLECTION_CIRCULAR_BUFFER_H__
20#define __PONGASOFT_UTILS_COLLECTION_CIRCULAR_BUFFER_H__
21
22#include <cassert>
23#include <memory>
24
25namespace pongasoft {
26namespace Utils {
27namespace Collection {
28
29template<typename T>
31{
32public:
33 explicit CircularBuffer(int iSize) : fSize(iSize), fStart(0)
34 {
35 assert(fSize > 0);
36
37 fBuf = new T[iSize];
38 };
39
40 CircularBuffer(CircularBuffer const& iOther) : fSize(iOther.fSize), fStart(iOther.fStart)
41 {
42 fBuf = new T[fSize];
43 memcpy(fBuf, iOther.fBuf, fSize * sizeof(T));
44 }
45
47 {
48 delete[] fBuf;
49 }
50
51 // handle negative offsets as well
52 inline int getSize() const
53 {
54 return fSize;
55 }
56
57 inline T getAt(int offset) const
58 {
59 return fBuf[adjustIndexFromOffset(offset)];
60 }
61
62 inline void setAt(int offset, T e)
63 {
64 fBuf[adjustIndexFromOffset(offset)] = e;
65 };
66
67 inline void incrementHead()
68 {
70 }
71
72 inline void push(T e)
73 {
74 setAt(0, e);
76 }
77
78 inline void init(T initValue)
79 {
80 for(int i = 0; i < fSize; ++i)
81 {
82 fBuf[i] = initValue;
83 }
84 }
85
86 inline void copyToBuffer(int startOffset, T *oBuffer, int iSize)
87 {
88 int adjStartOffset = adjustIndexFromOffset(startOffset);
89
90 if(adjStartOffset + iSize < fSize)
91 {
92 memcpy(oBuffer, &fBuf[adjStartOffset], iSize * sizeof(T));
93 }
94 else
95 {
96 int i = adjStartOffset;
97 for(int k = 0; k < iSize; k++)
98 {
99 oBuffer[k] = fBuf[i];
100 i++;
101 if(i == fSize)
102 i = 0;
103 }
104 }
105 }
106
107
130 template<typename U, class BinaryPredicate>
131 inline U fold(int startOffset, int endOffsetNotIncluded, U initValue, BinaryPredicate &op) const
132 {
133 if(startOffset == endOffsetNotIncluded)
134 return initValue;
135
136 U resultValue = initValue;
137
138 int i = adjustIndexFromOffset(startOffset);
139
140 if(startOffset < endOffsetNotIncluded)
141 {
142 int size = endOffsetNotIncluded - startOffset;
143 while(size > 0)
144 {
145 resultValue = op(resultValue, fBuf[i]);
146 ++i;
147 if(i == fSize)
148 i = 0;
149 size--;
150 }
151 }
152 else
153 {
154 int size = startOffset - endOffsetNotIncluded;
155 while(size > 0)
156 {
157 resultValue = op(resultValue, fBuf[i]);
158 --i;
159 if(i == -1)
160 i = fSize - 1;
161 size--;
162 }
163 }
164
165 return resultValue;
166 }
167
171 template<typename U, class BinaryPredicate>
172 inline U fold(int endOffsetNotIncluded, U initValue, BinaryPredicate &op) const
173 {
174 return fold(0, endOffsetNotIncluded, initValue, op);
175 }
176
180 template<typename U, class BinaryPredicate>
181 inline U fold(U initValue, BinaryPredicate &op) const
182 {
183 return fold(0, fSize, initValue, op);
184 }
185
192 template<typename U, class BinaryPredicateWithIndex>
193 inline U foldWithIndex(int startOffset, int endOffsetNotIncluded, U initValue, BinaryPredicateWithIndex &op) const
194 {
195 if(startOffset == endOffsetNotIncluded)
196 return initValue;
197
198 U resultValue = initValue;
199
200 int i = adjustIndexFromOffset(startOffset);
201 int index = startOffset;
202
203 if(startOffset < endOffsetNotIncluded)
204 {
205 int size = endOffsetNotIncluded - startOffset;
206 while(size > 0)
207 {
208 resultValue = op(index, resultValue, fBuf[i]);
209 ++i;
210 if(i == fSize)
211 i = 0;
212 size--;
213 index++;
214 }
215 }
216 else
217 {
218 int size = startOffset - endOffsetNotIncluded;
219 while(size > 0)
220 {
221 resultValue = op(index, resultValue, fBuf[i]);
222 --i;
223 if(i == -1)
224 i = fSize - 1;
225 size--;
226 index--;
227 }
228 }
229
230 return resultValue;
231 }
232
236 template<typename U, class BinaryPredicateWithIndex>
237 inline U foldWithIndex(int endOffsetNotIncluded, U initValue, BinaryPredicateWithIndex &op) const
238 {
239 return foldWithIndex(0, endOffsetNotIncluded, initValue, op);
240 }
241
245 template<typename U, class BinaryPredicateWithIndex>
246 inline U foldWithIndex(U initValue, BinaryPredicateWithIndex &op) const
247 {
248 return foldWithIndex(0, fSize, initValue, op);
249 }
250
251private:
252 inline int adjustIndexFromOffset(int offset) const
253 {
254 if(offset == 0)
255 return fStart;
256
257 return adjustIndex(fStart + offset);
258 }
259
260 inline int adjustIndex(int index) const
261 {
262 // shortcut since this is a frequent use case
263 if(index == fSize)
264 return 0;
265
266 while(index < 0)
267 index += fSize;
268
269 while(index >= fSize)
270 index -= fSize;
271
272 return index;
273 }
274
275 int fSize;
278};
279
280}
281}
282}
283
284#endif // __PONGASOFT_UTILS_COLLECTION_CIRCULAR_BUFFER_H__
int fStart
Definition CircularBuffer.h:277
U foldWithIndex(U initValue, BinaryPredicateWithIndex &op) const
Shortcut for entire buffer (starting at startOffset 0).
Definition CircularBuffer.h:246
int adjustIndexFromOffset(int offset) const
Definition CircularBuffer.h:252
U foldWithIndex(int startOffset, int endOffsetNotIncluded, U initValue, BinaryPredicateWithIndex &op) const
Similar to fold but BinaryPredicateWithIndex is also provided the index (starting at startOffset).
Definition CircularBuffer.h:193
void setAt(int offset, T e)
Definition CircularBuffer.h:62
void copyToBuffer(int startOffset, T *oBuffer, int iSize)
Definition CircularBuffer.h:86
U fold(int endOffsetNotIncluded, U initValue, BinaryPredicate &op) const
Shortcut with startOffset 0.
Definition CircularBuffer.h:172
T getAt(int offset) const
Definition CircularBuffer.h:57
int getSize() const
Definition CircularBuffer.h:52
void push(T e)
Definition CircularBuffer.h:72
int adjustIndex(int index) const
Definition CircularBuffer.h:260
U fold(U initValue, BinaryPredicate &op) const
Shortcut for entire buffer (starting at startOffset 0).
Definition CircularBuffer.h:181
CircularBuffer(CircularBuffer const &iOther)
Definition CircularBuffer.h:40
void incrementHead()
Definition CircularBuffer.h:67
U fold(int startOffset, int endOffsetNotIncluded, U initValue, BinaryPredicate &op) const
"standard" implementation of the fold algorithm starting at startOffset and ending at endOffsetNotInc...
Definition CircularBuffer.h:131
int fSize
Definition CircularBuffer.h:275
void init(T initValue)
Definition CircularBuffer.h:78
U foldWithIndex(int endOffsetNotIncluded, U initValue, BinaryPredicateWithIndex &op) const
Shortcut with startOffset = 0.
Definition CircularBuffer.h:237
~CircularBuffer()
Definition CircularBuffer.h:46
CircularBuffer(int iSize)
Definition CircularBuffer.h:33
T * fBuf
Definition CircularBuffer.h:276
Definition CircularBuffer.h:27
Definition CircularBuffer.h:26
Definition Clock.h:23