#ifndef ASYNC_CONTAINERS_HPP #define ASYNC_CONTAINERS_HPP #include <deque> #include <mutex> // AsyncQueue will remove items as they are consumed template <typename T, T sentinel> struct AsyncQueue { std::mutex m; std::deque<T> container; bool done = false; void produce(T m) { m.lock(); container.push_back(m); m.unlock(); } // do we need to use std::optional? T consume() { T ret; // Wait while (container.empty() && !done) { }; if (container.empty()) { // done return sentinel; } m.lock(); ret = container.front(); container.pop_front(); m.unlock(); return ret; } void finish() { done = true; } void reset() { done = false; } }; // AsyncBuffer will persist items template <typename T, T sentinel> struct AsyncBuffer { std::mutex m; std::deque container; bool done = false; void produce(T m) { m.lock(); container.push_back(m); m.unlock(); } //[] operator (?) T get(size_t i) { T ret; // Wait while (container.size() <= i && !done) { }; if (container.size() <= i) { // done return sentinel; } // Is locking necessary here? hmm m.lock(); ret = container[i]; m.unlock(); return ret; } void finish() { done = true; } void reset() { container.clear(); done = false; } }; #endif