#pragma once #include #include #include #include namespace lumi { template class bounded_spsc_queue { static_assert(Capacity > 1); std::array values_{}; alignas(64) std::atomic head_{0}; alignas(64) std::atomic tail_{0}; std::atomic dropped_{0}; public: bool try_push(T value) noexcept { const auto head = head_.load(std::memory_order_relaxed); const auto next = (head + 1) % Capacity; if (next == tail_.load(std::memory_order_acquire)) { dropped_.fetch_add(1, std::memory_order_relaxed); return false; } values_[head] = std::move(value); head_.store(next, std::memory_order_release); return true; } std::optional try_pop() noexcept { const auto tail = tail_.load(std::memory_order_relaxed); if (tail == head_.load(std::memory_order_acquire)) return std::nullopt; T value = std::move(values_[tail]); tail_.store((tail + 1) % Capacity, std::memory_order_release); return value; } std::uint64_t dropped() const noexcept { return dropped_.load(std::memory_order_relaxed); } }; }