28namespace seqan3::contrib
43template <
typename TSpec =
void>
47template <
typename TSpec = Tag<
void>>
50template <
typename TValue,
typename TSpec = Suspendable<>>
54using Limit = Tag<Limit_>;
56template <
typename TValue,
typename TSpec>
57class ConcurrentQueue<TValue, Suspendable<TSpec>>
61 typedef typename TString::size_type TSize;
76 ConcurrentQueue() : readerCount(0), writerCount(0), occupied(0),
back(0),
front(0), virgin(true)
81 assert(writerCount == 0u);
84 while (readerCount != 0u)
89template <
typename TValue>
90class ConcurrentQueue<TValue, Suspendable<Limit>> :
public ConcurrentQueue<TValue, Suspendable<>>
93 typedef ConcurrentQueue<TValue, Suspendable<>> TBase;
94 typedef typename TBase::TString TString;
95 typedef typename TBase::TSize TSize;
99 ConcurrentQueue(TSize maxSize) : TBase()
101 this->data.resize(maxSize);
106 ConcurrentQueue(ConcurrentQueue
const & other) : TBase((TBase const &)other)
110template <
typename TValue,
typename TSpec>
111inline void lockReading(ConcurrentQueue<TValue, Suspendable<TSpec>> &)
114template <
typename TValue,
typename TSpec>
115inline void unlockReading(ConcurrentQueue<TValue, Suspendable<TSpec>> & me)
119 if (--me.readerCount != 0u)
122 me.less.notify_all();
125template <
typename TValue,
typename TSpec>
126inline void lockWriting(ConcurrentQueue<TValue, Suspendable<TSpec>> &)
129template <
typename TValue,
typename TSpec>
130inline void unlockWriting(ConcurrentQueue<TValue, Suspendable<TSpec>> & me)
134 if (--me.writerCount != 0u)
137 me.more.notify_all();
140template <
typename TValue,
typename TSize,
typename TSpec>
141inline void setReaderCount(ConcurrentQueue<TValue, Suspendable<TSpec>> & me, TSize readerCount)
144 me.readerCount = readerCount;
147template <
typename TValue,
typename TSize,
typename TSpec>
148inline void setWriterCount(ConcurrentQueue<TValue, Suspendable<TSpec>> & me, TSize writerCount)
151 me.writerCount = writerCount;
154template <
typename TValue,
typename TSize1,
typename TSize2,
typename TSpec>
156setReaderWriterCount(ConcurrentQueue<TValue, Suspendable<TSpec>> & me, TSize1 readerCount, TSize2 writerCount)
159 me.readerCount = readerCount;
160 me.writerCount = writerCount;
163template <
typename TValue,
typename TSize,
typename TSpec>
164inline bool waitForMinSize(ConcurrentQueue<TValue, Suspendable<TSpec>> & me, TSize minSize)
167 while (me.occupied < minSize && me.writerCount > 0u)
169 return me.occupied >= minSize;
172template <
typename TValue,
typename TSpec>
173inline bool empty(ConcurrentQueue<TValue, Suspendable<TSpec>>
const & me)
175 return me.occupied == 0;
178template <
typename TValue,
typename TSpec>
179inline typename ConcurrentQueue<TValue, Suspendable<TSpec>>::SizeType
180length(ConcurrentQueue<TValue, Suspendable<TSpec>>
const & me)
185template <
typename TValue,
typename TSpec>
189 typedef ConcurrentQueue<TValue, Suspendable<TSpec>> TQueue;
190 typedef typename TQueue::TString TString;
191 typedef typename TString::size_type TSize;
193 TSize cap = me.data.size();
195 while (me.occupied == 0u && me.writerCount > 0u)
198 if (me.occupied == 0u)
201 assert(me.occupied > 0u);
205 result = std::ranges::iter_move(std::ranges::next(me.data.begin(), me.front));
209 me.front = (me.front + 1) % cap;
221template <
typename TValue,
typename TSpec>
225 typedef ConcurrentQueue<TValue, Suspendable<TSpec>> TQueue;
226 typedef typename TQueue::TString TString;
227 typedef typename TString::size_type TSize;
229 TSize cap = me.data.size();
231 while (me.occupied == 0u && me.writerCount > 0u)
234 if (me.occupied == 0u)
237 assert(me.occupied > 0u);
239 me.back = (me.back + cap - 1) % cap;
243 result = std::ranges::iter_move(std::ranges::next(me.data.begin(), me.back));
258template <
typename TValue,
typename TSpec>
259inline bool popFront(TValue & result, ConcurrentQueue<TValue, Suspendable<TSpec>> & me)
262 return _popFront(result, me, lock);
265template <
typename TValue>
266inline bool popFront(TValue & result, ConcurrentQueue<TValue, Suspendable<Limit>> & me)
270 if (!_popFront(result, me, lk))
273 me.less.notify_all();
277template <
typename TValue,
typename TSpec>
278inline bool popBack(TValue & result, ConcurrentQueue<TValue, Suspendable<TSpec>> & me)
281 return _popBack(result, me, lk);
284template <
typename TValue>
285inline bool popBack(TValue & result, ConcurrentQueue<TValue, Suspendable<Limit>> & me)
289 if (!_popBack(result, me, lk))
292 me.less.notify_all();
296template <
typename TValue,
typename TValue2,
typename TSpec,
typename TExpand>
298appendValue(ConcurrentQueue<TValue, Suspendable<TSpec>> & me, TValue2 && val, [[maybe_unused]] Tag<TExpand> expandTag)
300 typedef ConcurrentQueue<TValue, Suspendable<TSpec>> TQueue;
301 typedef typename TQueue::TString TString;
302 typedef typename TString::size_type TSize;
306 TSize cap = me.data.size();
308 if (me.occupied >= cap)
313 me.data.resize(cap + 1);
314 TSize delta = me.data.size() - cap;
320 std::ranges::move_backward(std::span{me.data.data() + me.front, me.data.data() + cap},
321 me.data.data() + me.data.size());
322 if (me.occupied != 0 && me.back <= me.front)
329 *std::ranges::next(me.data.begin(), me.back) = std::forward<TValue2>(val);
330 me.back = (me.back + 1) % cap;
340 me.more.notify_all();
344template <
typename TValue,
typename TValue2,
typename TSpec,
typename TExpand>
345inline bool appendValue(ConcurrentQueue<TValue, Suspendable<Limit>> & me, TValue2 && val, Tag<TExpand> expandTag);
347template <
typename TValue,
typename TValue2>
348inline bool appendValue(ConcurrentQueue<TValue, Suspendable<Limit>> & me, TValue2 && val, Limit)
350 typedef ConcurrentQueue<TValue, Suspendable<Limit>> TQueue;
351 typedef typename TQueue::TString TString;
352 typedef typename TString::size_type TSize;
356 TSize cap = me.data.size();
358 while (me.occupied >= cap && me.readerCount > 0u)
361 if (me.occupied >= cap)
364 assert(me.occupied < cap);
367 *std::ranges::next(me.data.begin(), me.back) = std::forward<TValue2>(val);
368 me.back = (me.back + 1) % cap;
377 me.more.notify_all();
381template <
typename TValue,
typename TValue2,
typename TSpec>
382inline bool appendValue(ConcurrentQueue<TValue, Suspendable<TSpec>> & me, TValue2 && val)
384 return appendValue(me, std::forward<TValue2>(val), TSpec{});
typename decltype(detail::front(list_t{}))::type front
Return the first type from the type list.
Definition type_list/traits.hpp:296
typename decltype(detail::back(list_t{}))::type back
Return the last type from the type list.
Definition type_list/traits.hpp:316