template class threadsafe_queue { private: std::unique_ptr try_pop_head() { std::lock_guard head_lock(head_mutex); if (head.get() == get_tail()) { return std::unique_ptr(); } return pop_head(); } std::unique_ptr try_pop_head(T& value) { std::lock_guard head_lock(head_mutex); if (head.get() == get_tail()) { return std::unique_ptr(); } value = std::move(*head->data); return pop_head(); } public: std::shared_ptr try_pop() { std::unique_ptr const old_head = try_pop_head(); return old_head ? old_head->data : std::shared_ptr(); } bool try_pop(T& value) { std::unique_ptr const old_head = try_pop_head(value); return old_head; } void empty() { std::lock_guard head_lock(head_mutex); return (head == get_tail()); } };