#pragma once

#include <mutex>
#include <optional>
#include <utility>

namespace ta::foundation
{
template <class T>
class CoalescingCommandSlot
{
public:
    std::optional<T> submit(T value)
    {
        std::lock_guard lock(mutex_);
        std::optional<T> replaced = std::move(pending_);
        pending_ = std::move(value);
        return replaced;
    }

    std::optional<T> consume()
    {
        std::lock_guard lock(mutex_);
        return std::exchange(pending_, std::nullopt);
    }

    [[nodiscard]] bool has_pending() const
    {
        std::lock_guard lock(mutex_);
        return pending_.has_value();
    }

private:
    mutable std::mutex mutex_;
    std::optional<T> pending_;
};
}
