Skip to content

Commit

Permalink
Merge pull request #15 from connectivecpp/main
Browse files Browse the repository at this point in the history
Merging main to dev
  • Loading branch information
cliffg-softwarelibre authored Jun 20, 2024
2 parents 3fa71fc + 4fbd6e1 commit 2d3de43
Showing 1 changed file with 73 additions and 13 deletions.
86 changes: 73 additions & 13 deletions include/queue/wait_queue.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@
#ifndef WAIT_QUEUE_HPP_INCLUDED
#define WAIT_QUEUE_HPP_INCLUDED

#include <cassert> // assert
#include <deque>
#include <mutex> // std::scoped_lock, std::mutex
#include <condition_variable>
Expand Down Expand Up @@ -185,23 +186,35 @@ class wait_queue {
* anything, so a different @c wait_queue constructor must be used if
* instantiated with a @c boost @c circular_buffer.
*
* @post @c empty returns true.
* @post @c size returns 0.
* @post @c stop_requested return false.
*/
wait_queue()
// noexcept(std::is_nothrow_constructible<Container>::value)
: m_mut(), m_stop_src(std::stop_source{}), m_stop_tok((*m_stop_src).get_token()),
m_data_cond(), m_data_queue() { }
: m_stop_src(std::stop_source{}), m_stop_tok((*m_stop_src).get_token())
{
assert(empty());
assert(size() == size_type(0));
assert(!stop_requested());
}

/**
* @brief Construct a @c wait_queue with an externally provided @c std::stop_token.
*
* @param stop_tok A @c std::stop_token which can be used to shutdown @c wait_queue
* processing.
*
* @post @c empty returns true.
* @post @c size returns 0.
*/
wait_queue(std::stop_token stop_tok)
// noexcept(std::is_nothrow_constructible<Container>::value)
: m_mut(), m_stop_src(), m_stop_tok(stop_tok),
m_data_cond(), m_data_queue() { }
: m_stop_tok(stop_tok)
{
assert(empty());
assert(size() == size_type(0));
}

/**
* @brief Construct a @c wait_queue with an iterator range for the container.
Expand All @@ -221,12 +234,19 @@ class wait_queue {
* @param beg Beginning iterator.
*
* @param end Ending iterator.
*
* @post @c empty returns true if @c beg equals @c end otherwise returns false.
* @post @c size returns the distance between @c beg and @c end parameters.
*/
template <typename Iter>
wait_queue(Iter beg, Iter end)
// noexcept(std::is_nothrow_constructible<Container, Iter, Iter>::value)
: m_mut(), m_stop_src(std::stop_source{}), m_stop_tok((*m_stop_src).get_token()),
m_data_cond(), m_data_queue(beg, end) { }
: m_stop_src(std::stop_source{}), m_stop_tok((*m_stop_src).get_token()),
m_data_queue(beg, end)
{
assert(empty() == (beg == end));
assert((size() == size_type(0)) == (beg == end)); // std::distance constrains beg, end.
}

/**
* @brief Construct a @c wait_queue with an iterator range and a @c std::stop_token.
Expand All @@ -237,12 +257,18 @@ class wait_queue {
* @param beg Beginning iterator.
*
* @param end Ending iterator.
*
* @post @c empty returns true if @c beg equals @c end otherwise returns false.
* @post @c size returns the distance between @c beg and @c end parameters.
*/
template <typename Iter>
wait_queue(std::stop_token stop_tok, Iter beg, Iter end)
// noexcept(std::is_nothrow_constructible<Container, Iter, Iter>::value)
: m_mut(), m_stop_src(), m_stop_tok(stop_tok),
m_data_cond(), m_data_queue(beg, end) { }
: m_stop_tok(stop_tok), m_data_queue(beg, end)
{
assert(empty() == (beg == end));
assert((size() == size_type(0)) == (beg == end)); // std::distance constrains beg, end.
}

/**
* @brief Construct a @c wait_queue with an initial size or capacity.
Expand All @@ -263,11 +289,17 @@ class wait_queue {
*
* @param sz Capacity or initial size, depending on container type.
*
* @post If @c sz is 0 @c empty returns true, else behavior depends on container used.
* @post @c size returns 0 or @c sz depending on container used.
*/
wait_queue(size_type sz)
// noexcept(std::is_nothrow_constructible<Container, size_type>::value)
: m_mut(), m_stop_src(std::stop_source{}), m_stop_tok((*m_stop_src).get_token()),
m_data_cond(), m_data_queue(sz) { }
: m_stop_src(std::stop_source{}), m_stop_tok((*m_stop_src).get_token()),
m_data_queue(sz)
{
assert((sz != size_type(0)) || empty());
assert((size() == size_type(0)) || (size() == sz));
}

/**
* @brief Construct a @c wait_queue with an initial size or capacity along
Expand All @@ -278,11 +310,16 @@ class wait_queue {
*
* @param sz Capacity or initial size, depending on container type.
*
* @post If @c sz is 0 @c empty returns true, else behavior depends on container used.
* @post @c size returns 0 or @c sz depending on container used.
*/
wait_queue(std::stop_token stop_tok, size_type sz)
// noexcept(std::is_nothrow_constructible<Container, size_type>::value)
: m_mut(), m_stop_src(), m_stop_tok((*m_stop_src).get_token()),
m_data_cond(), m_data_queue(sz) { }
: m_stop_tok((*m_stop_src).get_token()), m_data_queue(sz)
{
assert((sz != size_type(0)) || empty());
assert((size() == size_type(0)) || (size() == sz));
}

// disallow copy or move construction of the entire object
wait_queue(const wait_queue&) = delete;
Expand All @@ -307,7 +344,6 @@ class wait_queue {
* @return @c true if an internal @c stop_source was used (versus a @c std::stop_token
* passed in to the constructor) and the request returns @c true, @c false if an
* external @c std::stop_token was passed in.
*
*/
auto request_stop() noexcept
-> bool {
Expand All @@ -329,6 +365,9 @@ class wait_queue {
*
* @return @c true if successful, @c false if the @c wait_queue has been
* requested to stop.
*
* @post If @c true is returned and @c empty is false, one of any threads waiting for a
* value will be unblocked.
*/
auto push(const T& val) /* noexcept(std::is_nothrow_copy_constructible<T>::value) */
-> bool {
Expand All @@ -348,6 +387,9 @@ class wait_queue {
*
* This method has the same semantics as the other @c push, except that the value will
* be moved (if possible) instead of copied.
*
* @post If @c true is returned and @c empty is false, one of any threads waiting for a
* value will be unblocked.
*/
auto push(T&& val) /* noexcept(std::is_nothrow_move_constructible<T>::value) */
-> bool {
Expand All @@ -374,6 +416,9 @@ class wait_queue {
*
* @return @c true if successful, @c false if the @c wait_queue is has been requested
* to stop.
*
* @post If @c true is returned and @c empty is false, one of any threads waiting for a
* value will be unblocked.
*/
template <typename ... Args>
auto emplace_push(Args &&... args) /* noexcept(std::is_nothrow_constructible<T, Args...>::value)*/
Expand All @@ -399,6 +444,9 @@ class wait_queue {
*
* @return A value from the @c wait_queue (if non-empty). If the @c std::optional is empty,
* the @c wait_queue has been requested to be stopped.
*
* @post If a non empty value is returned, until a push function is called, @c size is one
* less than before this function was called.
*/
auto wait_and_pop() /* noexcept(std::is_nothrow_constructible<T>::value) */
-> std::optional<T> {
Expand All @@ -407,8 +455,13 @@ class wait_queue {
if (!m_data_cond.wait ( lk, m_stop_tok, [this] { return !m_data_queue.empty(); } )) {
return std::optional<T> {}; // queue was request to stop, no data available
}
assert(!m_data_queue.empty());
#ifndef NDEBUG
const auto old_size = m_data_queue.size();
#endif
std::optional<T> val {std::move_if_noexcept(m_data_queue.front())}; // move construct if possible
m_data_queue.pop_front();
assert(m_data_queue.size() + 1u == old_size);
return val;

}
Expand All @@ -420,6 +473,9 @@ class wait_queue {
* @return A value from the @c wait_queue or an empty @c std::optional if no values are
* available in the @c wait_queue or if the @c wait_queue has been requested to be
* stopped .
*
* @post If a non empty value is returned, until a push function is called, @c size is one
* less than before this function was called.
*/
auto try_pop() /* noexcept(std::is_nothrow_constructible<T>::value) */
-> std::optional<T> {
Expand All @@ -431,8 +487,12 @@ class wait_queue {
if (m_data_queue.empty()) {
return std::optional<T> {};
}
#ifndef NDEBUG
const auto old_size = m_data_queue.size();
#endif
std::optional<T> val {std::move_if_noexcept(m_data_queue.front())}; // move construct if possible
m_data_queue.pop_front();
assert(m_data_queue.size() + 1u == old_size);
return val;

}
Expand Down

0 comments on commit 2d3de43

Please sign in to comment.