11 template<ice::concepts::LinkedListNode NodeType>
14 template<ice::concepts::LinkedListNode NodeType>
31 constexpr
bool is_empty() const noexcept {
return _head.load(std::memory_order_relaxed) ==
nullptr; }
34 template<ice::concepts::LinkedListNode DerivedNodeType = NodeType>
35 constexpr void push_back(DerivedNodeType* node)
noexcept;
36 template<ice::concepts::LinkedListNode DerivedNodeType = NodeType>
59 constexpr auto operator*() const noexcept -> NodeType*;
60 constexpr
void operator++() noexcept;
62 constexpr
bool operator==(
Iterator other) const noexcept;
63 constexpr
bool operator!=(
Iterator other) const noexcept;
73 template<ice::concepts::LinkedListNode NodeType>
80 template<ice::concepts::LinkedListNode NodeType>
91 template<ice::concepts::LinkedListNode NodeType>
104 template<ice::concepts::LinkedListNode NodeType>
105 template<ice::concepts::LinkedListNode DerivedNodeType>
108 NodeType*
const previous_tail =
_tail.exchange(node, std::memory_order_relaxed);
110 if (previous_tail ==
nullptr)
112 _head.store(node, std::memory_order_relaxed);
116 previous_tail->_next = node;
119 std::atomic_thread_fence(std::memory_order_release);
122 template<ice::concepts::LinkedListNode NodeType>
123 template<ice::concepts::LinkedListNode DerivedNodeType>
129 if (range.
_tail ==
nullptr)
142 NodeType*
const previous_tail =
_tail.exchange(range.
_tail, std::memory_order_relaxed);
144 if (previous_tail ==
nullptr)
146 _head.store(range.
_head, std::memory_order_relaxed);
150 previous_tail->_next = range.
_head;
153 std::atomic_thread_fence(std::memory_order_release);
157 template<ice::concepts::LinkedListNode NodeType>
160 NodeType*
volatile result_node =
_head.exchange(
nullptr, std::memory_order_relaxed);
162 if (result_node ==
nullptr)
168 if (result_node !=
nullptr)
170 NodeType* tail_node =
_tail.load(std::memory_order_relaxed);
173 bool skip_tail_update = tail_node == result_node;
174 if (skip_tail_update)
178 skip_tail_update =
_tail.compare_exchange_strong(
181 std::memory_order_relaxed,
182 std::memory_order_relaxed
187 if (skip_tail_update ==
false)
191 NodeType
volatile* next = result_node;
192 while (next->_next ==
nullptr)
194 std::atomic_thread_fence(std::memory_order_acquire);
197 NodeType* previous =
_head.exchange(next->_next, std::memory_order_relaxed);
205 template<ice::concepts::LinkedListNode NodeType>
210 NodeType*
const head_result =
_head.exchange(
nullptr, std::memory_order_relaxed);
214 if (head_result !=
nullptr)
216 result.
_head = head_result;
217 result.
_tail =
_tail.exchange(
nullptr, std::memory_order_acquire);
224 template<ice::concepts::LinkedListNode NodeType>
230 template<ice::concepts::LinkedListNode NodeType>
243 volatile NodeType* next =
_next;
244 while (next->_next ==
nullptr)
246 std::atomic_thread_fence(std::memory_order_acquire);
259 template<ice::concepts::LinkedListNode NodeType>
262 return (
_tail == other._tail) && (
_current == other._current);
265 template<ice::concepts::LinkedListNode NodeType>
268 return !(*
this == other);
271 template<ice::concepts::LinkedListNode NodeType>
274 if (
_head !=
nullptr)
282 NodeType
volatile* next =
_head;
283 while (next->_next ==
nullptr)
285 std::atomic_thread_fence(std::memory_order_acquire);
296 template<ice::concepts::LinkedListNode NodeType>
299 return {
nullptr,
nullptr,
_tail };
#define ICE_ASSERT_CORE(expression)
Definition assert_core.hxx:43
Definition container_concepts.hxx:12
SPDX-License-Identifier: MIT.
Definition array.hxx:12
constexpr auto operator=(AtomicLinkedQueue &&other) noexcept -> AtomicLinkedQueue &
Definition atomic_linked_queue.hxx:92
constexpr bool is_empty() const noexcept
Definition atomic_linked_queue.hxx:31
std::atomic< NodeType * > _tail
Definition atomic_linked_queue.hxx:20
NodeType ValueType
Definition atomic_linked_queue.hxx:17
constexpr auto take_all() noexcept -> ice::AtomicLinkedQueueRange< NodeType >
Definition atomic_linked_queue.hxx:206
constexpr auto take_front() noexcept -> NodeType *
Definition atomic_linked_queue.hxx:158
constexpr AtomicLinkedQueue() noexcept
Definition atomic_linked_queue.hxx:74
constexpr bool not_empty() const noexcept
Definition atomic_linked_queue.hxx:32
std::atomic< NodeType * > _head
Definition atomic_linked_queue.hxx:19
constexpr void push_back(DerivedNodeType *node) noexcept
Definition atomic_linked_queue.hxx:106
Definition atomic_linked_queue.hxx:54
constexpr bool operator==(Iterator other) const noexcept
Definition atomic_linked_queue.hxx:260
NodeType * _next
Definition atomic_linked_queue.hxx:56
NodeType * _current
Definition atomic_linked_queue.hxx:55
constexpr void operator++() noexcept
Definition atomic_linked_queue.hxx:231
constexpr bool operator!=(Iterator other) const noexcept
Definition atomic_linked_queue.hxx:266
NodeType * _tail
Definition atomic_linked_queue.hxx:57
constexpr auto operator*() const noexcept -> NodeType *
Definition atomic_linked_queue.hxx:225
Definition atomic_linked_queue.hxx:47
NodeType ValueType
Definition atomic_linked_queue.hxx:48
constexpr bool is_empty() const noexcept
Definition atomic_linked_queue.hxx:69
NodeType * _tail
Definition atomic_linked_queue.hxx:51
constexpr bool not_empty() const noexcept
Definition atomic_linked_queue.hxx:70
constexpr auto end() const noexcept -> Iterator
Definition atomic_linked_queue.hxx:297
constexpr auto begin() const noexcept -> Iterator
Definition atomic_linked_queue.hxx:272
NodeType * _head
Definition atomic_linked_queue.hxx:50