#ifndef CONCURRENTQUEUE_H #define CONCURRENTQUEUE_H #include #include #include using namespace std; template class ConcurrentQueue { private: queue queue_; mutable mutex mutex_; condition_variable condition_; public: // Apparently, if you have a mutex in a class, you can't copy or assign the class to any other class. ConcurrentQueue() = default; ConcurrentQueue(const ConcurrentQueue&) = delete; // Prevent copying ConcurrentQueue& operator=(const ConcurrentQueue&) = delete; // Prevent assignment void push(T value) { lock_guard lock(mutex_); queue_.push(move(value)); condition_.notify_one(); } bool try_pop(T& value) { lock_guard lock(mutex_); if (queue_.empty()) { return false; } value = move(queue_.front()); queue_.pop(); return true; } T wait_and_pop() { unique_lock lock(mutex_); condition_.wait(lock, [this] { return !queue_.empty(); }); T value = move(queue_.front()); queue_.pop(); return value; } bool empty() const { lock_guard lock(mutex_); return queue_.empty(); } int size() { lock_guard lock(mutex_); return queue_.size(); } }; #endif