59#if defined(__aarch64__) || defined(_M_ARM64)
65template <
typename T, std::
size_t Capacity = 32>
68 static_assert(Capacity > 0 && (Capacity & (Capacity - 1)) == 0,
69 "SpscQueue: Capacity must be a power of two.");
70 static_assert(std::is_trivially_copyable_v<T>,
71 "SpscQueue: Element type must be trivially copyable for lock-free safety.");
89 [[nodiscard]]
bool push(
const T& item)
noexcept
91 const auto write = writePos_.load(std::memory_order_relaxed);
92 const auto next = (write + 1) & kMask;
95 if (next == cachedReadPos_)
97 cachedReadPos_ = readPos_.load(std::memory_order_acquire);
98 if (next == cachedReadPos_)
102 buffer_[write] = item;
103 writePos_.store(next, std::memory_order_release);
116 [[nodiscard]]
bool pop(T& item)
noexcept
118 const auto read = readPos_.load(std::memory_order_relaxed);
121 if (read == cachedWritePos_)
123 cachedWritePos_ = writePos_.load(std::memory_order_acquire);
124 if (read == cachedWritePos_)
128 item = buffer_[read];
129 readPos_.store((read + 1) & kMask, std::memory_order_release);
142 const auto w = writePos_.load(std::memory_order_relaxed);
143 const auto r = readPos_.load(std::memory_order_relaxed);
144 return (w - r) & kMask;
151 [[nodiscard]]
static constexpr std::size_t
capacity() noexcept {
return Capacity - 1; }
154 static constexpr std::size_t kMask = Capacity - 1;
156 std::array<T, Capacity> buffer_ {};
160#pragma warning(disable: 4324)
167 std::size_t cachedReadPos_ {0};
173 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