* @brief Attempt to dequeue an item * * @param item Reference to store the dequeued item * @return true if an item was successfully dequeued * @return false if the queue is empty */
| 85 | * @return false if the queue is empty |
| 86 | */ |
| 87 | [[nodiscard]] auto pop(T& item) noexcept -> bool { |
| 88 | size_t pos; |
| 89 | Cell* cell; |
| 90 | size_t seq; |
| 91 | |
| 92 | pos = tail_.load(std::memory_order_relaxed); |
| 93 | |
| 94 | for (;;) { |
| 95 | cell = &buffer_[pos & (Capacity - 1)]; |
| 96 | seq = cell->sequence.load(std::memory_order_acquire); |
| 97 | intptr_t diff = |
| 98 | static_cast<intptr_t>(seq) - static_cast<intptr_t>(pos + 1); |
| 99 | |
| 100 | if (diff == 0) { |
| 101 | if (tail_.compare_exchange_weak(pos, pos + 1, |
| 102 | std::memory_order_relaxed)) { |
| 103 | item = std::move(cell->data); |
| 104 | cell->sequence.store(pos + Capacity, std::memory_order_release); |
| 105 | return true; |
| 106 | } |
| 107 | } else if (diff < 0) { |
| 108 | return false; |
| 109 | } else { |
| 110 | pos = tail_.load(std::memory_order_relaxed); |
| 111 | } |
| 112 | } |
| 113 | } |
| 114 | |
| 115 | /** |
| 116 | * @brief Get the capacity of the queue |
no outgoing calls