25 struct alignas(cache_line_size) aligned_item
28 aligned_item() =
default;
29 aligned_item(T&& value) : item(std::move(value)) {}
30 template <
typename U = T, std::enable_if_t<std::is_copy_constructible_v<U>,
int> = 0>
31 aligned_item(T
const& value) : item(value)
36 std::unique_ptr<aligned_item[]> buffer_;
38 alignas(cache_line_size) std::atomic<size_t> top_{ 0 };
39 alignas(cache_line_size) std::atomic<size_t> bottom_{ 0 };
40 alignas(cache_line_size)
mutable std::mutex mutex_;
44 : buffer_(
std::make_unique<aligned_item[]>(capacity)), capacity_(capacity)
51 std::lock_guard<std::mutex> lock(mutex_);
52 size_t const top = top_.load(std::memory_order_relaxed);
53 size_t const bottom = bottom_.load(std::memory_order_relaxed);
54 if (top - bottom >= capacity_)
56 buffer_[top % capacity_] = aligned_item(std::move(item));
57 top_.store(top + 1, std::memory_order_release);
61 template <
typename U = T, std::enable_if_t<std::is_copy_constructible_v<U>,
int> = 0>
63 push(T
const& item) ->
bool
65 std::lock_guard<std::mutex> lock(mutex_);
66 size_t const top = top_.load(std::memory_order_relaxed);
67 size_t const bottom = bottom_.load(std::memory_order_relaxed);
68 if (top - bottom >= capacity_)
70 buffer_[top % capacity_] = aligned_item(item);
71 top_.store(top + 1, std::memory_order_release);
78 std::lock_guard<std::mutex> lock(mutex_);
79 size_t const top = top_.load(std::memory_order_relaxed);
80 size_t const bottom = bottom_.load(std::memory_order_relaxed);
83 size_t const new_top = top - 1;
84 item = std::move(buffer_[new_top % capacity_].item);
85 top_.store(new_top, std::memory_order_relaxed);
92 std::lock_guard<std::mutex> lock(mutex_);
93 size_t const bottom = bottom_.load(std::memory_order_relaxed);
94 size_t const top = top_.load(std::memory_order_relaxed);
97 item = std::move(buffer_[bottom % capacity_].item);
98 bottom_.store(bottom + 1, std::memory_order_relaxed);
105 size_t const top = top_.load(std::memory_order_relaxed);
106 size_t const bottom = bottom_.load(std::memory_order_relaxed);
107 return top > bottom ? top - bottom : 0;
119 (void)clear_and_count();
127 while (steal(discarded))