Audio plugin host https://kx.studio/carla
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

163 lines
3.2KB

  1. //
  2. // detail/op_queue.hpp
  3. // ~~~~~~~~~~~~~~~~~~~
  4. //
  5. // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
  6. //
  7. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  8. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  9. //
  10. #ifndef ASIO_DETAIL_OP_QUEUE_HPP
  11. #define ASIO_DETAIL_OP_QUEUE_HPP
  12. #if defined(_MSC_VER) && (_MSC_VER >= 1200)
  13. # pragma once
  14. #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
  15. #include "asio/detail/noncopyable.hpp"
  16. #include "asio/detail/push_options.hpp"
  17. namespace asio {
  18. namespace detail {
  19. template <typename Operation>
  20. class op_queue;
  21. class op_queue_access
  22. {
  23. public:
  24. template <typename Operation>
  25. static Operation* next(Operation* o)
  26. {
  27. return static_cast<Operation*>(o->next_);
  28. }
  29. template <typename Operation1, typename Operation2>
  30. static void next(Operation1*& o1, Operation2* o2)
  31. {
  32. o1->next_ = o2;
  33. }
  34. template <typename Operation>
  35. static void destroy(Operation* o)
  36. {
  37. o->destroy();
  38. }
  39. template <typename Operation>
  40. static Operation*& front(op_queue<Operation>& q)
  41. {
  42. return q.front_;
  43. }
  44. template <typename Operation>
  45. static Operation*& back(op_queue<Operation>& q)
  46. {
  47. return q.back_;
  48. }
  49. };
  50. template <typename Operation>
  51. class op_queue
  52. : private noncopyable
  53. {
  54. public:
  55. // Constructor.
  56. op_queue()
  57. : front_(0),
  58. back_(0)
  59. {
  60. }
  61. // Destructor destroys all operations.
  62. ~op_queue()
  63. {
  64. while (Operation* op = front_)
  65. {
  66. pop();
  67. op_queue_access::destroy(op);
  68. }
  69. }
  70. // Get the operation at the front of the queue.
  71. Operation* front()
  72. {
  73. return front_;
  74. }
  75. // Pop an operation from the front of the queue.
  76. void pop()
  77. {
  78. if (front_)
  79. {
  80. Operation* tmp = front_;
  81. front_ = op_queue_access::next(front_);
  82. if (front_ == 0)
  83. back_ = 0;
  84. op_queue_access::next(tmp, static_cast<Operation*>(0));
  85. }
  86. }
  87. // Push an operation on to the back of the queue.
  88. void push(Operation* h)
  89. {
  90. op_queue_access::next(h, static_cast<Operation*>(0));
  91. if (back_)
  92. {
  93. op_queue_access::next(back_, h);
  94. back_ = h;
  95. }
  96. else
  97. {
  98. front_ = back_ = h;
  99. }
  100. }
  101. // Push all operations from another queue on to the back of the queue. The
  102. // source queue may contain operations of a derived type.
  103. template <typename OtherOperation>
  104. void push(op_queue<OtherOperation>& q)
  105. {
  106. if (Operation* other_front = op_queue_access::front(q))
  107. {
  108. if (back_)
  109. op_queue_access::next(back_, other_front);
  110. else
  111. front_ = other_front;
  112. back_ = op_queue_access::back(q);
  113. op_queue_access::front(q) = 0;
  114. op_queue_access::back(q) = 0;
  115. }
  116. }
  117. // Whether the queue is empty.
  118. bool empty() const
  119. {
  120. return front_ == 0;
  121. }
  122. // Test whether an operation is already enqueued.
  123. bool is_enqueued(Operation* o) const
  124. {
  125. return op_queue_access::next(o) != 0 || back_ == o;
  126. }
  127. private:
  128. friend class op_queue_access;
  129. // The front of the queue.
  130. Operation* front_;
  131. // The back of the queue.
  132. Operation* back_;
  133. };
  134. } // namespace detail
  135. } // namespace asio
  136. #include "asio/detail/pop_options.hpp"
  137. #endif // ASIO_DETAIL_OP_QUEUE_HPP