Program Listing for File queue.hpp

Return to documentation for file (include/rsl/queue.hpp)

#pragma once

#include <chrono>
#include <condition_variable>
#include <mutex>
#include <optional>
#include <queue>

namespace rsl {

template <typename T>
class Queue {
    std::queue<T> queue_;
    std::condition_variable cv_;
    mutable std::mutex mutex_;

   public:
    [[nodiscard]] auto size() const noexcept {
        auto const lock = std::lock_guard(mutex_);
        return queue_.size();
    }

    [[nodiscard]] auto empty() const noexcept {
        auto const lock = std::lock_guard(mutex_);
        return queue_.empty();
    }

    void push(T value) noexcept {
        auto const lock = std::lock_guard(mutex_);
        queue_.push(std::move(value));
        cv_.notify_one();
    }

    void clear() noexcept {
        auto const lock = std::lock_guard(mutex_);

        // Swap queue with an empty queue of the same type to ensure queue_ is left in a
        // default-constructed state
        decltype(queue_)().swap(queue_);
    }

    [[nodiscard]] auto pop(std::chrono::nanoseconds wait_time = {}) -> std::optional<T> {
        auto lock = std::unique_lock(mutex_);

        // If queue is empty after wait_time, return nothing
        if (!cv_.wait_for(lock, wait_time, [this] { return !queue_.empty(); })) return std::nullopt;

        auto value = queue_.front();
        queue_.pop();
        return value;
    }
};
}  // namespace rsl