27namespace seqan3::contrib
42template <
typename TSpec =
void>
45template <
typename TSpec = Tag<
void>>
48template <
typename TValue,
typename TSpec = Suspendable<>>
52using Limit = Tag<Limit_>;
54template <
typename TValue,
typename TSpec>
55class ConcurrentQueue<TValue, Suspendable<TSpec> >
59 typedef typename TString::size_type TSize;
85 assert(writerCount == 0u);
88 while (readerCount != 0u)
93template <
typename TValue>
94class ConcurrentQueue<TValue, Suspendable<Limit> >:
95 public ConcurrentQueue<TValue, Suspendable<> >
98 typedef ConcurrentQueue<TValue, Suspendable<> > TBase;
99 typedef typename TBase::TString TString;
100 typedef typename TBase::TSize TSize;
104 ConcurrentQueue(TSize maxSize):
107 this->data.resize(maxSize);
112 ConcurrentQueue(ConcurrentQueue
const & other):
113 TBase((TBase const &)other)
117template <
typename TValue,
typename TSpec>
119lockReading(ConcurrentQueue<TValue, Suspendable<TSpec> > &)
122template <
typename TValue,
typename TSpec>
124unlockReading(ConcurrentQueue<TValue, Suspendable<TSpec> > & me)
128 if (--me.readerCount != 0u)
131 me.less.notify_all();
134template <
typename TValue,
typename TSpec>
136lockWriting(ConcurrentQueue<TValue, Suspendable<TSpec> > &)
139template <
typename TValue,
typename TSpec>
141unlockWriting(ConcurrentQueue<TValue, Suspendable<TSpec> > & me)
145 if (--me.writerCount != 0u)
148 me.more.notify_all();
151template <
typename TValue,
typename TSize,
typename TSpec>
153setReaderCount(ConcurrentQueue<TValue, Suspendable<TSpec> > & me, TSize readerCount)
156 me.readerCount = readerCount;
159template <
typename TValue,
typename TSize,
typename TSpec>
161setWriterCount(ConcurrentQueue<TValue, Suspendable<TSpec> > & me, TSize writerCount)
164 me.writerCount = writerCount;
167template <
typename TValue,
typename TSize1,
typename TSize2,
typename TSpec>
169setReaderWriterCount(ConcurrentQueue<TValue, Suspendable<TSpec> > & me, TSize1 readerCount, TSize2 writerCount)
172 me.readerCount = readerCount;
173 me.writerCount = writerCount;
176template <
typename TValue,
typename TSize,
typename TSpec>
178waitForMinSize(ConcurrentQueue<TValue, Suspendable<TSpec> > & me,
182 while (me.occupied < minSize && me.writerCount > 0u)
184 return me.occupied >= minSize;
187template <
typename TValue,
typename TSpec>
189empty(ConcurrentQueue<TValue, Suspendable<TSpec> >
const & me)
191 return me.occupied == 0;
194template <
typename TValue,
typename TSpec>
195inline typename ConcurrentQueue<TValue, Suspendable<TSpec> >::SizeType
196length(ConcurrentQueue<TValue, Suspendable<TSpec> >
const & me)
201template <
typename TValue,
typename TSpec>
203_popFront(TValue & result, ConcurrentQueue<TValue, Suspendable<TSpec> > & me,
206 typedef ConcurrentQueue<TValue, Suspendable<TSpec> > TQueue;
207 typedef typename TQueue::TString TString;
208 typedef typename TString::size_type TSize;
210 TSize cap = me.data.size();
212 while (me.occupied == 0u && me.writerCount > 0u)
215 if (me.occupied == 0u)
218 assert(me.occupied > 0u);
222 result = std::ranges::iter_move(std::ranges::next(me.data.begin(), me.front));
226 me.front = (me.front + 1) % cap;
238template <
typename TValue,
typename TSpec>
240_popBack(TValue & result,
241 ConcurrentQueue<TValue, Suspendable<TSpec> > & me,
244 typedef ConcurrentQueue<TValue, Suspendable<TSpec> > TQueue;
245 typedef typename TQueue::TString TString;
246 typedef typename TString::size_type TSize;
248 TSize cap = me.data.size();
250 while (me.occupied == 0u && me.writerCount > 0u)
253 if (me.occupied == 0u)
256 assert(me.occupied > 0u);
258 me.back = (me.back + cap - 1) % cap;
262 result = std::ranges::iter_move(std::ranges::next(me.data.begin(), me.back));
277template <
typename TValue,
typename TSpec>
279popFront(TValue & result, ConcurrentQueue<TValue, Suspendable<TSpec> > & me)
282 return _popFront(result, me, lock);
285template <
typename TValue>
287popFront(TValue & result, ConcurrentQueue<TValue, Suspendable<Limit> > & me)
291 if (!_popFront(result, me, lk))
294 me.less.notify_all();
298template <
typename TValue,
typename TSpec>
300popBack(TValue & result, ConcurrentQueue<TValue, Suspendable<TSpec> > & me)
303 return _popBack(result, me, lk);
306template <
typename TValue>
308popBack(TValue & result, ConcurrentQueue<TValue, Suspendable<Limit> > & me)
312 if (!_popBack(result, me, lk))
315 me.less.notify_all();
320template <
typename TValue,
typename TValue2,
typename TSpec,
typename TExpand>
322appendValue(ConcurrentQueue<TValue, Suspendable<TSpec> > & me,
324 [[maybe_unused]] Tag<TExpand> expandTag)
326 typedef ConcurrentQueue<TValue, Suspendable<TSpec> > TQueue;
327 typedef typename TQueue::TString TString;
328 typedef typename TString::size_type TSize;
332 TSize cap = me.data.size();
334 if (me.occupied >= cap)
339 me.data.resize(cap + 1);
340 TSize delta = me.data.size() - cap;
346 std::ranges::move_backward(
std::span{me.
data.data() + me.front, me.data.data() + cap},
347 me.data.data() + me.data.size());
348 if (me.occupied != 0 && me.back <= me.front)
355 *std::ranges::next(me.data.begin(), me.back) = std::forward<TValue2>(val);
356 me.back = (me.back + 1) % cap;
366 me.more.notify_all();
370template <
typename TValue,
typename TValue2,
typename TSpec,
typename TExpand>
372appendValue(ConcurrentQueue<TValue, Suspendable<Limit> > & me,
374 Tag<TExpand> expandTag);
376template <
typename TValue,
typename TValue2>
378appendValue(ConcurrentQueue<TValue, Suspendable<Limit> > & me,
382 typedef ConcurrentQueue<TValue, Suspendable<Limit> > TQueue;
383 typedef typename TQueue::TString TString;
384 typedef typename TString::size_type TSize;
388 TSize cap = me.data.size();
390 while (me.occupied >= cap && me.readerCount > 0u)
393 if (me.occupied >= cap)
396 assert(me.occupied < cap);
399 *std::ranges::next(me.data.begin(), me.back) = std::forward<TValue2>(val);
400 me.back = (me.back + 1) % cap;
409 me.more.notify_all();
413template <
typename TValue,
typename TValue2,
typename TSpec>
415appendValue(ConcurrentQueue<TValue, Suspendable<TSpec> > & me,
418 return appendValue(me, std::forward<TValue2>(val), TSpec{});
The <algorithm> header from C++20's standard library.
typename decltype(detail::front(list_t{}))::type front
Return the first type from the type list.
Definition: traits.hpp:279
typename decltype(detail::back(list_t{}))::type back
Return the last type from the type list.
Definition: traits.hpp:301
The <iterator> header from C++20's standard library.
The <ranges> header from C++20's standard library.
Provides std::span from the C++20 standard library.