generic_ring_buffer.h
Go to the documentation of this file.
1 // *****************************************************************************
2 //
3 // Copyright (c) 2014, Southwest Research Institute® (SwRI®)
4 // All rights reserved.
5 //
6 // Redistribution and use in source and binary forms, with or without
7 // modification, are permitted provided that the following conditions are met:
8 // * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above copyright
11 // notice, this list of conditions and the following disclaimer in the
12 // documentation and/or other materials provided with the distribution.
13 // * Neither the name of Southwest Research Institute® (SwRI®) nor the
14 // names of its contributors may be used to endorse or promote products
15 // derived from this software without specific prior written permission.
16 //
17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 // ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
21 // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 //
28 // *****************************************************************************
29 
30 #ifndef MATH_UTIL_GENERIC_RING_BUFFER_H_
31 #define MATH_UTIL_GENERIC_RING_BUFFER_H_
32 #ifndef NULL
33 #define NULL 0
34 #endif
35 #define GEN_RING_BUFF_DEFAULT_NUM_ELEMENTS 16
36 
37 #include <cassert>
38 #include <algorithm>
39 
40 namespace swri_math_util
41 {
42  template <class T>
44  {
45  public:
46  // Default constructor
48  {
49  NumElements = 0;
51  this->init_array();
52  }
53 
54  explicit GenRingBuffer(int NumElements2Alloc)
55  {
56  NumElements = 0;
57  this->alloc_mem(NumElements2Alloc);
58  this->init_array();
59  }
60 
62  {
63  this->alloc_mem(src.MaxNumElements);
64  this->init_array();
65  this->copyRB(src);
66  }
67 
68  // Copy Assignment
70  {
71  this->copyRB(src);
72  return *this;
73  }
74 
75  virtual ~GenRingBuffer()
76  {
77  delete [] HEAD;
78  }
79 
80  void ResizeBuffer(int newSize)
81  {
82  this->realloc_mem(newSize);
83  }
84 
85  int size() const
86  {
87  return NumElements;
88  }
89 
90  int MaxSize() const
91  {
92  return MaxNumElements;
93  }
94 
95  virtual T* operator[](int i)
96  {
97  return this->get(i);
98  }
99 
100  virtual T* get(int i = 0) const
101  {
102  if (i >= NumElements) return NULL;
103  int j = ((consumePtr-HEAD)+i)%MaxNumElements;
104  return (&HEAD[j].Data);
105  }
106 
107  T* getRaw(int i) const
108  {
109  if (i >= MaxNumElements)
110  {
111  return NULL;
112  }
113  return (&HEAD[i].Data);
114  }
115 
116  T* getLoad() const
117  {
118  return &loadPtr->Data;
119  }
120 
121  // getTail searches backward from index i
122  T* getTail(int i = 0) const
123  {
124  if (i >= NumElements) return NULL;
125  int j = ((loadPtr-1-HEAD)-i);
126  if (j < 0)
127  {
128  j += MaxNumElements;
129  }
130  return (&HEAD[j].Data);
131  }
132 
133  void load(const T &newElem)
134  {
135  this->push(newElem);
136  }
137 
138  void load1(T newElem)
139  {
140  this->push(newElem);
141  }
142 
143  T* pop()
144  {
145  T* temp;
146  if (this->size() == 0)
147  {
148  return 0;
149  }
150  else
151  {
152  temp = this->get();
153  this->incConsumePtr();
154  NumElements--;
155  }
156  return temp;
157  }
158 
159  bool indexValid(int i)
160  {
161  return (i >= 0 && i <this->NumElements);
162  }
163 
164  void clear()
165  {
166  while (this->pop());
167  }
168 
169  protected:
170  void realloc_mem(int NumElements2Alloc)
171  {
172  temp = new ctr[std::max(2, NumElements2Alloc)];
173  this->copy_elems(temp, NumElements2Alloc);
174  delete [] HEAD;
175  HEAD = temp;
176  TAIL = HEAD+NumElements2Alloc;
177  loadPtr = HEAD;
178  consumePtr = HEAD;
179  MaxNumElements = NumElements2Alloc;
181  {
183  }
184  this->init_array();
185  }
186 
187  private:
188  struct ctr
189  {
190  T Data;
193  };
199 
202 
203 
204  bool copy_elems(ctr* dest, int MaxNum2Copy)
205  {
206  bool success;
207  int Num2Copy = std::min(NumElements, MaxNum2Copy);
208  if (Num2Copy !=NumElements)
209  {
210  success = false;
211  }
212  else
213  {
214  success = true;
215  }
216  for (int i = 0; i < Num2Copy; i++)
217  {
218  dest[i].Data = *(this->get(i));
219  }
220  return success;
221  }
222 
223  void push(const T &newElem)
224  {
225  assert(NumElements <= MaxNumElements);
226  loadPtr->Data = newElem;
227  if (NumElements >= MaxNumElements)
228  {
229  this->incLoadPtr();
230  this->incConsumePtr();
231  }
232  else
233  {
234  this->incLoadPtr();
235  NumElements++;
236  }
237  }
238 
239  void incLoadPtr()
240  {
241  loadPtr = loadPtr->next;
242  }
243 
245  {
246  consumePtr = consumePtr->next;
247  }
248 
249  ctr* alloc_mem(int NumElems)
250  {
251  HEAD = new ctr[std::max(NumElems, 2)];
252  TAIL = HEAD+NumElems;
253  loadPtr = HEAD;
254  consumePtr = HEAD;
255  MaxNumElements = NumElems;
256  return HEAD;
257  }
258 
259  void init_array()
260  {
261  int j, k;
262  for (int i = 0; i < MaxNumElements; i++)
263  {
264  j = (i+1)%MaxNumElements;
265  k = (i-1)%MaxNumElements;
266  HEAD[i].next = &HEAD[j];
267  HEAD[i].prev = &HEAD[k];
268  }
269  }
270 
272  {
273  this->clear();
274  if (src.MaxNumElements != this->MaxNumElements)
275  {
276  this->realloc_mem(src.MaxNumElements);
277  }
278 
279  // Initialize the new buffer's number of elements to zero. The for loop
280  // below will take care of incrementing NumElements to the correct value.
281  this->NumElements = 0;
282  // This was the previously-used line of code, which resulted in the
283  // copied-to buffer incorrectly having a NumElements greater than the
284  // copy-from buffer by 1:
285  // this->NumElements = src.NumElements;
286  for (int i = 0; i < src.NumElements; ++i)
287  {
288  this->load(*(src[i]));
289  }
290  }
291  };
292 }
293 
294 #endif // MATH_UTIL_GENERIC_RING_BUFFER_H_
void copyRB(GenRingBuffer< T > &src)
GenRingBuffer(const GenRingBuffer< T > &src)
void realloc_mem(int NumElements2Alloc)
bool copy_elems(ctr *dest, int MaxNum2Copy)
GenRingBuffer< T > & operator=(const GenRingBuffer< T > &src)
#define NULL
#define GEN_RING_BUFF_DEFAULT_NUM_ELEMENTS
GenRingBuffer(int NumElements2Alloc)


swri_math_util
Author(s): Marc Alban
autogenerated on Sat Jan 21 2023 03:13:11