27 namespace seqan3::contrib
42 template <
typename TSpec =
void>
45 template <
typename TSpec = Tag<
void>>
48 template <
typename TValue,
typename TSpec = Suspendable<>>
49 class ConcurrentQueue;
52 using Limit = Tag<Limit_>;
54 template <
typename TValue,
typename TSpec>
55 class ConcurrentQueue<TValue, Suspendable<TSpec> >
59 typedef typename TString::size_type TSize;
85 assert(writerCount == 0u);
88 while (readerCount != 0u)
93 template <
typename TValue>
94 class 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)
117 template <
typename TValue,
typename TSpec>
119 lockReading(ConcurrentQueue<TValue, Suspendable<TSpec> > &)
122 template <
typename TValue,
typename TSpec>
124 unlockReading(ConcurrentQueue<TValue, Suspendable<TSpec> > & me)
128 if (--me.readerCount != 0u)
131 me.less.notify_all();
134 template <
typename TValue,
typename TSpec>
136 lockWriting(ConcurrentQueue<TValue, Suspendable<TSpec> > &)
139 template <
typename TValue,
typename TSpec>
141 unlockWriting(ConcurrentQueue<TValue, Suspendable<TSpec> > & me)
145 if (--me.writerCount != 0u)
148 me.more.notify_all();
151 template <
typename TValue,
typename TSize,
typename TSpec>
153 setReaderCount(ConcurrentQueue<TValue, Suspendable<TSpec> > & me, TSize readerCount)
156 me.readerCount = readerCount;
159 template <
typename TValue,
typename TSize,
typename TSpec>
161 setWriterCount(ConcurrentQueue<TValue, Suspendable<TSpec> > & me, TSize writerCount)
164 me.writerCount = writerCount;
167 template <
typename TValue,
typename TSize1,
typename TSize2,
typename TSpec>
169 setReaderWriterCount(ConcurrentQueue<TValue, Suspendable<TSpec> > & me, TSize1 readerCount, TSize2 writerCount)
172 me.readerCount = readerCount;
173 me.writerCount = writerCount;
176 template <
typename TValue,
typename TSize,
typename TSpec>
178 waitForMinSize(ConcurrentQueue<TValue, Suspendable<TSpec> > & me,
182 while (me.occupied < minSize && me.writerCount > 0u)
184 return me.occupied >= minSize;
187 template <
typename TValue,
typename TSpec>
189 empty(ConcurrentQueue<TValue, Suspendable<TSpec> >
const & me)
191 return me.occupied == 0;
194 template <
typename TValue,
typename TSpec>
195 inline typename ConcurrentQueue<TValue, Suspendable<TSpec> >::SizeType
196 length(ConcurrentQueue<TValue, Suspendable<TSpec> >
const & me)
201 template <
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;
238 template <
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));
277 template <
typename TValue,
typename TSpec>
279 popFront(TValue & result, ConcurrentQueue<TValue, Suspendable<TSpec> > & me)
282 return _popFront(result, me, lock);
285 template <
typename TValue>
287 popFront(TValue & result, ConcurrentQueue<TValue, Suspendable<Limit> > & me)
291 if (!_popFront(result, me, lk))
294 me.less.notify_all();
298 template <
typename TValue,
typename TSpec>
300 popBack(TValue & result, ConcurrentQueue<TValue, Suspendable<TSpec> > & me)
303 return _popBack(result, me, lk);
306 template <
typename TValue>
308 popBack(TValue & result, ConcurrentQueue<TValue, Suspendable<Limit> > & me)
312 if (!_popBack(result, me, lk))
315 me.less.notify_all();
320 template <
typename TValue,
typename TValue2,
typename TSpec,
typename TExpand>
322 appendValue(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();
370 template <
typename TValue,
typename TValue2,
typename TSpec,
typename TExpand>
372 appendValue(ConcurrentQueue<TValue, Suspendable<Limit> > & me,
374 Tag<TExpand> expandTag);
376 template <
typename TValue,
typename TValue2>
378 appendValue(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();
413 template <
typename TValue,
typename TValue2,
typename TSpec>
415 appendValue(ConcurrentQueue<TValue, Suspendable<TSpec> > & me,
418 return appendValue(me, std::forward<TValue2>(val), TSpec{});
Adaptations of algorithms from the Ranges TS.
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
Provides C++20 additions to the <iterator> header.
Adaptations of concepts from the Ranges TS.
Provides std::span from the C++20 standard library.