Micro template library A library for building device drivers
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.
 
 
 
 

147 lignes
5.6 KiB

  1. /*!
  2. * \file container/equeue.h
  3. * \brief
  4. * A queue with event based callables based on edeque.
  5. *
  6. * \copyright Copyright (C) 2021 Christos Choutouridis <christos@choutouridis.net>
  7. *
  8. * <dl class=\"section copyright\"><dt>License</dt><dd>
  9. * The MIT License (MIT)
  10. *
  11. * Permission is hereby granted, free of charge, to any person obtaining a copy
  12. * of this software and associated documentation files (the "Software"), to deal
  13. * in the Software without restriction, including without limitation the rights
  14. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  15. * copies of the Software, and to permit persons to whom the Software is
  16. * furnished to do so, subject to the following conditions:
  17. *
  18. * The above copyright notice and this permission notice shall be included in all
  19. * copies or substantial portions of the Software.
  20. *
  21. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  22. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  23. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  24. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  25. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  26. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  27. * SOFTWARE.
  28. * </dd></dl>
  29. */
  30. #ifndef utl_container_equeue_h__
  31. #define utl_container_equeue_h__
  32. #include <utl/core/impl.h>
  33. #include <utl/container/edeque.h>
  34. namespace utl {
  35. /*!
  36. * \class equeue
  37. * \brief
  38. * A statically allocated queue based on edeque with size and data matching
  39. * event based callables.
  40. *
  41. * We use the \ref edeque::push_back() and \ref edeque::pop_front() pair from edeque's
  42. * functionality, so at the \c push the increment performed after the insertion.
  43. * Similarly at the \c pop the decrement performed before the exctraction. This way also
  44. * the \ref edeque::front() and \ref edeque::back() stay the same ;)
  45. *
  46. * We also provide stream operators.
  47. *
  48. * \tparam Data_t The char-like queued item type. Usually \c char
  49. * \tparam N The size of edeque
  50. * \tparam SemiAtomic True for semi-atomic operation. In that case the \c ring_iterator is also atomic.
  51. * \tparam Fn The type of Callable
  52. * \note
  53. * SemiAtomic means it is safe to for one thread to push only from front and another can pop.
  54. */
  55. template <typename Data_t, size_t N, bool SemiAtomic =false, typename Fn = std::function<void()>>
  56. class equeue : public edeque<Data_t, N, SemiAtomic, Fn> {
  57. public:
  58. // meta-identity types
  59. using equeue_t = equeue<Data_t, N, SemiAtomic, Fn>;
  60. using base_type = edeque<Data_t, N, SemiAtomic, Fn>;
  61. using range_t = typename base_type::range_t;
  62. // STL
  63. using value_type = typename base_type::value_type;
  64. using reference = typename base_type::reference;
  65. using const_reference = typename base_type::const_reference;
  66. using pointer = typename base_type::pointer;
  67. using const_pointer = typename base_type::const_pointer;
  68. using iterator = typename base_type::iterator;
  69. using const_iterator = typename base_type::const_iterator;
  70. using reverse_iterator = typename base_type::reverse_iterator;
  71. using const_reverse_iterator= typename base_type::const_reverse_iterator;
  72. //! \name Constructor / Destructor
  73. //! @{
  74. public:
  75. //! Default constructor
  76. constexpr equeue () noexcept : base_type() { }
  77. //! Forward constructor
  78. template <typename ...It>
  79. constexpr equeue(It&& ...it) noexcept : base_type(std::forward<It>(it)...) { }
  80. //! @}
  81. //! \name Member access
  82. //! @{
  83. public:
  84. //! \brief Push an item in the back of the queue
  85. //! \param it The item to push
  86. void push (const Data_t& it) noexcept {
  87. base_type::push_back(it);
  88. }
  89. //! \brief Extract an item from the front of the queue and remove it from the queue
  90. //! \param it The item to push
  91. Data_t pop () noexcept {
  92. return base_type::pop_front();
  93. }
  94. //! \brief Push an item in the back of the queue
  95. //! \param it The item to push
  96. equeue_t& operator<< (const Data_t& it) noexcept {
  97. push(it);
  98. return *this;
  99. }
  100. //! \brief Push an item in the back of the queue
  101. //! \param it The item to push
  102. equeue_t& operator>> (Data_t& it) noexcept {
  103. it = pop();
  104. return *this;
  105. }
  106. //! @}
  107. };
  108. /*!
  109. * \brief
  110. * Pop an item from the front of the queue.
  111. *
  112. * This definition enables the "data << equeue" syntax for pop operation
  113. *
  114. * \tparam Data_t The char-like queued item type. Usually \c char
  115. * \tparam N The size of queue
  116. * \tparam SemiAtomic True for semi-atomic operation. In that case the \c ring_iterator is also atomic.
  117. * \tparam Fn The type of Callable
  118. *
  119. * \param it The item to write to
  120. * \param q The queue to read from
  121. * \return Reference to the returned item
  122. */
  123. template <typename Data_t, size_t N, bool SemiAtomic =false, typename Fn = std::function<void()>>
  124. Data_t& operator<< (Data_t& it, equeue<Data_t, N, SemiAtomic, Fn>& q) noexcept {
  125. it = q.pop();
  126. return it;
  127. }
  128. } // namespace utl
  129. #endif /* utl_container_equeue_h__ */