Chris@16: // Chris@16: // detail/op_queue.hpp Chris@16: // ~~~~~~~~~~~~~~~~~~~ Chris@16: // Chris@101: // Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com) Chris@16: // Chris@16: // Distributed under the Boost Software License, Version 1.0. (See accompanying Chris@16: // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) Chris@16: // Chris@16: Chris@16: #ifndef BOOST_ASIO_DETAIL_OP_QUEUE_HPP Chris@16: #define BOOST_ASIO_DETAIL_OP_QUEUE_HPP Chris@16: Chris@16: #if defined(_MSC_VER) && (_MSC_VER >= 1200) Chris@16: # pragma once Chris@16: #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) Chris@16: Chris@16: #include Chris@16: Chris@16: #include Chris@16: Chris@16: namespace boost { Chris@16: namespace asio { Chris@16: namespace detail { Chris@16: Chris@16: template Chris@16: class op_queue; Chris@16: Chris@16: class op_queue_access Chris@16: { Chris@16: public: Chris@16: template Chris@16: static Operation* next(Operation* o) Chris@16: { Chris@16: return static_cast(o->next_); Chris@16: } Chris@16: Chris@16: template Chris@16: static void next(Operation1*& o1, Operation2* o2) Chris@16: { Chris@16: o1->next_ = o2; Chris@16: } Chris@16: Chris@16: template Chris@16: static void destroy(Operation* o) Chris@16: { Chris@16: o->destroy(); Chris@16: } Chris@16: Chris@16: template Chris@16: static Operation*& front(op_queue& q) Chris@16: { Chris@16: return q.front_; Chris@16: } Chris@16: Chris@16: template Chris@16: static Operation*& back(op_queue& q) Chris@16: { Chris@16: return q.back_; Chris@16: } Chris@16: }; Chris@16: Chris@16: template Chris@16: class op_queue Chris@16: : private noncopyable Chris@16: { Chris@16: public: Chris@16: // Constructor. Chris@16: op_queue() Chris@16: : front_(0), Chris@16: back_(0) Chris@16: { Chris@16: } Chris@16: Chris@16: // Destructor destroys all operations. Chris@16: ~op_queue() Chris@16: { Chris@16: while (Operation* op = front_) Chris@16: { Chris@16: pop(); Chris@16: op_queue_access::destroy(op); Chris@16: } Chris@16: } Chris@16: Chris@16: // Get the operation at the front of the queue. Chris@16: Operation* front() Chris@16: { Chris@16: return front_; Chris@16: } Chris@16: Chris@16: // Pop an operation from the front of the queue. Chris@16: void pop() Chris@16: { Chris@16: if (front_) Chris@16: { Chris@16: Operation* tmp = front_; Chris@16: front_ = op_queue_access::next(front_); Chris@16: if (front_ == 0) Chris@16: back_ = 0; Chris@16: op_queue_access::next(tmp, static_cast(0)); Chris@16: } Chris@16: } Chris@16: Chris@16: // Push an operation on to the back of the queue. Chris@16: void push(Operation* h) Chris@16: { Chris@16: op_queue_access::next(h, static_cast(0)); Chris@16: if (back_) Chris@16: { Chris@16: op_queue_access::next(back_, h); Chris@16: back_ = h; Chris@16: } Chris@16: else Chris@16: { Chris@16: front_ = back_ = h; Chris@16: } Chris@16: } Chris@16: Chris@16: // Push all operations from another queue on to the back of the queue. The Chris@16: // source queue may contain operations of a derived type. Chris@16: template Chris@16: void push(op_queue& q) Chris@16: { Chris@16: if (Operation* other_front = op_queue_access::front(q)) Chris@16: { Chris@16: if (back_) Chris@16: op_queue_access::next(back_, other_front); Chris@16: else Chris@16: front_ = other_front; Chris@16: back_ = op_queue_access::back(q); Chris@16: op_queue_access::front(q) = 0; Chris@16: op_queue_access::back(q) = 0; Chris@16: } Chris@16: } Chris@16: Chris@16: // Whether the queue is empty. Chris@16: bool empty() const Chris@16: { Chris@16: return front_ == 0; Chris@16: } Chris@16: Chris@16: private: Chris@16: friend class op_queue_access; Chris@16: Chris@16: // The front of the queue. Chris@16: Operation* front_; Chris@16: Chris@16: // The back of the queue. Chris@16: Operation* back_; Chris@16: }; Chris@16: Chris@16: } // namespace detail Chris@16: } // namespace asio Chris@16: } // namespace boost Chris@16: Chris@16: #include Chris@16: Chris@16: #endif // BOOST_ASIO_DETAIL_OP_QUEUE_HPP