#include <atomic>
#include <condition_variable>
#include <memory>
#include <mutex>
#include <stack>
#include <stdexcept>
#include <thread>
struct empty_stack : public std::exception {
const char* what() const noexcept { return "Empty stack"; }
};
template <typename T> class threadsafe_stack {
private:
std::stack<T> data;
mutable std::mutex m;
std::condition_variable data_condition;
std::atomic<bool> in_waiting_state{true};
public:
threadsafe_stack() {}
~threadsafe_stack() { stop(); }
threadsafe_stack(const threadsafe_stack& other)
{
std::lock_guard<std::mutex> lock(m);
data = other.data;
}
threadsafe_stack& operator=(const threadsafe_stack& other) = delete;
void push(T new_value)
{
std::lock_guard<std::mutex> lock(m);
data.push(std::move(new_value));
data_condition.notify_one(