// PHZ
// 2018-5-15
#ifndef _RING_BUFFER_H
#define _RING_BUFFER_H
#include <vector>
#include <memory>
#include <atomic>
#include <iostream>
template <typename T>
class RingBuffer
{
public:
RingBuffer(unsigned capacity=60)
: _buffer(capacity)
, _capacity(capacity)
, _numDatas(0)
{ }
~RingBuffer() { }
bool push(const T& data) { return pushData(std::forward<T>(data)); }
bool push(T&& data) { return pushData(data); }
bool pop(T& data)
{
if(_numDatas > 0)
{
data = std::move(_buffer[_getPos]);
add(_getPos);
_numDatas--;
return true;
}
return false;
}
bool isFull() const { return ((_numDatas==_capacity)?true:false); }
bool isEmpty() const { return ((_numDatas==0)?true:false); }
int size() const { return _numDatas; }
private:
template <typename F>
bool pushData(F&& data)
{
if (_numDatas < _capacity)
{
_buffer[_putPos] = std::forward<F>(data);
add(_putPos);
_numDatas++;
return true;
}
return false;
}
void add(int& pos)
{
pos = (((pos+1)==_capacity) ? 0 : (pos+1));
}
int _capacity = 0;
int _putPos = 0;
int _getPos = 0;
std::atomic_int _numDatas;
std::vector<T> _buffer;
};
#endif