17 setAllocator(allocator);
22 for (
size_t i = head_pos; i != tail_pos; ++i)
23 (&p_node[i & capacity_mask].data)->~T();
28 void setAllocator(
Allocator& allocator) { vector.setAllocator(allocator); }
30 void resize(
size_t capacity) {
31 capacity_mask = capacity - 1;
32 for (
size_t i = 1; i <=
sizeof(
void*) * 4; i <<= 1)
33 capacity_mask |= capacity_mask >> i;
34 capacity_value = capacity_mask + 1;
36 vector.resize(capacity);
37 p_node = vector.data();
39 for (
size_t i = 0; i < capacity; ++i) {
40 p_node[i].tail.store(i, std::memory_order_relaxed);
41 p_node[i].head.store(-1, std::memory_order_relaxed);
44 tail_pos.store(0, std::memory_order_relaxed);
45 head_pos.store(0, std::memory_order_relaxed);
48 size_t capacity()
const {
return capacity_value; }
50 bool empty() {
return size() == 0;}
53 size_t head = head_pos.load(std::memory_order_acquire);
54 return tail_pos.load(std::memory_order_relaxed) - head;
57 bool enqueue(
const T&& data) {
61 bool enqueue(
const T& data) {
63 size_t tail = tail_pos.load(std::memory_order_relaxed);
65 node = &p_node[tail & capacity_mask];
66 if (node->tail.load(std::memory_order_relaxed) != tail)
return false;
67 if ((tail_pos.compare_exchange_weak(tail, tail + 1,
68 std::memory_order_relaxed)))
71 new (&node->data) T(data);
72 node->head.store(tail, std::memory_order_release);
76 bool dequeue(T& result) {
78 size_t head = head_pos.load(std::memory_order_relaxed);
80 node = &p_node[head & capacity_mask];
81 if (node->head.load(std::memory_order_relaxed) != head)
return false;
82 if (head_pos.compare_exchange_weak(head, head + 1,
83 std::memory_order_relaxed))
88 node->tail.store(head + capacity_value, std::memory_order_release);
100 std::atomic<size_t> tail;
101 std::atomic<size_t> head;
104 Node* p_node =
nullptr;
105 size_t capacity_mask;
106 size_t capacity_value;
107 std::atomic<size_t> tail_pos;
108 std::atomic<size_t> head_pos;