97 lines
1.3 KiB
C++
97 lines
1.3 KiB
C++
// PHZ
|
|
// 2018-5-15
|
|
|
|
#ifndef XOP_RING_BUFFER_H
|
|
#define XOP_RING_BUFFER_H
|
|
|
|
#include <vector>
|
|
#include <memory>
|
|
#include <atomic>
|
|
#include <iostream>
|
|
|
|
namespace xop
|
|
{
|
|
|
|
template <typename T>
|
|
class RingBuffer
|
|
{
|
|
public:
|
|
RingBuffer(int capacity=60)
|
|
: capacity_(capacity)
|
|
, num_datas_(0)
|
|
, buffer_(capacity)
|
|
{ }
|
|
|
|
virtual ~RingBuffer() { }
|
|
|
|
bool Push(const T& data)
|
|
{
|
|
return pushData(std::forward<T>(data));
|
|
}
|
|
|
|
bool Push(T&& data)
|
|
{
|
|
return PushData(data);
|
|
}
|
|
|
|
bool Pop(T& data)
|
|
{
|
|
if(num_datas_ > 0) {
|
|
data = std::move(buffer_[get_pos_]);
|
|
Add(get_pos_);
|
|
num_datas_--;
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool IsFull() const
|
|
{
|
|
return ((num_datas_==capacity_) ? true : false);
|
|
}
|
|
|
|
bool IsEmpty() const
|
|
{
|
|
return ((num_datas_==0) ? true : false);
|
|
}
|
|
|
|
int Size() const
|
|
{
|
|
return num_datas_;
|
|
}
|
|
|
|
private:
|
|
template <typename F>
|
|
bool PushData(F&& data)
|
|
{
|
|
if (num_datas_ < capacity_)
|
|
{
|
|
buffer_[put_pos_] = std::forward<F>(data);
|
|
Add(put_pos_);
|
|
num_datas_++;
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void Add(int& pos)
|
|
{
|
|
pos = (((pos+1)==capacity_) ? 0 : (pos+1));
|
|
}
|
|
|
|
int capacity_ = 0;
|
|
int put_pos_ = 0;
|
|
int get_pos_ = 0;
|
|
|
|
std::atomic_int num_datas_;
|
|
std::vector<T> buffer_;
|
|
};
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|