blob: 5791600a93585576e8797e7b2498e1e7bcb292d9 [file] [log] [blame] [edit]
#pragma once
#include <condition_variable>
#include <deque>
#include <mutex>
// Copied from
// https://morestina.net/blog/1400/minimalistic-blocking-bounded-queue-for-c
template <typename T> class queue
{
std::deque<T> content;
size_t capacity;
std::mutex mutex;
std::condition_variable not_empty;
std::condition_variable not_full;
queue(const queue&) = delete;
queue(queue&&) = delete;
queue& operator=(const queue&) = delete;
queue& operator=(queue&&) = delete;
public:
queue(size_t capacity) : capacity(capacity) {}
void push(T&& item)
{
{
std::unique_lock<std::mutex> lk(mutex);
not_full.wait(lk, [this]() { return content.size() < capacity; });
content.push_back(std::move(item));
}
not_empty.notify_one();
}
bool try_push(T&& item)
{
{
std::unique_lock<std::mutex> lk(mutex);
if (content.size() == capacity)
return false;
content.push_back(std::move(item));
}
not_empty.notify_one();
return true;
}
void pop(T& item)
{
{
std::unique_lock<std::mutex> lk(mutex);
not_empty.wait(lk, [this]() { return !content.empty(); });
item = std::move(content.front());
content.pop_front();
}
not_full.notify_one();
}
bool try_pop(T& item)
{
{
std::unique_lock<std::mutex> lk(mutex);
if (content.empty())
return false;
item = std::move(content.front());
content.pop_front();
}
not_full.notify_one();
return true;
}
};