op_queue.hpp 3.2 KB

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