WPOCT Software Developer's Kit (SDK)
SDK For using Wasatch Photonics OCT Spectrometers
SameSizeBuffers.h
Go to the documentation of this file.
1 
6 #pragma once
7 
8 #include <vector>
9 #include <boost/thread/mutex.hpp>
10 
15 template <typename T, typename U>
17 {
18 public:
19  // Constructors
21  SameSizeBuffers(int sizeOfBuffer);
22  SameSizeBuffers(int sizeOfBuffer, int numBuffers);
23 
24  virtual ~SameSizeBuffers();
25 
26  // Getters
27  int GetNumBuffers () const { return (int)_buffers.size(); }
28  int GetBufferSize () const { return _bufferSize; }
29  int GetCurrentBuffer () const { return _currentBuffer; }
30  int GetFirstBufferIndex () const { return _firstBufferIndex; }
31  int GetNumBuffersInRing () const { return max(_buffers.size() - _firstBufferIndex, 0); }
32 
34  T* operator[] (int index);
35 
36  // Setters
37  void SetCurrentBuffer (int value);
39  void SetFirstBufferIndex (int value);
40 
41  // Methods
42  bool CreateBuffers (int bufferSize, int numBuffers);
43  bool SetBufferToValue (int index, U value);
44 
45  bool AddTogether (int sourceIndex, int destIndex);
46  bool Subtract (int sourceIndex, int destIndex);
47  bool CopyBufferIn (U* buffer, int index);
48  bool AddBufferToAverage (U* buffer, int index, int divisor);
49  bool CopyBufferOut (U* buffer, int index);
50  void Clear();
51 
52 private:
54  std::vector<std::vector<T>> _buffers;
55 
57  boost::mutex _mutex;
58 
60  int _bufferSize;
62  int _currentBuffer;
64  int _firstBufferIndex;
65 
66  // Methods
67  void Init ();
68  void DeleteAll ();
69  void AddOrDeleteBuffers (int numTotalBuffers);
70 
75  bool UsingSameType() const { return (std::is_same<T, U>::value); }
76 
77 };
78 
79 
80 // Implementation - included here since the class is templated.
81 
85 template <typename T, typename U>
87 {
88  Init();
89 }
90 
95 template <typename T, typename U>
97 {
98  Init();
99  _bufferSize = sizeOfBuffer;
100 }
101 
108 template <typename T, typename U>
109 SameSizeBuffers<T, U>::SameSizeBuffers(int sizeOfBuffer, int numBuffers)
110 {
111  Init();
112  CreateBuffers(int bufferSize, int numBuffers);
113 }
114 
118 template <typename T, typename U>
120 {
121  DeleteAll();
122  _bufferSize = 0;
123  _currentBuffer = -1;
124  _firstBufferIndex = 0;
125 }
126 
130 template <typename T, typename U>
132 {
133  _bufferSize = 0;
134  _currentBuffer = -1;
135  _firstBufferIndex = 0;
136 }
137 
142 template <typename T, typename U>
144 {
145  if (value < _buffers.size())
146  {
147  _currentBuffer = value;
148  }
149 }
150 
154 template <typename T, typename U>
156 {
157  for (int i = (int)_buffers.size() - 1; i >= 0; i--)
158  {
159  _buffers[i].clear();
160  }
161  _buffers.clear();
162 }
163 
170 template <typename T, typename U>
171 bool SameSizeBuffers<T, U>::CreateBuffers(int bufferSize, int numBuffers)
172 {
173  bool result = false;
174  try
175  {
176  boost::mutex::scoped_lock lock(_mutex);
177  if (bufferSize == _bufferSize && numBuffers == _buffers.size())
178  return true;
179 
180  if (bufferSize <= 0 || numBuffers <= 0)
181  {
182  DeleteAll();
183  }
184  else if (bufferSize == _bufferSize)
185  {
186  AddOrDeleteBuffers(numBuffers);
187  }
188  else
189  {
190  // Delete buffers and reallocate.
191  _bufferSize = bufferSize;
192  DeleteAll();
193  for (int i = 0; i < numBuffers; i++)
194  {
195  _buffers.push_back(vector<T>(_bufferSize));
196  }
197  }
198  result = true;
199  }
200  catch (exception&)
201  {
202  }
203  return result;
204 }
205 
209 template <typename T, typename U>
211 {
212  boost::mutex::scoped_lock lock(_mutex);
213  DeleteAll();
214 }
215 
220 template <typename T, typename U>
222 {
223  boost::mutex::scoped_lock lock(_mutex);
224  _currentBuffer = _firstBufferIndex;
225  return _firstBufferIndex;
226 }
227 
232 template <typename T, typename U>
233 void SameSizeBuffers<T, U>::AddOrDeleteBuffers(int numTotalBuffers)
234 {
235  int currentBufferCount = (int)_buffers.size();
236  // We can use existing buffers here. Add more as needed.
237  if (numTotalBuffers > currentBufferCount)
238  {
239  for (int i = 0; i < numTotalBuffers - currentBufferCount; i++)
240  {
241  _buffers.push_back(vector<T>(_bufferSize));
242  }
243 
244  }
245  // Else, delete unneeded buffers.
246  else
247  {
248  for (int i = currentBufferCount - 1; i >= numTotalBuffers; i--)
249  {
250  _buffers[i].clear();
251  _buffers.erase(_buffers.begin() + i);
252  }
253  }
254 }
255 
261 template <typename T, typename U>
263 {
264  boost::mutex::scoped_lock lock(_mutex);
265  if (index < _buffers.size())
266  {
267  return _buffers[index].data();
268  }
269  return nullptr;
270 }
271 
276 template <typename T, typename U>
278 {
279  boost::mutex::scoped_lock lock(_mutex);
280  ++_currentBuffer;
281  // If we hit the end of our circular buffer...
282  if (_currentBuffer >= _buffers.size())
283  {
284  // Set the current buffer to the beginning of the circular buffer.
285  _currentBuffer = _firstBufferIndex;
286  }
287  return _currentBuffer;
288 }
289 
296 template <typename T, typename U>
297 bool SameSizeBuffers<T, U>::CopyBufferIn(U* buffer, int index)
298 {
299  bool result = false;
300  boost::mutex::scoped_lock lock(_mutex);
301 
302  if (index < _buffers.size())
303  {
304  if (UsingSameType())
305  {
306  memcpy(_buffers[index].data(), buffer, _bufferSize * sizeof(T));
307  }
308  else
309  {
310  for (int i = 0; i < _bufferSize; i++)
311  {
312  _buffers[index][i] = static_cast<T>(*(buffer + i));
313  }
314  }
315  result = true;
316  }
317  return result;
318 }
319 
327 template <typename T, typename U>
328 bool SameSizeBuffers<T, U>::AddBufferToAverage(U* buffer, int index, int divisor)
329 {
330  bool result = false;
331  boost::mutex::scoped_lock lock(_mutex);
332 
333  if (index < _buffers.size())
334  {
335  if (UsingSameType())
336  {
337  for (int i = 0; i < _bufferSize; i++)
338  {
339  _buffers[index][i] = *(buffer + i) / static_cast<T>(divisor);
340  }
341  }
342  else
343  {
344  for (int i = 0; i < _bufferSize; i++)
345  {
346  _buffers[index][i] = static_cast<T>(*(buffer + i) / divisor);
347  }
348  }
349  result = true;
350  }
351  return result;
352 }
353 
361 template <typename T, typename U>
362 bool SameSizeBuffers<T, U>::CopyBufferOut(U* buffer, int index)
363 {
364  bool result = false;
365  boost::mutex::scoped_lock lock(_mutex);
366  if (index < _buffers.size())
367  {
368  if (UsingSameType())
369  {
370  memcpy(buffer, _buffers[index].data(), _bufferSize * sizeof(T));
371  }
372  else
373  {
374  for (int i = 0; i < _bufferSize; i++)
375  {
376  *(buffer + i) = static_cast<U>(_buffers[index][i]);
377  }
378  }
379  result = true;
380  }
381 
382  return result;
383 }
384 
391 template <typename T, typename U>
393 {
394  bool result = false;
395  boost::mutex::scoped_lock lock(_mutex);
396 
397  if (index < _buffers.size())
398  {
399  if (UsingSameType())
400  {
401  std::fill_n(_buffers[index].begin(), _bufferSize, value);
402  }
403  else
404  {
405  std::fill_n(_buffers[index].begin(), _bufferSize, static_cast<T>(value));
406  }
407  result = true;
408  }
409 
410  return result;
411 }
412 
419 template <typename T, typename U>
420 bool SameSizeBuffers<T, U>::AddTogether(int sourceIndex, int destIndex)
421 {
422  bool result = false;
423  boost::mutex::scoped_lock lock(_mutex);
424 
425  if (sourceIndex < (int)_buffers.size() && destIndex < (int)_buffers.size())
426  {
427  for (int i = 0; i < _bufferSize; i++)
428  {
429  _buffers[destIndex][i] += _buffers[sourceIndex][i];
430  }
431  result = true;
432  }
433  return result;
434 }
435 
442 template <typename T, typename U>
443 bool SameSizeBuffers<T, U>::Subtract(int sourceIndex, int destIndex)
444 {
445  bool result = false;
446  boost::mutex::scoped_lock lock(_mutex);
447 
448  if (sourceIndex < _buffers.size() && destIndex < _buffers.size())
449  {
450  for (int i = 0; i < _bufferSize; i++)
451  {
452  _buffers[destIndex][i] -= _buffers[sourceIndex][i];
453  }
454  result = true;
455  }
456  return result;
457 }
458 
463 template <typename T, typename U>
465 {
466  boost::mutex::scoped_lock lock(_mutex);
467  _firstBufferIndex = value;
468  if (_firstBufferIndex > _currentBuffer + 1)
469  {
470  _currentBuffer = _firstBufferIndex - 1;
471  }
472 }
473 
A general purpose templated class that holds a programmable number of buffers, each the same size.
Definition: SameSizeBuffers.h:17
bool CopyBufferIn(U *buffer, int index)
Copies the buffer supplied to the buffer specified by the index.
Definition: SameSizeBuffers.h:297
void Clear()
Deletes all buffers and the pointers to them.
Definition: SameSizeBuffers.h:210
bool SetBufferToValue(int index, U value)
Sets each element in the buffer to value supplied.
Definition: SameSizeBuffers.h:392
void SetCurrentBuffer(int value)
Sets the value of the current buffer.
Definition: SameSizeBuffers.h:143
bool AddTogether(int sourceIndex, int destIndex)
Adds the source and destination buffers together and places the result in the destination.
Definition: SameSizeBuffers.h:420
bool CreateBuffers(int bufferSize, int numBuffers)
Creates the buffers specified by the supplied parameters.
Definition: SameSizeBuffers.h:171
virtual ~SameSizeBuffers()
Finalizes an instance of the SameSizeBuffers<T, U> class.
Definition: SameSizeBuffers.h:119
bool CopyBufferOut(U *buffer, int index)
Copies the buffer specified by the index out to the buffer supplied.
Definition: SameSizeBuffers.h:362
SameSizeBuffers(int sizeOfBuffer)
Initializes a new instance of the SameSizeBuffers<T, U> class.
Definition: SameSizeBuffers.h:96
bool AddBufferToAverage(U *buffer, int index, int divisor)
Copies the buffer supplied to the buffer specified by the index.
Definition: SameSizeBuffers.h:328
bool Subtract(int sourceIndex, int destIndex)
Subtracts the source buffer from the destination buffer and places the result in the destination.
Definition: SameSizeBuffers.h:443
T * operator[](int index)
Returns a pointer to the buffer specified by the index.
Definition: SameSizeBuffers.h:262
int GetNextBufferIndex()
Gets the index of the next buffer in the circular queue.
Definition: SameSizeBuffers.h:277
int ResetCurrentBuffer()
Resets the current buffer to the index of the first buffer in the circular queue.
Definition: SameSizeBuffers.h:221
SameSizeBuffers()
Initializes a new instance of the SameSizeBuffers<T, U> class.
Definition: SameSizeBuffers.h:86
SameSizeBuffers(int sizeOfBuffer, int numBuffers)
Initializes a new instance of the SameSizeBuffers<T, U> class and creates the buffers specified.
Definition: SameSizeBuffers.h:109
void SetFirstBufferIndex(int value)
Sets the first index of the circular buffer.
Definition: SameSizeBuffers.h:464