LCOV - code coverage report
Current view: top level - include/esys/repo - queuemt.h (source / functions) Hit Total Coverage
Test: esysrepo_coverage.info Lines: 47 50 94.0 %
Date: 2026-08-01 10:43:40 Functions: 15 15 100.0 %

          Line data    Source code
       1             : /*!
       2             :  * \file esys/repo/queuemt.h
       3             :  * \brief Thread-safe queue
       4             :  *
       5             :  * \cond
       6             :  * __legal_b__
       7             :  *
       8             :  * Copyright (c) 2020 Michel Gillet
       9             :  * Distributed under the MIT License.
      10             :  * (See accompanying file LICENSE.txt or
      11             :  * copy at https://opensource.org/licenses/MIT)
      12             :  *
      13             :  * __legal_e__
      14             :  * \endcond
      15             :  *
      16             :  */
      17             : 
      18             : #pragma once
      19             : 
      20             : #include "esys/repo/esysrepo_defs.h"
      21             : 
      22             : #include <mutex>
      23             : #include <deque>
      24             : #include <functional>
      25             : 
      26             : namespace esys
      27             : {
      28             : 
      29             : namespace repo
      30             : {
      31             : 
      32             : /*! \class QueueMT esys/repo/queuemt.h "esys/repo/queuemt.h"
      33             :  * \brief Thread-safe queue
      34             :  */
      35             : /*! \tparam T the element type */
      36             : template<typename T>
      37             : class QueueMT
      38             : {
      39             : public:
      40             :     //! Constructor
      41             :     QueueMT();
      42             : 
      43             :     //! Destructor
      44             :     ~QueueMT();
      45             : 
      46             :     //! Push an element at back of the queue
      47             :     /*!
      48             :      * \param[in] val the element to add to the queue
      49             :      */
      50             :     void push_back(const T &val);
      51             : 
      52             :     //! Push an element at front of the queue
      53             :     /*!
      54             :      * \param[in] val the element to add to the queue
      55             :      */
      56             :     void push_front(const T &val);
      57             : 
      58             :     //! Pop an element from the back of the queue
      59             :     /*!
      60             :      * \param[out] val if the queue is not empty, the element at the back of the queue
      61             :      * \return 0 if successful, < 0 otherwise
      62             :      */
      63             :     int pop_back(T &val);
      64             : 
      65             :     //! Pop an element from the front of the queue
      66             :     /*!
      67             :      * \param[out] val if the queue is not empty, the element at the front of the queue
      68             :      * \return 0 if successful, < 0 otherwise
      69             :      */
      70             :     int pop_front(T &val);
      71             : 
      72             :     //! Return the size of the queue
      73             :     /*!
      74             :      * \return the size of the queue
      75             :      */
      76             :     std::size_t size();
      77             : 
      78             :     //! Tells if the queue is empty or not
      79             :     /*!
      80             :      * \return true if the queue is empty, false otherwise
      81             :      */
      82             :     bool empty();
      83             : 
      84             :     //! Erase elements matching the given condition
      85             :     /*!
      86             :      * \param[in] fct erase the element if this function return true
      87             :      * \return true if the queue is empty, false otherwise
      88             :      */
      89             :     int remove_if(std::function<bool(const T &val)> fct);
      90             : 
      91             :     void for_each(std::function<void(const T &val)> fct);
      92             : 
      93             :     //! Clear all data
      94             :     void clear();
      95             : 
      96             : private:
      97             :     //!< \cond DOXY_IMPL
      98             :     std::mutex m_mutex;    //!< The mutex to use
      99             :     std::deque<T> m_queue; //!< The actual queue
     100             :     //!< \endcond
     101             : };
     102             : 
     103             : template<typename T>
     104         276 : QueueMT<T>::QueueMT()
     105             : {
     106         220 : }
     107             : 
     108             : template<typename T>
     109         221 : QueueMT<T>::~QueueMT()
     110             : {
     111         221 :     m_queue.clear();
     112         111 : }
     113             : 
     114             : template<typename T>
     115         447 : void QueueMT<T>::push_back(const T &val)
     116             : {
     117             :     //! lock
     118             :     /*!
     119             :      * \param[in] m_mutex the m mutex
     120             :      */
     121         447 :     std::lock_guard lock(m_mutex);
     122             : 
     123         447 :     m_queue.push_back(val);
     124         447 : }
     125             : 
     126             : template<typename T>
     127             : void QueueMT<T>::push_front(const T &val)
     128             : {
     129             :     //! lock
     130             :     /*!
     131             :      * \param[in] m_mutex the m mutex
     132             :      */
     133             :     std::lock_guard lock(m_mutex);
     134             : 
     135             :     m_queue.push_front(val);
     136             : }
     137             : 
     138             : template<typename T>
     139           1 : int QueueMT<T>::pop_back(T &val)
     140             : {
     141             :     //! lock
     142             :     /*!
     143             :      * \param[in] m_mutex the m mutex
     144             :      */
     145           1 :     std::lock_guard lock(m_mutex);
     146             : 
     147           1 :     val = nullptr;
     148             : 
     149           1 :     if (m_queue.size() == 0) return -1;
     150             : 
     151           0 :     val = m_queue.back();
     152           0 :     m_queue.pop_back();
     153             : 
     154           0 :     return 0;
     155           1 : }
     156             : 
     157             : template<typename T>
     158         199 : int QueueMT<T>::pop_front(T &val)
     159             : {
     160             :     //! lock
     161             :     /*!
     162             :      * \param[in] m_mutex the m mutex
     163             :      */
     164         199 :     std::lock_guard lock(m_mutex);
     165             : 
     166         199 :     val = nullptr;
     167             : 
     168         199 :     if (m_queue.size() == 0) return -1;
     169             : 
     170         123 :     val = m_queue.front();
     171         123 :     m_queue.pop_front();
     172             : 
     173         123 :     return 0;
     174         199 : }
     175             : 
     176             : template<typename T>
     177        1317 : std::size_t QueueMT<T>::size()
     178             : {
     179             :     //! lock
     180             :     /*!
     181             :      * \param[in] m_mutex the m mutex
     182             :      */
     183        1317 :     std::lock_guard lock(m_mutex);
     184             : 
     185        1317 :     return m_queue.size();
     186        1317 : }
     187             : 
     188             : template<typename T>
     189             : bool QueueMT<T>::empty()
     190             : {
     191             :     //! lock
     192             :     /*!
     193             :      * \param[in] m_mutex the m mutex
     194             :      */
     195             :     std::lock_guard lock(m_mutex);
     196             : 
     197             :     return m_queue.empty();
     198             : }
     199             : 
     200             : template<typename T>
     201         199 : int QueueMT<T>::remove_if(std::function<bool(const T &val)> fct)
     202             : {
     203             :     //! lock
     204             :     /*!
     205             :      * \param[in] m_mutex the m mutex
     206             :      */
     207         199 :     std::lock_guard lock(m_mutex);
     208             : 
     209         199 :     typename std::deque<T>::iterator it;
     210             :     bool remove;
     211         199 :     int result = -1;
     212             : 
     213         199 :     it = m_queue.begin();
     214             : 
     215         657 :     while (it != m_queue.end())
     216             :     {
     217         458 :         remove = fct(*it);
     218         458 :         if (remove)
     219             :         {
     220         199 :             it = m_queue.erase(it);
     221         199 :             result = 0;
     222             :         }
     223             :         else
     224         259 :             ++it;
     225             :     }
     226         199 :     return result;
     227         199 : }
     228             : 
     229             : template<typename T>
     230           1 : void QueueMT<T>::for_each(std::function<void(const T &val)> fct)
     231             : {
     232             :     //! lock
     233             :     /*!
     234             :      * \param[in] m_mutex the m mutex
     235             :      */
     236           1 :     std::lock_guard lock(m_mutex);
     237             : 
     238           7 :     for (auto item : m_queue) fct(item);
     239           1 : }
     240             : 
     241             : template<typename T>
     242          90 : void QueueMT<T>::clear()
     243             : {
     244             :     //! lock
     245             :     /*!
     246             :      * \param[in] m_mutex the m mutex
     247             :      */
     248          90 :     std::lock_guard lock(m_mutex);
     249             : 
     250          90 :     m_queue.clear();
     251          90 : }
     252             : 
     253             : } // namespace repo
     254             : 
     255             : } // namespace esys

Generated by: LCOV version 1.14