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