// // Created by loki on 6/10/19. // #ifndef SUNSHINE_QUEUE_H #define SUNSHINE_QUEUE_H #include #include #include #include "utility.h" namespace safe { template class queue_t { using status_t = util::either_t< (std::is_same_v || util::instantiation_of_v || util::instantiation_of_v || std::is_pointer_v), T, std::optional>; public: template void push(Args &&... args) { std::lock_guard lg{_lock}; if(!_continue) { return; } _queue.emplace_back(std::forward(args)...); _cv.notify_all(); } bool peek() { std::lock_guard lg { _lock }; return !_queue.empty(); } status_t pop() { std::unique_lock ul{_lock}; if (!_continue) { return util::false_v; } while (_queue.empty()) { _cv.wait(ul); if (!_continue) { return util::false_v; } } auto val = std::move(_queue.front()); _queue.erase(std::begin(_queue)); return val; } std::vector &unsafe() { return _queue; } void stop() { std::lock_guard lg{_lock}; _continue = false; _cv.notify_all(); } bool running() const { return _continue; } private: bool _continue{true}; std::mutex _lock; std::condition_variable _cv; std::vector _queue; }; } #endif //SUNSHINE_QUEUE_H