8000 Finished DBC code, added requires clauses · connectivecpp/wait-queue@ecd350b · GitHub
[go: up one dir, main page]

Skip to content

Commit ecd350b

Browse files
Finished DBC code, added requires clauses
1 parent 5b13757 commit ecd350b

File tree

1 file changed

+69
-46
lines changed

1 file changed

+69
-46
lines changed

include/queue/wait_queue.hpp

Lines changed: 69 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -158,11 +158,12 @@
158158
#include <stop_token> // std::stop_source, std::stop_token
159159
#include <optional>
160160
#include <utility> // std::move, std::move_if_noexcept
161-
#include <type_traits> // for noexcept specs
161+
#include <type_traits> // for requires clauses and noexcept specs
162162

163163
namespace chops {
164164

165165
template <typename T, typename Container = std::deque<T> >
166+
requires std::is_copy_constructible_v<T> || std::is_move_constructible_v<T>
166167
class wait_queue {
167168
private:
168169
mutable std::mutex m_mut;
@@ -195,8 +196,10 @@ class wait_queue {
195196
* @post @c stop_requested returns @c false.
196197
*/
197198
wait_queue()
198-
// noexcept(std::is_nothrow_constructible<Container>::value)
199-
: m_stop_src(std::stop_source{}), m_stop_tok((*m_stop_src).get_token()) {
199+
requires std::is_default_constructible_v<Container>
200+
// noexcept(std::is_nothrow_constructible_v<Container>)
201+
: m_stop_src(std::stop_source{}), m_stop_tok((*m_stop_src).get_token())
202+
{
200203
assert(empty());
201204
assert(size() == size_type(0));
202205
assert(!stop_requested());
@@ -212,8 +215,10 @@ class wait_queue {
212215
* @post @c size returns 0.
213216
*/
214217
wait_queue(std::stop_token stop_tok)
215-
// noexcept(std::is_nothrow_constructible<Container>::value)
216-
: m_stop_tok(stop_tok) {
218+
requires std::is_default_constructible_v<Container>
219+
// noexcept(std::is_nothrow_constructible_v<Container, std::stop_token>)
220+
: m_stop_tok(stop_tok)
221+
{
217222
assert(empty());
218223
assert(size() == size_type(0));
219224
}
@@ -236,15 +241,16 @@ class wait_queue {
236241
* @param container Container object to be moved from (or copied from if not
237242
* movable).
238243
*
239-
* @post @c empty returns @c true if @c beg equals @c end otherwise returns @c false.
240-
* @post @c size returns the distance between @c beg and @c end parameters.
244+
* @post @c empty and @c size match moved (or copied) in container.
241245
*/
242246
wait_queue(Container&& container)
243-
// noexcept(std::is_ something movable or maybe copyable )
247+
requires std::is_move_constructible_v<Container> ||
248+
std::is_copy_constructible_v<Container>
249+
// noexcept(std::is_nnthrow_constructible_v<Container, Container&&>)
244250
: m_stop_src(std::stop_source{}), m_stop_tok((*m_stop_src).get_token()),
245-
m_data_queue(std::move(container)) {
246-
// assert(empty() == (beg == end));
247-
// assert((size() == size_type(0)) == (beg == end)); // std::distance constrains beg, end.
251+
m_data_queue(std::move(container))
252+
{
253+
// not easily assertible until contracts added to C++
248254
}
249255

250256
/**
@@ -257,14 +263,14 @@ class wait_queue {
257263
* @param container Container object to be moved from (or copied from if not
258264
* movable).
259265
*
260-
* @post @c empty returns @c true if @c beg equals @c end otherwise returns @c false.
261-
* @post @c size returns the distance between @c beg and @c end parameters.
266+
* @post @c empty and @c size match moved (or copied) in container.
262267
*/
263268
wait_queue(std::stop_token stop_tok, Container&& container)
264-
// noexcept(std::is_nothrow_constructible<Container, Iter, Iter>::value)
265-
: m_stop_tok(stop_tok), m_data_queue(std::move(container)) {
266-
// assert(empty() == (beg == end));
267-
// assert((size() == size_type(0)) == (beg == end)); // std::distance constrains beg, end.
269+
requires std::is_move_constructible_v<Container> ||
270+
std::is_copy_constructible_v<Container>
271+
// noexcept(std::is_nothrow_constructible_v<Container, std::stop_token, Container&&>)
272+
: m_stop_tok(stop_tok), m_data_queue(std::move(container))
273+
{
268274
}
269275

270276
/**
@@ -290,9 +296,11 @@ class wait_queue {
290296
* @post @c size returns 0 or @c sz depending on container used.
291297
*/
292298
wait_queue(size_type sz)
293-
// noexcept(std::is_nothrow_constructible<Container, size_type>::value)
299+
requires std::is_constructible_v<Container, size_type>
300+
// noexcept(std::is_nothrow_constructible_v<Container, size_type>)
294301
: m_stop_src(std::stop_source{}), m_stop_tok((*m_stop_src).get_token()),
295-
m_data_queue(sz) {
302+
m_data_queue(sz)
303+
{
296304
assert((sz != size_type(0)) || empty());
297305
assert((size() == size_type(0)) || (size() == sz));
298306
}
@@ -310,8 +318,10 @@ class wait_queue {
310318
* @post @c size returns 0 or @c sz depending on container used.
311319
*/
312320
wait_queue(std::stop_token stop_tok, size_type sz)
313-
// noexcept(std::is_nothrow_constructible<Container, size_type>::value)
314-
: m_stop_tok((*m_stop_src).get_token()), m_data_queue(sz) {
321+
requires std::is_constructible_v<Container, std::stop_token, size_type>
322+
// noexcept(std::is_nothrow_constructible_v<Container, std::stop_token, size_type>)
323+
: m_stop_tok((*m_stop_src).get_token()), m_data_queue(sz)
324+
{
315325
assert((sz != size_type(0)) || empty());
316326
assert((size() == size_type(0)) || (size() == sz));
317327
}
@@ -341,13 +351,12 @@ class wait_queue {
341351
* external @c std::stop_token was passed in.
342352
*/
343353
auto request_stop() noexcept
344-
-> bool {
345-
354+
-&g F438 t; bool
355+
{
346356
if (m_stop_src) {
347357
return (*m_stop_src).request_stop();
348358
}
349359
return false;
350-
351360
}
352361

353362
/**
@@ -364,9 +373,11 @@ class wait_queue {
364373
* @post If @c true is returned and @c empty is @c false, one of any threads waiting for a
365374
* value will be unblocked.
366375
*/
367-
auto push(const T& val) /* noexcept(std::is_nothrow_copy_constructible<T>::value) */
368-
-> bool {
376+
auto push(const T& val) /* noexcept(std::is_nothrow_copy_constructible_v<T>) */
377+
-> bool
378+
requires requires (T val, Container c) { c.push_back(val); }
369379

380+
{
370381
if (m_stop_tok.stop_requested()) {
371382
return false;
372383
}
@@ -386,9 +397,11 @@ class wait_queue {
386397
* @post If @c true is returned and @c empty is @c false, one of any threads waiting for a
387398
* value will be unblocked.
388399
*/
389-
auto push(T&& val) /* noexcept(std::is_nothrow_move_constructible<T>::value) */
390-
-> bool {
400+
auto push(T&& val) /* noexcept(std::is_nothrow_move_constructible_v<T>) */
401+
-> bool
402+
requires requires (T val, Container c) { c.push_back(val); }
391403

404+
{
392405
if (m_stop_tok.stop_requested()) {
393406
return false;
394407
}
@@ -416,17 +429,18 @@ class wait_queue {
416429
* value will be unblocked.
417430
*/
418431
template <typename ... Args>
419-
auto emplace_push(Args &&... args) /* noexcept(std::is_nothrow_constructible<T, Args...>::value)*/
420-
-> bool {
421-
432+
auto emplace_push(Args &&... args) /* noexcept(std::is_nothrow_constructible_v<T, Args...>)*/
433+
-> bool
434+
requires requires (Args && args, Container c) { c.emplace_back(args); }
435+
436+
{
422437
if (m_stop_tok.stop_requested()) {
423438
return false;
424439
}
425440
lock_guard lk{m_mut};
426441
m_data_queue.emplace_back(std::forward<Args>(args)...);
427442
m_data_cond.notify_one();
428443
return true;
429-
430444
}
431445

432446
/**
@@ -443,9 +457,11 @@ class wait_queue {
443457
* @post If a non empty value is returned, until a push function is called, @c size is one
444458
* less than before this function was called.
445459
*/
446-
auto wait_and_pop() /* noexcept(std::is_nothrow_constructible<T>::value) */
447-
-> std::optional<T> {
460+
[[nodiscard]] auto wait_and_pop() /* noexcept(std::is_nothrow_constructible_v<T>) */
461+
-> std::optional<T>
462+
requires requires (Container c) { c.empty(); c.pop_front(); }
448463

464+
{
449465
std::unique_lock<std::mutex> lk{m_mut};
450466
if (!m_data_cond.wait ( lk, m_stop_tok, [this] { return !m_data_queue.empty(); } )) {
451467
return std::optional<T> {}; // queue was request to stop, no data available
@@ -472,9 +488,10 @@ class wait_queue {
472488
* @post If a non empty value is returned, until a push function is called, @c size is one
473489
* less than before this function was called.
474490
*/
475-
auto try_pop() /* noexcept(std::is_nothrow_constructible<T>::value) */
476-
-> std::optional<T> {
477-
491+
[[nodiscard]] auto try_pop() /* noexcept(std::is_nothrow_constructible_v<T>) */
492+
-> std::optional<T>
493+
requires requires (Container c) { c.empty(); c.pop_front(); }
494+
{
478495
if (m_stop_tok.stop_requested()) {
479496
return std::optional<T> {};
480497
}
@@ -520,9 +537,11 @@ class wait_queue {
520537
* same @c wait_queue since it results in recursive mutex locks.
521538
*/
522539
template <typename F>
523-
auto apply(F&& func) const /* noexcept(std::is_nothrow_invocable<F&&, const T&>::value) */
524-
-> void {
540+
auto apply(F&& func) const /* noexcept(std::is_nothrow_invocable_v<F&&, const T&>) */
541+
-> void
542+
requires requires (T elem, F func) { func(elem); }
525543

544+
{
526545
lock_guard lk{m_mut};
527546
for (const T& elem : m_data_queue) {
528547
func(elem);
@@ -536,21 +555,23 @@ class wait_queue {
536555
*
537556
* @return @c true if the @c stop_requested has been called.
538557
*/
539-
auto stop_requested() const noexcept
540-
-> bool {
558+
[[nodiscard]] auto stop_requested() const noexcept
559+
-> bool
541560

561+
{
542562
return m_stop_tok.stop_requested();
543-
544563
}
545564

546565
/**
547566
* Query whether the @c wait_queue is empty or not.
548567
*
549568
* @return @c true if the @c wait_queue is empty.
550569
*/
551-
auto empty() const /* noexcept */
552-
-> bool {
570+
[[nodiscard]] auto empty() const /* noexcept */
571+
-> bool
572+
requires requires (Container c) { c.empty(); }
553573

574+
{
554575
lock_guard lk{m_mut};
555576
return m_data_queue.empty();
556577

@@ -561,9 +582,11 @@ class wait_queue {
561582
*
562583
* @return Number of elements in the @c wait_queue.
563584
*/
564-
auto size() const /* noexcept */
565-
-> size_type {
585+
[[nodiscard]] auto size() const /* noexcept */
586+
-> size_type
587+
requires requires (Container c) { c.size(); }
566588

589+
{
567590
lock_guard lk{m_mut};
568591
return m_data_queue.size();
569592

0 commit comments

Comments
 (0)
0