aboutsummaryrefslogtreecommitdiffstats
path: root/lib/asio/detail/op_queue.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/asio/detail/op_queue.hpp')
-rw-r--r--lib/asio/detail/op_queue.hpp162
1 files changed, 162 insertions, 0 deletions
diff --git a/lib/asio/detail/op_queue.hpp b/lib/asio/detail/op_queue.hpp
new file mode 100644
index 0000000..6219f79
--- /dev/null
+++ b/lib/asio/detail/op_queue.hpp
@@ -0,0 +1,162 @@
+//
+// detail/op_queue.hpp
+// ~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef ASIO_DETAIL_OP_QUEUE_HPP
+#define ASIO_DETAIL_OP_QUEUE_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include "asio/detail/noncopyable.hpp"
+
+#include "asio/detail/push_options.hpp"
+
+namespace asio {
+namespace detail {
+
+template <typename Operation>
+class op_queue;
+
+class op_queue_access
+{
+public:
+ template <typename Operation>
+ static Operation* next(Operation* o)
+ {
+ return static_cast<Operation*>(o->next_);
+ }
+
+ template <typename Operation1, typename Operation2>
+ static void next(Operation1*& o1, Operation2* o2)
+ {
+ o1->next_ = o2;
+ }
+
+ template <typename Operation>
+ static void destroy(Operation* o)
+ {
+ o->destroy();
+ }
+
+ template <typename Operation>
+ static Operation*& front(op_queue<Operation>& q)
+ {
+ return q.front_;
+ }
+
+ template <typename Operation>
+ static Operation*& back(op_queue<Operation>& q)
+ {
+ return q.back_;
+ }
+};
+
+template <typename Operation>
+class op_queue
+ : private noncopyable
+{
+public:
+ // Constructor.
+ op_queue()
+ : front_(0),
+ back_(0)
+ {
+ }
+
+ // Destructor destroys all operations.
+ ~op_queue()
+ {
+ while (Operation* op = front_)
+ {
+ pop();
+ op_queue_access::destroy(op);
+ }
+ }
+
+ // Get the operation at the front of the queue.
+ Operation* front()
+ {
+ return front_;
+ }
+
+ // Pop an operation from the front of the queue.
+ void pop()
+ {
+ if (front_)
+ {
+ Operation* tmp = front_;
+ front_ = op_queue_access::next(front_);
+ if (front_ == 0)
+ back_ = 0;
+ op_queue_access::next(tmp, static_cast<Operation*>(0));
+ }
+ }
+
+ // Push an operation on to the back of the queue.
+ void push(Operation* h)
+ {
+ op_queue_access::next(h, static_cast<Operation*>(0));
+ if (back_)
+ {
+ op_queue_access::next(back_, h);
+ back_ = h;
+ }
+ else
+ {
+ front_ = back_ = h;
+ }
+ }
+
+ // Push all operations from another queue on to the back of the queue. The
+ // source queue may contain operations of a derived type.
+ template <typename OtherOperation>
+ void push(op_queue<OtherOperation>& q)
+ {
+ if (Operation* other_front = op_queue_access::front(q))
+ {
+ if (back_)
+ op_queue_access::next(back_, other_front);
+ else
+ front_ = other_front;
+ back_ = op_queue_access::back(q);
+ op_queue_access::front(q) = 0;
+ op_queue_access::back(q) = 0;
+ }
+ }
+
+ // Whether the queue is empty.
+ bool empty() const
+ {
+ return front_ == 0;
+ }
+
+ // Test whether an operation is already enqueued.
+ bool is_enqueued(Operation* o) const
+ {
+ return op_queue_access::next(o) != 0 || back_ == o;
+ }
+
+private:
+ friend class op_queue_access;
+
+ // The front of the queue.
+ Operation* front_;
+
+ // The back of the queue.
+ Operation* back_;
+};
+
+} // namespace detail
+} // namespace asio
+
+#include "asio/detail/pop_options.hpp"
+
+#endif // ASIO_DETAIL_OP_QUEUE_HPP