25namespace seqan3::contrib
40template <
typename TSpec =
void>
44template <
typename TSpec = Tag<
void>>
47template <
typename TValue,
typename TSpec = Suspendable<>>
51using Limit = Tag<Limit_>;
53template <
typename TValue,
typename TSpec>
54class ConcurrentQueue<TValue, Suspendable<TSpec>>
58 typedef typename TString::size_type TSize;
73 ConcurrentQueue() : readerCount(0), writerCount(0), occupied(0),
back(0),
front(0), virgin(true)
78 assert(writerCount == 0u);
81 while (readerCount != 0u)
86template <
typename TValue>
87class ConcurrentQueue<TValue, Suspendable<Limit>> :
public ConcurrentQueue<TValue, Suspendable<>>
90 typedef ConcurrentQueue<TValue, Suspendable<>> TBase;
91 typedef typename TBase::TString TString;
92 typedef typename TBase::TSize TSize;
96 ConcurrentQueue(TSize maxSize) : TBase()
98 this->data.resize(maxSize);
103 ConcurrentQueue(ConcurrentQueue
const & other) : TBase((TBase const &)other)
107template <
typename TValue,
typename TSpec>
108inline void lockReading(ConcurrentQueue<TValue, Suspendable<TSpec>> &)
111template <
typename TValue,
typename TSpec>
112inline void unlockReading(ConcurrentQueue<TValue, Suspendable<TSpec>> & me)
116 if (--me.readerCount != 0u)
119 me.less.notify_all();
122template <
typename TValue,
typename TSpec>
123inline void lockWriting(ConcurrentQueue<TValue, Suspendable<TSpec>> &)
126template <
typename TValue,
typename TSpec>
127inline void unlockWriting(ConcurrentQueue<TValue, Suspendable<TSpec>> & me)
131 if (--me.writerCount != 0u)
134 me.more.notify_all();
137template <
typename TValue,
typename TSize,
typename TSpec>
138inline void setReaderCount(ConcurrentQueue<TValue, Suspendable<TSpec>> & me, TSize readerCount)
141 me.readerCount = readerCount;
144template <
typename TValue,
typename TSize,
typename TSpec>
145inline void setWriterCount(ConcurrentQueue<TValue, Suspendable<TSpec>> & me, TSize writerCount)
148 me.writerCount = writerCount;
151template <
typename TValue,
typename TSize1,
typename TSize2,
typename TSpec>
153setReaderWriterCount(ConcurrentQueue<TValue, Suspendable<TSpec>> & me, TSize1 readerCount, TSize2 writerCount)
156 me.readerCount = readerCount;
157 me.writerCount = writerCount;
160template <
typename TValue,
typename TSize,
typename TSpec>
161inline bool waitForMinSize(ConcurrentQueue<TValue, Suspendable<TSpec>> & me, TSize minSize)
164 while (me.occupied < minSize && me.writerCount > 0u)
166 return me.occupied >= minSize;
169template <
typename TValue,
typename TSpec>
170inline bool empty(ConcurrentQueue<TValue, Suspendable<TSpec>>
const & me)
172 return me.occupied == 0;
175template <
typename TValue,
typename TSpec>
176inline typename ConcurrentQueue<TValue, Suspendable<TSpec>>::SizeType
177length(ConcurrentQueue<TValue, Suspendable<TSpec>>
const & me)
182template <
typename TValue,
typename TSpec>
186 typedef ConcurrentQueue<TValue, Suspendable<TSpec>> TQueue;
187 typedef typename TQueue::TString TString;
188 typedef typename TString::size_type TSize;
190 TSize cap = me.data.size();
192 while (me.occupied == 0u && me.writerCount > 0u)
195 if (me.occupied == 0u)
198 assert(me.occupied > 0u);
202 result = std::ranges::iter_move(std::ranges::next(me.data.begin(), me.front));
206 me.front = (me.front + 1) % cap;
218template <
typename TValue,
typename TSpec>
222 typedef ConcurrentQueue<TValue, Suspendable<TSpec>> TQueue;
223 typedef typename TQueue::TString TString;
224 typedef typename TString::size_type TSize;
226 TSize cap = me.data.size();
228 while (me.occupied == 0u && me.writerCount > 0u)
231 if (me.occupied == 0u)
234 assert(me.occupied > 0u);
236 me.back = (me.back + cap - 1) % cap;
240 result = std::ranges::iter_move(std::ranges::next(me.data.begin(), me.back));
255template <
typename TValue,
typename TSpec>
256inline bool popFront(TValue & result, ConcurrentQueue<TValue, Suspendable<TSpec>> & me)
259 return _popFront(result, me, lock);
262template <
typename TValue>
263inline bool popFront(TValue & result, ConcurrentQueue<TValue, Suspendable<Limit>> & me)
267 if (!_popFront(result, me, lk))
270 me.less.notify_all();
274template <
typename TValue,
typename TSpec>
275inline bool popBack(TValue & result, ConcurrentQueue<TValue, Suspendable<TSpec>> & me)
278 return _popBack(result, me, lk);
281template <
typename TValue>
282inline bool popBack(TValue & result, ConcurrentQueue<TValue, Suspendable<Limit>> & me)
286 if (!_popBack(result, me, lk))
289 me.less.notify_all();
293template <
typename TValue,
typename TValue2,
typename TSpec,
typename TExpand>
295appendValue(ConcurrentQueue<TValue, Suspendable<TSpec>> & me, TValue2 && val, [[maybe_unused]] Tag<TExpand> expandTag)
297 typedef ConcurrentQueue<TValue, Suspendable<TSpec>> TQueue;
298 typedef typename TQueue::TString TString;
299 typedef typename TString::size_type TSize;
303 TSize cap = me.data.size();
305 if (me.occupied >= cap)
310 me.data.resize(cap + 1);
311 TSize delta = me.data.size() - cap;
318 me.data.data() + me.data.size());
319 if (me.occupied != 0 && me.back <= me.front)
326 *std::ranges::next(me.data.begin(), me.back) = std::forward<TValue2>(val);
327 me.back = (me.back + 1) % cap;
337 me.more.notify_all();
341template <
typename TValue,
typename TValue2,
typename TSpec,
typename TExpand>
342inline bool appendValue(ConcurrentQueue<TValue, Suspendable<Limit>> & me, TValue2 && val, Tag<TExpand> expandTag);
344template <
typename TValue,
typename TValue2>
345inline bool appendValue(ConcurrentQueue<TValue, Suspendable<Limit>> & me, TValue2 && val, Limit)
347 typedef ConcurrentQueue<TValue, Suspendable<Limit>> TQueue;
348 typedef typename TQueue::TString TString;
349 typedef typename TString::size_type TSize;
353 TSize cap = me.data.size();
355 while (me.occupied >= cap && me.readerCount > 0u)
358 if (me.occupied >= cap)
361 assert(me.occupied < cap);
364 *std::ranges::next(me.data.begin(), me.back) = std::forward<TValue2>(val);
365 me.back = (me.back + 1) % cap;
374 me.more.notify_all();
378template <
typename TValue,
typename TValue2,
typename TSpec>
379inline bool appendValue(ConcurrentQueue<TValue, Suspendable<TSpec>> & me, TValue2 && val)
381 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:293
typename decltype(detail::back(list_t{}))::type back
Return the last type from the type list.
Definition type_list/traits.hpp:313
T move_backward(T... args)