EDIT
After all of the valuable comments I have modified my class. The one thing. I've tried to incorporate all of the comments and also my findings online. The one missing piece left is described by @David problem with destruction of an empty Buffer
, but I'll update the solution once this will be fixed.
#include <deque>
#include <thread>
#include <mutex>
#include <condition_variable>
template <typename T>
class Buffer
{
public:
void add(const T& num)
{
std::unique_lock<std::mutex> locker(mu);
buffer.push_back(num);
locker.unlock();
cond.notify_one();
}
void add(T&& num)
{
std::unique_lock<std::mutex> locker(mu);
buffer.push_back(std::move(num));
locker.unlock();
cond.notify_one();
}
template<typename ...Args>
void emplace_back(Args&&... args)
{
std::unique_lock<std::mutex> locker(mu);
buffer.emplace_back(std::forward<Args>(args)...);
locker.unlock();
cond.notify_one();
}
T remove()
{
std::unique_lock<std::mutex> locker(mu);
cond.wait(locker, [this](){return !buffer.empty();});
T front(std::move(buffer.front()));
buffer.pop_front();
return front;
}
int size()
{
std::lock_guard<std::mutex> lock{mu};
return buffer.size();
}
private:
std::mutex mu;
std::condition_variable cond;
std::deque<T> buffer;
};