50#if defined(__aarch64__) || defined(_M_ARM64)
56template <
typename T, std::
size_t Capacity = 32>
59 static_assert(Capacity > 0 && (Capacity & (Capacity - 1)) == 0,
60 "SpscQueue: Capacity must be a power of two.");
61 static_assert(std::is_trivially_copyable_v<T>,
62 "SpscQueue: Element type must be trivially copyable for lock-free safety.");
80 [[nodiscard]]
bool push(
const T& item)
noexcept
82 const auto write = writePos_.load(std::memory_order_relaxed);
83 const auto next = (write + 1) & kMask;
86 if (next == cachedReadPos_)
88 cachedReadPos_ = readPos_.load(std::memory_order_acquire);
89 if (next == cachedReadPos_)
93 buffer_[write] = item;
94 writePos_.store(next, std::memory_order_release);
107 [[nodiscard]]
bool pop(T& item)
noexcept
109 const auto read = readPos_.load(std::memory_order_relaxed);
112 if (read == cachedWritePos_)
114 cachedWritePos_ = writePos_.load(std::memory_order_acquire);
115 if (read == cachedWritePos_)
119 item = buffer_[read];
120 readPos_.store((read + 1) & kMask, std::memory_order_release);
133 const auto w = writePos_.load(std::memory_order_relaxed);
134 const auto r = readPos_.load(std::memory_order_relaxed);
135 return (w - r) & kMask;
142 [[nodiscard]]
static constexpr std::size_t
capacity() noexcept {
return Capacity - 1; }
145 static constexpr std::size_t kMask = Capacity - 1;
147 std::array<T, Capacity> buffer_ {};
151#pragma warning(disable: 4324)
158 std::size_t cachedReadPos_ {0};
164 std::size_t cachedWritePos_ {0};
std::size_t sizeApprox() const noexcept
Returns the approximate number of elements in the queue.
SpscQueue(const SpscQueue &)=delete
bool empty() const noexcept
Returns true if the queue appears empty (approximate).
SpscQueue & operator=(const SpscQueue &)=delete
static constexpr std::size_t capacity() noexcept
Usable capacity: one slot is reserved to tell full from empty.
SpscQueue()=default
Constructs an empty SPSC queue.
bool push(const T &item) noexcept
Pushes an element into the queue (producer side).
bool pop(T &item) noexcept
Pops an element from the queue (consumer side).
Main namespace for the DSPark framework.
constexpr std::size_t kCacheLineSize